Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » TTCN Titan Testport for socketCAN(Testport for CAN-bus)
TTCN Titan Testport for socketCAN [message #1722735] Mon, 08 February 2016 17:37 Go to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello,

I am wondering what would be the best way to create a TTCN test port for Titan for the CAN bus using socketCAN.

www.kernel.org/doc/Documentation/networking/can.txt

Would the test port "Abstract_Socket" a good example to start with?

Re: TTCN Titan Testport for socketCAN [message #1722788 is a reply to message #1722735] Tue, 09 February 2016 07:54 Go to previous messageGo to next message
Gábor Szalai is currently offline Gábor SzalaiFriend
Messages: 131
Registered: December 2015
Senior Member
The Abstract Socket is too complex for it. I recommend the UnixDomainSocket test port and the UDP test port as examples. The UnixDomainSocket uses the newer event handler interface, which is recommended for a new development.
Re: TTCN Titan Testport for socketCAN [message #1722791 is a reply to message #1722788] Tue, 09 February 2016 08:10 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

the Abstract Socket is not a stand-alone port , but rather the common part of a number of our test ports relying on socket communication.

a hint: the "-t" option of the compiler will generate a test port skeleton matching your port declaration. In case of the Unix Domain port , the declaration looks like this:

module UD_PortType
{
import from UD_Types all;

  type port UD_PT message
  {
    out   UD_close;
    out   UD_listen;
    in    UD_listen_result;
    out   UD_shutdown;
    out   UD_connect;
    in    UD_connect_result;
    inout UD_send_data;
    in   UD_connected;
    
  } with { extension "provider" }

}





compiler -t UD_PortType.ttcn UD_Types.ttcn


will generate UD_PT.hh:

// This Test Port skeleton header file was generated by the
// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4C
// for Elemer Lelik (ethlel@esekilxxen1842) on Tue Feb  9 09:02:15 2016

// Copyright (c) 2000-2015 Ericsson Telecom AB

// You may modify this file. Add your attributes and prototypes of your
// member functions here.

#ifndef UD__PT_HH
#define UD__PT_HH

#include <TTCN3.hh>

// Note: Header file UD_PortType.hh must not be included into this file!
// (because it includes this file)
// Please add the declarations of message types manually.

namespace UD__PortType {

class UD__PT_PROVIDER : public PORT {
public:
	UD__PT_PROVIDER(const char *par_port_name);
	~UD__PT_PROVIDER();

	void set_parameter(const char *parameter_name,
		const char *parameter_value);

private:
	/* void Handle_Fd_Event(int fd, boolean is_readable,
		boolean is_writable, boolean is_error); */
	void Handle_Fd_Event_Error(int fd);
	void Handle_Fd_Event_Writable(int fd);
	void Handle_Fd_Event_Readable(int fd);
	/* void Handle_Timeout(double time_since_last_call); */
protected:
	void user_map(const char *system_port);
	void user_unmap(const char *system_port);

	void user_start();
	void user_stop();

	void outgoing_send(const UD__Types::UD__close& send_par);
	void outgoing_send(const UD__Types::UD__listen& send_par);
	void outgoing_send(const UD__Types::UD__shutdown& send_par);
	void outgoing_send(const UD__Types::UD__connect& send_par);
	void outgoing_send(const UD__Types::UD__send__data& send_par);
	virtual void incoming_message(const UD__Types::UD__listen__result& incoming_par) = 0;
	virtual void incoming_message(const UD__Types::UD__connect__result& incoming_par) = 0;
	virtual void incoming_message(const UD__Types::UD__connected& incoming_par) = 0;
	virtual void incoming_message(const UD__Types::UD__send__data& incoming_par) = 0;
};

} /* end of namespace */

#endif



and UD_PT.cc:


// This Test Port skeleton source file was generated by the
// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/5 R4C
// for Elemer Lelik (ethlel@esekilxxen1842) on Tue Feb  9 09:02:15 2016

// Copyright (c) 2000-2015 Ericsson Telecom AB

// You may modify this file. Complete the body of empty functions and
// add your member functions here.

#include "UD_PT.hh"
#include "UD_PortType.hh"

namespace UD__PortType {

UD__PT_PROVIDER::UD__PT_PROVIDER(const char *par_port_name)
	: PORT(par_port_name)
{

}

UD__PT_PROVIDER::~UD__PT_PROVIDER()
{

}

void UD__PT_PROVIDER::set_parameter(const char * /*parameter_name*/,
	const char * /*parameter_value*/)
{

}

/*void UD__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
	boolean is_writable, boolean is_error) {}*/

void UD__PT_PROVIDER::Handle_Fd_Event_Error(int /*fd*/)
{

}

void UD__PT_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/)
{

}

void UD__PT_PROVIDER::Handle_Fd_Event_Readable(int /*fd*/)
{

}

/*void UD__PT_PROVIDER::Handle_Timeout(double time_since_last_call) {}*/

void UD__PT_PROVIDER::user_map(const char * /*system_port*/)
{

}

void UD__PT_PROVIDER::user_unmap(const char * /*system_port*/)
{

}

void UD__PT_PROVIDER::user_start()
{

}

void UD__PT_PROVIDER::user_stop()
{

}

void UD__PT_PROVIDER::outgoing_send(const UD__Types::UD__close& /*send_par*/)
{

}

void UD__PT_PROVIDER::outgoing_send(const UD__Types::UD__listen& /*send_par*/)
{

}

void UD__PT_PROVIDER::outgoing_send(const UD__Types::UD__shutdown& /*send_par*/)
{

}

void UD__PT_PROVIDER::outgoing_send(const UD__Types::UD__connect& /*send_par*/)
{

}

void UD__PT_PROVIDER::outgoing_send(const UD__Types::UD__send__data& /*send_par*/)
{

}

} /* end of namespace */



So the first step you should probably take is to design the port declaration .


Best regards

Elemer
Re: TTCN Titan Testport for socketCAN [message #1739565 is a reply to message #1722791] Tue, 02 August 2016 22:59 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Took some time, but here is a first port declaration.

module SocketCAN_PortType
{
import from SocketCAN_Types all;

  type port SocketCAN_PT message
  {
    out   SocketCAN_close;
    out   SocketCAN_listen;
    in    SocketCAN_listen_result;
    out   SocketCAN_ioctl;
    in    SocketCAN_ioctl_result;
    out   SocketCAN_connect;
    in    SocketCAN_connect_result;
    out   SocketCAN_bind;
    in    SocketCAN_bind_result;    
    out   SocketCAN_send_data;
    out   SocketCAN_sendto_data;
    out   SocketCAN_write_data;
    in    SocketCAN_receive_data;
    in    SocketCAN_connected;
    in    SocketCAN_bound;
    out   SocketCAN_setsockopt; 
    out   SocketCAN_shutdown;
  } with { extension "provider" }
}


I have generated the code with:
compiler -t SocketCAN_PortType.ttcn SocketCAN_Types.ttcn Bcm.ttcn Can.ttcn Raw.ttcn

The SocketCan interface seems to be more complex than the UD_PortType.

1. Listen is used to open the socket
2. SocketCAN_ioctl is used to define, which CAN-Interface shall be used.
3. SocketCAN_connect is used to interact with the SocketCan Broadcast Manager (not for sending CAN messages).
4. SocketCAN_bind is used to send CAN messages (not for interaction with the broadcast manager)
5. SocketCAN_send_data is used to send to an interface that has not been bound to the 'any' interface.
6. SocketCAN_sendto_data is used to send on a socket that is bound to the 'any' interface.
7. SocketCAN_write_data is used to send data to the broadcast manager
8. SocketCAN_receive_data is used for data reception (for Handle_Fd_Event_Readable)
9. SocketCAN_connected unclear where it is needed for. It is defined as input in the UD_PortType.ttcn example, but used in UD_PT.cc like an output.
10. SocketCAN_bound same as 9. , but for bind operation instead of connect.
11. SocketCAN_setsockopt to do various operations for CAN RAW-sockets.
12. SocketCAN_shutdown closes the file handle

Further questions:
- For what purpose is path in UD_Types.ttcn used? Is it needed here as well?
- Is it wise to include here something like general types or better to define the variables like UInt32 locally, with the risk of later naming conflicts.
- Is it better to use integer or octetstring? Is the main difference the format used in the log files?
- I have seen the setsockopt is marked with the '__THROW'. Does this have impact on titan?

Reference:
https://www.kernel.org/doc/Documentation/networking/can.txt
http://stackoverflow.com/questions/2486386/why-do-i-see-throw-in-a-c-library
Re: TTCN Titan Testport for socketCAN [message #1739616 is a reply to message #1739565] Wed, 03 August 2016 10:19 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

well done!

- For what purpose is path in UD_Types.ttcn used? Is it needed here as well?

the path identifies the Unix socket that is referred to , see http://blog.siphos.be/2011/12/unix-domain-sockets-are-files/
it should not be needed here

- Is it wise to include here something like general types or better to define the variables like UInt32 locally, with the risk of later naming conflicts.

I believe it's better to use the file General_Types.ttcn in https://github.com/eclipse/titan.ProtocolModules.COMMON

- Is it better to use integer or octetstring? Is the main difference the format used in the log files?

I'd say octetstring is more comprehensible in logs


Let me come back about the fourth question.

BTW, do you plan by any chance to make your port open source as part of Titans' toolbox?

Best regards
Elemer



- Is it better to use integer or octetstring? Is the main difference the format used in the log files?


Re: TTCN Titan Testport for socketCAN [message #1739641 is a reply to message #1739616] Wed, 03 August 2016 13:21 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elmer,

> BTW, do you plan by any chance to make your port open source as part of Titans' toolbox?
Yes I do. I think it makes most sense to have the test ports and stubs open source. Especially for the CAN bus, which seems to continually develop further.
When I looked 6 month ago on the SocketCAN documentation, there was nothing about multiple CAN-interfaces or CAN FD.
However I can obviously not commit on any deadlines for completion.
> I believe it's better to use the file General_Types.ttcn
Ok. I will selectively include from General_Types.ttcn

> Let me come back about the fourth question.
Form what I see, I have the choice between:
- integer
- octectstring
for unsigned numbers of the size 8-bit, 16-bit, 32-Bit, ..

and for bit fields like "Flags"
- integer
- octectstring
- bitstring
- record {boolean bit0, boolean bit1, boolean bit3, .., boolean reserved0, ..} with variant {..}
I will await your answer, then make the update and then start with the C++ code.

One further question:
In the following thread you have reported about Windows Subsystem for Linux:
https://www.eclipse.org/forums/index.php?t=msg&th=1076950&goto=1730666&#msg_1730666

Are you aware if this will also provide the socketcan interface, which is otherwise not available on Windows as far as I know?

Best regards,
Michael
Re: TTCN Titan Testport for socketCAN [message #1739653 is a reply to message #1739641] Wed, 03 August 2016 13:42 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


Form what I see, I have the choice between:
- integer
- octetstring
for unsigned numbers of the size 8-bit, 16-bit, 32-Bit, ..

and for bit fields like "Flags"
- integer
- octetstring
- bitstring
- record {boolean bit0, boolean bit1, boolean bit3, .., boolean reserved0, ..} with variant {..}


For the first one, I would chose octetstring, as it is more readable;
for "Flags" , I'd go with bitstring as it's closest to bitfield.



Are you aware if this will also provide the socketcan interface, which is otherwise not available on Windows as far as I know?


Sorry , I have no info; I'm waiting for the Win 10 Anniversary Update then I'll start playing with it. However I understand WSL will be based on Ubuntu 16.04, and there's a chance socketcan will be supported.




- I have seen the setsockopt is marked with the '__THROW'. Does this have impact on titan?

I still owe you an answer for that one. I'll come back to you.



BR Elemer




Re: TTCN Titan Testport for socketCAN [message #1739714 is a reply to message #1739653] Thu, 04 August 2016 08:46 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

regarding this:

- I have seen the setsockopt is marked with the '__THROW'. Does this have impact on titan?


'__THROW' signifies that the socket cannot throw an exception , hence no impact on Titan is expected.

BR
Elemer

Re: TTCN Titan Testport for socketCAN [message #1739955 is a reply to message #1739714] Fri, 05 August 2016 22:42 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
> I have no info; I'm waiting for the Win 10 Anniversary Update then I'll start playing with it. However I understand WSL will be based on Ubuntu 16.04, and there's a chance socketcan will be supported.
If there should be no CAN device driver support for SocketCAN under WSL, then it might work to use canneloni to connect CAN-Messages over the network to a Linux based PC, which provides the physical (e.g. CAN-USB) link to the external CAN-Device.
Re: TTCN Titan Testport for socketCAN [message #1739972 is a reply to message #1739955] Sat, 06 August 2016 09:39 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

this is what I have seen so far:

-it's an Ubuntu 14.04 (not 16.04); not that it matters much
-socketcan is not in the repository
-most discouraging of all , networking part is not fully implemented:
Ifconfig, Ip addr etc. , netstat , ping, traceroute , tracepath does not work

but the stack is there and can be used, as curl, wget, apt-get xxxx, nslookup are working

as I can't refer directly to the interfaces, it's unlikely canneloni can be used

maybe these will be fixed, but for the moment from CAN Bus perspective you are better off with a VmWare/VirtualBox Linux machine run on the Windows host

Best regards
Elemer

Re: TTCN Titan Testport for socketCAN [message #1740236 is a reply to message #1739972] Wed, 10 August 2016 15:23 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elmer,

thanks a lot.
> Ifconfig, Ip addr etc. , netstat , ping, traceroute , tracepath does not work
According to the wsl faq at least ping is a known issued to be solved, it currently requires bash to be started with administrator privileges. See :
https://msdn.microsoft.com/en-us/commandline/wsl/faq
Have you checked with administrator privileges?
Here is also a bug report:
https://github.com/Microsoft/BashOnWindows/issues/69

Anyway I have here added a feature request. Please upvote:
https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo/suggestions/15617214-socketcan-support

Best regards,
Michael

[Updated on: Wed, 10 August 2016 15:28]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1740251 is a reply to message #1740236] Wed, 10 August 2016 17:48 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elmer,

in the meantime a have dug more into the SocketCAN interface. Now it is time to get the interface right and accessing optional and union configurations from C++.

Questions:
1) When sending a message via SocketCAN an interface address such as "can0":
- can be given as interface name
- as interface index (before retrieved with ioctl(..) command from interface name)
- not given any interface address

This can be modeled using an optional attribute and union:

type union SocketCAN_ifu {
  SocketCAN_if_name                if_name, 
  SocketCAN_if_index               if_index
} 

type record SocketCAN_send_data{
  SocketCAN_socketid               id,
  SocketCAN_ifu                    ifu optional,
  SocketCAN_CAN_or_CAN_FD_frame    frame
}


alternatively it may modeled using union and an enumeration (representing the ASN.1 NULL type):

 type enumerated SocketCAN_if_any { ANY }

type union SocketCAN_ifu {
 SocketCAN_if_any                   if_any
  SocketCAN_if_name              if_name, 
  SocketCAN_if_index               if_index
} 

type record SocketCAN_send_data{
  SocketCAN_socketid               id,
  SocketCAN_ifu                    ifu,
  SocketCAN_CAN_or_CAN_FD_frame    frame
}


What is the better solution?

2) Any suggestions better coping with the type nesting level :

Looking here for improvements to:
2a) TTCN code and
frame.CAN_FD_frame.can_pdu[6] = ....


SocketCAN_write_data:
bcm_tx_msg.opcode
bcm_tx_msg.flags
bcm_tx_msg.frames.canfd_frame[56].can_pdu[7] = ...


2b) C++ code:
void SocketCAN__PT_PROVIDER::outgoing_send(
const SocketCAN__Types::SocketCAN__write__data& send_par) {
Such as:
void SocketCAN__PT_PROVIDER::outgoing_send(
....
      const SocketCAN__Types::SocketCAN__write__data& send_par) {
....
      bcm_msg.msg_head.opcode = send_par.bcm__tx__msg().opcode();
      bcm_msg.msg_head.flags = send_par.bcm__tx__msg().flags();
      bcm_msg.msg_head.count = send_par.bcm__tx__msg().count();
      bcm_msg.msg_head.ival1.tv_sec = send_par.bcm__tx__msg().ival1().tv__sec();
      bcm_msg.msg_head.ival1.tv_usec = send_par.bcm__tx__msg().ival1().tv__usec();
      bcm_msg.msg_head.ival2.tv_sec = send_par.bcm__tx__msg().ival2().tv__sec();
      bcm_msg.msg_head.ival2.tv_usec = send_par.bcm__tx__msg().ival2().tv__usec();


converting to:
void SocketCAN__PT_PROVIDER::outgoing_send(
      const SocketCAN__Types::SocketCAN__write__data& send_par) {
....
      Bcm::SocketCAN__bcm__frame& msg = send_par.bcm__tx__msg();
      bcm_msg.msg_head.opcode = msg.opcode();
      bcm_msg.msg_head.flags = msg.flags();
      bcm_msg.msg_head.count = msg.count();
      bcm_msg.msg_head.ival1.tv_sec = msg.ival1().tv__sec();
      bcm_msg.msg_head.ival1.tv_usec = msg.ival1().tv__usec();
      bcm_msg.msg_head.ival2.tv_sec = msg.ival2().tv__sec();
      bcm_msg.msg_head.ival2.tv_usec = msg.ival2().tv__usec();


Best regards,
Michael

[Updated on: Sun, 14 August 2016 18:22]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1740465 is a reply to message #1740251] Sat, 13 August 2016 19:38 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
When defining e.g. :
Can.ttcn:
type octetstring CAN_id length (4);


then this causes errors in the following generated code in can.cc:

void CAN__frame::set_implicit_omit()
{
if (can__id().is_bound()) can__id().set_implicit_omit();
if (can__pdu().is_bound()) can__pdu().set_implicit_omit();
}

with the message : Method "set_implicit_omit()" could not be resolved.

A workaround to this is defining "can_id" as "bitstring" or "hexstring" of the equivalent length:

type hexstring CAN_id length (8);

Same applies for all other used types having a length restriction such as:
Can.ttcn:
CAN_frame.can_pdu
CAN_FD_frame.can_pdu

bcm.ttcn:
SocketCAN_bcm_frame. opcode
SocketCAN_bcm_frame. count

It also applies when e.g. "OCT4" of "General_Types.ttcn" is used:
type OCT4 CAN_id;

[Updated on: Sat, 13 August 2016 19:53]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1740502 is a reply to message #1739972] Mon, 15 August 2016 09:05 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

sorry, I've been away for a while;

>Have you checked with administrator privileges?

Yes, although some of the networking commands do not require superuser.


I did upvote your feature request.


I'll come back to the rest of the questions,

Best regards

Elemer

Re: TTCN Titan Testport for socketCAN [message #1740518 is a reply to message #1740251] Mon, 15 August 2016 10:58 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

1) What is the better solution?

everything else being equal I always prefer the simpler solution; so I would go for the first alternative ( which consists of two declarations )

type union SocketCAN_ifu {
  SocketCAN_if_name                if_name, 
  SocketCAN_if_index               if_index
} 

type record SocketCAN_send_data{
  SocketCAN_socketid               id,
  SocketCAN_ifu                    ifu optional,
  SocketCAN_CAN_or_CAN_FD_frame    frame
}



2)Any suggestions better coping with the type nesting level

I'm afraid not; I believe here readability should be pursued and it's not worth saving a few letters; but I admit this is highly subjective.


We have to look into the implicit omit issue; I'll be back.

Best regards

Elemer



Re: TTCN Titan Testport for socketCAN [message #1740519 is a reply to message #1740465] Mon, 15 August 2016 11:05 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,



I could not reproduce the mentioned error:

makefilegen -f Can.ttcn General_Types.ttcn
Generating Makefile skeleton...
Makefile skeleton was generated.
zenmachine1962  [13:01] [/home/ethlel/Josenhans] -> make
/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/bin/compiler -L  \
        Can.ttcn General_Types.ttcn  - Can.ttcn General_Types.ttcn
Notify: Parsing TTCN-3 module `Can.ttcn'...
Notify: Parsing TTCN-3 module `General_Types.ttcn'...
Notify: Checking modules...
Notify: Generating code...
Notify: File `Can.hh' was generated.
Notify: File `Can.cc' was generated.
Notify: File `General_Types.hh' was generated.
Notify: File `General_Types.cc' was generated.
Notify: 4 files were updated.
touch compile
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -Wall   -o Can.o Can.cc
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -Wall   -o General_Types.o General_Types.cc
if g++   -o Can Can.o General_Types.o  \
        -L/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/lib -lttcn3-parallel \
        -L/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/lib -lcrypto \
        -L/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/lib -lxml2 -lpthread -lrt; \
        then : ; else /proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/bin/titanver Can.o General_Types.o ; exit 1; fi




Where Can.ttcn is from the zip file you have attached.


I am using the latest Titan so maybe this is something that has been already fixed.

What is the response to compiler -v ?

Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1740552 is a reply to message #1740519] Mon, 15 August 2016 15:55 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
So far I have to to use the second alternative:

type enumerated SocketCAN_if_any { ANY }

type union SocketCAN_send_data_ifu {
  SocketCAN_if_any                    if_any,
  SocketCAN_if_name                if_name, 
  SocketCAN_if_index                if_index
} 
type record SocketCAN_send_data{
  SocketCAN_socketid                    id,
  SocketCAN_send_data_ifu          ifu optional,   // made optional for demonstration purposes
  SocketCAN_CAN_or_CAN_FD_frame    frame
}


As I make the union optional as shown above the same code that complied before does not compile any longer. With my current code, which I will upload soon I get the following error:

SocketCAN_PT.cc: In member function 'void SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__send__data&)':
SocketCAN_PT.cc:553:40: error: 'const class OPTIONAL<SocketCAN__Types::SocketCAN__send__data__ifu>' has no member named 'if__name'
    strcpy(ifr.ifr_name, send_par.ifu().if__name());
                                        ^
SocketCAN_PT.cc:568:3: warning: case value '3' not in enumerated type 'optional_sel' [-Wswitch]
   case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
   ^
SocketCAN_PT.cc:608:5: warning: case value '3' not in enumerated type 'optional_sel' [-Wswitch]
     case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
     ^
SocketCAN_PT.cc:684:5: warning: case value '3' not in enumerated type 'optional_sel' [-Wswitch]
     case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
     ^
Makefile:140: recipe for target 'SocketCAN_PT.o' failed


Do I need to change my C++ code in order to make it compilable after making this optional. Surely I have to make code changes to get this working in runtime.

> I am using the latest Titan so maybe this is something that has been already fixed.
> What is the response to compiler -v ?
compiler -v
TTCN-3 and ASN.1 Compiler for the TTCN-3 Test Executor
Product number: CRL 113 200/5 R5A
Build date: Aug 1 2016 18:50:42
Compiled with: GCC 5.4.0

Copyright (c) 2000-2016 Ericsson Telecom AB

My current guess is that it has been an Eclipse CDT highlighting problem or a makefile problem or both. I had problems until I started to running "make clean" before running "make".
Re: TTCN Titan Testport for socketCAN [message #1740586 is a reply to message #1740552] Mon, 15 August 2016 22:28 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elmer,

with some workarounds I got it working. I had e.g. to change the data types from OCTETSTRING to INTEGER and commented those changes in Can.ttcn and Bcm.ttcn in order to get it working. I will come back to these in the coming days.

SocketCANtest.ttcn provides testcases.
The first test case (CAN_RAW) sends an receives a message via a virtual can.
The second test cases 2 (CAN_BCM) uses the CAN Broadcast manager, which e.g. allows to configure cyclic sending of messages with write(...) . It fails as it sends too few data and then repeats this multiple times. This can be seen in the attached log file.
However may be a similar kernel issue as in the python bug report below. The BCM seems to be still under development:
https://bitbucket.org/hardbyte/python-can/issues/58/sending-periodically-doesnt-work-even

I have created a Readme.md file which explains how to get it working.

Cyclic sending and receiving of messages is one of the main use cases in CAN.
Thus there need to be TTCN components:
a) which look for cyclic reception of a matching CAN message:
- they need to be dynamically created, started , stopped, restarted (I guess)
- they need to log, set verdict or just report a missing message via Port
- optionally they need to report status changes further, but filter unchanged messages
- may or may not use the BCM, but provide the same high level interface in both cases
b) which cyclic send a CAN message with given content:
- they need to be dynamically created, started , stopped, restarted (I guess)
- the given CAN message content needs to be modifiable via a port (e.g. simulating vehicle speed changes or toggle the door open status)
- may or may not use the BCM, but provide the same high level interface in both cases

This reminds me on your article on Dual face test ports.

Questions:
- Is it possible to transmit match templates via ports?
- Is it possible to transmit functions (like funs in Erlang) via ports?
- How about:
- one component type for handling a), which creates one via a port configurable instance for each filtering / matching criteria.
- one component type for handling b), which creates one via a port configurable instance for each CAN message to be cyclic send

Best regards,
Michael
PS:
The attached files have the same license as Titan.
Re: TTCN Titan Testport for socketCAN [message #1740618 is a reply to message #1740586] Tue, 16 August 2016 10:32 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


first of all, congrats. Well done!

A few thoughts:

- I tried to compile your code (on Ubuntu 14,04) and I got the following error:
g++  -c -DLINUX -I/home/ntaf/TTCNv3-5.4.pl1-linux64-gcc4.8-ubuntu14.04-foss/include -Wall   -o SocketCAN_PT.o SocketCAN_PT.cc
SocketCAN_PT.cc: In member function 'void SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__setsockopt&)':
SocketCAN_PT.cc:1108:40: error: 'CAN_RAW_JOIN_FILTERS' was not declared in this scope
    res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,
                                        ^
make: *** [SocketCAN_PT.o] Error 1




the reason for the error being that CAN_RAW_JOIN_FILTERS
is not declared in my raw.h:




ntaf@ntaf:~/Josenhans/titan.TestPorts.SOCKET_CANasp/src$ cat /usr/src/linux-headers-3.13.0-92/include/uapi/linux/can/raw.h
/*
 * linux/can/raw.h
 *
 * Definitions for raw CAN sockets
 *
 * Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
 *          Urs Thuermann   <urs.thuermann@volkswagen.de>
 * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Volkswagen nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * Alternatively, provided that this notice is retained in full, this
 * software may be distributed under the terms of the GNU General
 * Public License ("GPL") version 2, in which case the provisions of the
 * GPL apply INSTEAD OF those given above.
 *
 * The provided data structures and external interfaces from this code
 * are not restricted to be used by modules with a GPL compatible license.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#ifndef CAN_RAW_H
#define CAN_RAW_H

#include <linux/can.h>

#define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW)

/* for socket options affecting the socket (not the global system) */

enum {
	CAN_RAW_FILTER = 1,	/* set 0 .. n can_filter(s)          */
	CAN_RAW_ERR_FILTER,	/* set filter for error frames       */
	CAN_RAW_LOOPBACK,	/* local loopback (default:on)       */
	CAN_RAW_RECV_OWN_MSGS,	/* receive my own msgs (default:off) */
	CAN_RAW_FD_FRAMES,	/* allow CAN FD frames (default:off) */
};

#endif
ntaf@ntaf:~/Josenhans/titan.TestPorts.SOCKET_CANasp/src$ 




which raises the question of socketcan etc. versions.

Maybe you should specify in Readme.md which versions are needed for your code to tun.

- a generic note: the Titan compiler and the Eclipse plug-ins are totally independent implementations, which means that they can contradict each other: the plug-in may indicate an error and the compiler may not. In such cases the compiler is to be considered authoritative and the plug-in will have to be probably fixed.

However, if the first alternative causes problems, could you create a package that displays the symptom, s we can take a look?




- a question: would you agree that we publish in open source the code of the test port?
(For administrative reasons, we cannot use github for the coming products, but Eclipse git; but we will create a link in github pointing to the egit repo.


-not strictly related , but you were right about ping: if bash is started as admin ("Run as administrator") then ping will work


-the OCTETSTRING to Integer thing is weird and we would like to investigate it; could you create a package that presents the symptom so we can take a look?


- I don't know much about CAN but creating , stopping, restarting etc. components does not seem the right way to do it; why just starting a component , receiving cyclically and stopping at the end is not enough?


> - Is it possible to transmit match templates via ports?

I'm not sure exactly what you have in mind, could you describe the use case?

> - Is it possible to transmit functions (like funs in Erlang) via ports?

as above; I don't think so though



Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1740663 is a reply to message #1740618] Wed, 17 August 2016 00:09 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elmer,

The best solution would be something like this:

SocketCAN_PT.cc:
#ifdef CAN_RAW_JOIN_FILTERS
   ....
   setsockopt(sock, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,	&join_filters, sizeof(join_filters));
   ....     
#else
     TTCN_error("SocketCAN: setsockopt option CAN_RAW_JOIN_FILTERS is not supported by the current can-utils version"),
#endif 


This does not work, however as enum values are not available to the preprocessor.

A similar issue exists for FD frames which are described in the current documentation, however do not seem to be implemented by my can-utils version.
I did this crude workaround, but I will replace it by a solution as above:

SocketCAN_PT.cc:
// workaround, as not yet defined in "linux/can/Bcm.h":
#define CAN_FD_FRAME 0x0800


Anyway the workaround is easy. Just add the following code to the file "SocketCAN_PT.cc":
// workaround, as some of those below may not yet be defined in "linux/can/raw.h":
#define CAN_RAW_FILTER        = 1 /* set 0 .. n can_filter(s)          */
#define CAN_RAW_ERR_FILTER	  = 2 /* set filter for error frames       */
#define CAN_RAW_LOOPBACK      = 3 /* local loopback (default:on)       */
#define CAN_RAW_RECV_OWN_MSGS = 4 /* receive my own msgs (default:off) */
#define CAN_RAW_FD_FRAMES     = 5 /* allow CAN FD frames (default:off) */
#define CAN_RAW_JOIN_FILTERS  = 6 /* all filters must match to trigger */


The workaround has the problem that a divergence of the emun definition and the #define definitions will happen unnoticed. Please note that above option setsockopt(..., CAN_RAW_JOIN_FILTERS,...) is not used by the currently available test cases and even if it would be called, I expect it to provide a useful error code as response.

Nevertheless, I do not see a proper solution without changes to the file "linux/can/raw.h". Either by adding additional preprocessor #define feature flags or converting the enum into defines.
I think this will require discussion with the linux-can developers on their mailing list. Currently the same people implement the userspace can-utils and the SocketCAN part of the Linux kernel.
Thus SocketCAN versioning may have not been on focus in the past.

> Maybe you should specify in Readme.md which versions are needed for your code to tun.
Yes. However this will be difficult until I understand the SocketCAN versioning sheme. My current guess is that with the workarounds everything will work, except that some of the function calls of the SocketCAN interface may fail and return an appropriate errno error code. From what I see, CAN FD support and some advanced filtering and BCM operations will be problematic.

>- a generic note: the Titan compiler and the Eclipse plug-ins are totally independent implementations, which means that they can contradict each other: the plug-in may indicate an error and the compiler may not. In such cases the compiler is to be considered authoritative and the plug-in will have to be probably fixed.
I am using just the Titan compiler and plain CDT Eclipse for C++ from Ubuntu without titan specific plug-ins at the moment.

> However, if the first alternative causes problems, could you create a package that displays the symptom, s we can take a look?
Please use the zip-file in my message from "Mon, 15 August 2016 22:28" and use the latest version of the Titan compiler. Eclipse is not needed.
Just apply the following change:
SocketCAN_PT.cc:
#define CAN_RAW_JOIN_FILTERS  = 6 /* all filters must match to trigger */

run:
make
There should be no compile errors.
Follow the Readme.md. Test case SocketCANtest.tc_can_raw1 should be fine, while Testcase SocketCANtest.tc_can_bcm1 will fail.

Then change SocketCAN_Types.ttcn by adding the keyword "optional" as shown:
type record SocketCAN_send_data{
  SocketCAN_socketid                    id,
  SocketCAN_send_data_ifu          ifu optional,   // made optional for to trigger titan error
  SocketCAN_CAN_or_CAN_FD_frame    frame
}

run:
make clean; make
The error above in my mesage from "Mon, 15 August 2016 15:55" will occur.

If you have further questions. Please let me know.

> - a question: would you agree that we publish in open source the code of the test port?
Yes. Let me know when you need something from me. When is it due?

> (For administrative reasons, we cannot use github for the coming products, but Eclipse git; but we will create a link in github pointing to the egit repo.
> egit repo
I do not know egit. Can I still use git command-line tools or do I need to use Eclipse?

> -the OCTETSTRING to Integer thing is weird and we would like to investigate it; could you create a package that presents the symptom so we can take a look?
I have written a list of issues down and I will come back when you have successfully compiled above package.

> - I don't know much about CAN but creating , stopping, restarting etc. components does not seem the right way to do it; why just starting a component , receiving cyclically and stopping at the end is not enough?
Yes. That may be the right way to handle it in TTCN.

> - Is it possible to transmit match templates via ports?
>I'm not sure exactly what you have in mind, could you describe the use case?
Can I provide a component with parameters during component startup. E.g. with a CAN ID and a bit pattern that has to match the received PDU to trigger an action on an TTCN internal port interface. Instead of sending bit pattern over the port, sending a match function if possible by TTCN standard might be more time efficient.

Best regards,
Michael
Re: TTCN Titan Testport for socketCAN [message #1740692 is a reply to message #1740663] Wed, 17 August 2016 10:54 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-about the "optional" error:

you need to change in SocketCAN_PT.cc

line 554:
to
switch (send_par.ifu().get_selection()) {
                               case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__name: {
                                             const OPTIONAL<SocketCAN__Types::SocketCAN__send__data__ifu>& ifu = send_par.ifu();
                                               strcpy(ifr.ifr_name, ifu().if__name()); // Here ifu() calls the overloaded () operator of OPTIONAL class, which returns the ifu field.
                                               res = ioctl(sock, SIOCGIFINDEX, &ifr);
                                               if (res != 0) {
                                                               TTCN_warning(
                                                                                              "Send CAN frame: Ioctl failed while retrieving the interface : %d with interface index %s\n",
                                                                                              sock, ifr.ifr_name);
                                                               result.result().result__code() =
                                                                                              SocketCAN__Types::SocketCAN__Result__code::ERROR_;
                                                               result.result().err() = errno;
                                                               result.result().err__text() =
                                                                                              "Send CAN frame: Ioctl failed while retrieving the interface";
                                               }
                                               addr.can_ifindex = ifr.ifr_ifindex;
                                               addr.can_family = AF_CAN;
                                               break; }



(or
strcpy(ifr.ifr_name, send_par.ifu()().if__name());

)

The optional fields are enveloped in an OPTIONAL class with an overloaded operator which returns the optional field.


-we can publish as soon as you give us the green light; we will do a review before which we will run by you of course

-Can I provide a component with parameters during component startup.
yes definitely, module parameters seem the appropriate means to do it , see https://www.eclipse.org/forums/index.php/t/1077635/

I believe what you describe is a template in TTCN-3 terms;
one can specify a template , possibly based on module parameters,
and confront at reception the incoming message with the template ;
if there is a match ( it does not have to be an exact match, wildcards (?, * ) can be used ) a certain action is taken, else execution continues elsewhere.

-eclipse git can e used from command line as well; however we are still figuring it out as it is new for us too; so far we published in github but we sort of exhausted some quota there so from now on we will publish in eclipse git.

As we have all the details I'll let you know

I'll also give you examples in TTCN-3 for repetitive sending /receiving , but it's nothing complicated , you need to enclose your sending/receiving instructions in a loop , possibly with timers to control frequency of sending and waiting time at reception


Best regards
Elemer


Re: TTCN Titan Testport for socketCAN [message #1740971 is a reply to message #1740692] Sun, 21 August 2016 23:12 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elmer,
thank you for the the help.

>>-Can I provide a component with parameters during component startup.
>yes definitely, module parameters seem the appropriate means to do it , see https://www.eclipse.org/forums/index.php/t/1077635/
Great. I was always wondering how to handle Pics & Pixit in TTCN.
Pixit:
- FD CAN support (yes / no) (by the hardware under test, the CAN-adapter and / or the LINUX kernel used.)
Pics:
- For RAW data (sending of CAN frames as broadcast to all CAN nodes listening):
the selected socket can interface e.g. "any", vcan0, "can0"
- For BCM (using the SocketCAN broadcast manager for all sorts of things like filtering received frames or cyclicly sending frames):
the selected socket can interface e.g. "any", vcan0, "can0"
- For ISO-TP (comming soon ..)
the selected socket can interface e.g. vcan0, "can0"
the source can_id, destination source can_id
Note: ISOTP is a segmentation / reassembly protocol transferring bigger chunks of data over the CAN / CAN FD protocol to a remote ECU identified by its can_id. It is used transfer software updates or diagnostic messages using the UDS protocol.)

I have fixed lots of bugs and added quite some test coverage. The missing CAN FD define on Ubuntu 14. 04. should no longer be a compile problem. The BCM is working now and setsockopt() function had been implemented.
However when implementing parallel testing using components I broke all test cases. The public documentation on parallel test components is not helpful. Are there examples?

Currently I have something like this (SocketCANtest.ttcn), but its broken:
type component TimedComponent {
    port SocketCAN_PT pt_socketCAN 
    timer Tl_timer := 0.2
}
type component SocketCAN_comptype {
    port SocketCAN_PT pt_socketCAN
    timer Tl_timer := 0.2
}

  var SocketCAN_comptype v_raw_responder_ref := SocketCAN_comptype.create("Raw_responder")
  var SocketCAN_comptype v_raw_initator_ref := SocketCAN_comptype.create("Raw_initator")
  
  map(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  map(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)
 
  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_send
  v_frame_to_send := {canfd_frame := 
                       {can_id := 21, 
                        can_flags := '00000000'B, 
                        can_pdu := '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'O}
                    }
  v_raw_responder_ref.start(f_raw_responder(v_raw_responder_ref, c_if_name, v_frame_to_send))
  v_raw_initator_ref.start(f_raw_initiator(v_raw_initator_ref, c_if_name, v_frame_to_send))

....
  
  Tl_timer.start;
  Tl_timer.timeout;

  unmap(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  unmap(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)


- Could you give me a hint an on how to fix e.g. testcase tc_can_raw1.
- Should I use templates to check respones.

> -we can publish as soon as you give us the green light; we will do a review before which we will run by you of course
some issues I am aware of:
- ISOTP changes
- SocketCAN Port Interface has currently no SocketCAN__PT_PROVIDER::shutdown() method
I guess it is needed as I saw some error message. I do not know what needs to be done there.
- Maybe some refactoring out code into classes CAN_RAW, CAN_BCM and CAN_ISOTP with methods for socket_open, sending data, receiving data, ...
- Maybe having classes for the different protocols CAN / CAN_FD.
- I am unsure, whether I should be able to call multiple binds or multiple connects using the same socket id. I do not think my code is working here correctly.

Other questions:
- Can the "RAW Encoder and Decoder" used also in conjunction with ASN.1 code instead of TTCN code?
- Are the TTCN data structures by the TTCN compiler converted the ASN.1 code as intermediate step?

> I'll also give you examples in TTCN-3 for repetitive sending /receiving , but it's nothing complicated , you need to enclose your sending/receiving instructions in a loop , possibly with timers to control frequency of sending and waiting time at reception
Great.
Best regards,
Michael
Re: TTCN Titan Testport for socketCAN [message #1741001 is a reply to message #1740971] Mon, 22 August 2016 10:02 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

a few words about parallel execution:

For single mode execution, the behaviour is described entirely by the code executed on the MTC (Main Test Component).

In case of parallel mode, it's similar, but the MTC can spawn ( create, start) and kill paralel test components, each with an independent behaviour and possibly its' own ports.


                                                                         +-------------------------+
                                                                         |                         |
            +-------------------------+                                  |         PTC3            |
            |                         |                                  |                         |
            |                         |                         +--------+----------------+        |
            |                         |                         |                         |        |
            |                         |                         |         PTC2            |        |
            |         MTC             |                         |                         |        |
            |                         |               +---------+---------------+         |        |
            |                         |               |                         |         |        |
            |                         |               |                         |         |        |
            |                         |               |                         |         |        |
            |                         |               |                         |         +---+----+
            |                         |               |                         |         |   |
            +-------------------------+               |       PTC1              |         |   |
                                                      |                         |         |   |
                                                      |                         +--+------+   |
                                                      |                         |  |          |
                                                      |                         |  |          |
                                                      |                         |  |          |
                                                      +-------------+-----------+  |          |
                                                                    |              |          |
                                                                    |              |          |
            +                                                       |              |          |        +
            |                                                       |              |          |        |
            +-------------------------------------------------------v--------------v----------v--------+
            |                                           SUT                                            |
            +                                                                                          +




The below skeleton is an example of using PTCs:
(there are other ways of course to reach the same result, but this is a tested and proven flow)


module  ExMod 

{


//component declarations
type component MTC_CT
{ 
  :
}

type component PTC1_CT
{
  //variables
  //timers
  timer Tl:= 0.2
  
  :
}
type component PTC2_CT
{
  //variables
  //timers
  timer Tl:= 0.2
  :
}
type component PTC3_CT
{
  //variables
  //timers
  :
}

//parallel test component behaviour declarations
function  f_behaviour1()  runs on PTC1_CT
{
  
}


function  f_behaviour2()  runs on PTC2_CT
{
  
}

function  f_behaviour3()  runs on PTC3_CT
{
  
}

//test case declarations
testcase tc_Example001  runs on MTC
{
  //create components
  v_PTC1:=PTC1_CT.create; 
  v_PTC2:=PTC2_CT.create; 
  v_PTC3:=PTC3_CT.create; 
  
  //connnect ports
  //map ports
  
  //start components 
  
  v_PTC1.start(f_behaviour1());
  v_PTC2.start(f_behaviour2());
  v_PTC3.start(f_behaviour3());
  
  //wait for termination
  all components.done
  
  
  //unmap ports
  //disconnect ports
  //terminate all parallel test componenets
  all components.kill
  
}
//when the test case terminates, MTC will terminate as well
//PTCs terminate (reach the state done) when the function with which they were started terminates

control 
{
  
  
  execute(tc_Example001())
  
  
}//endcontrol



}//endmodule




The PTC behaviours are functions with a "runs on" clause referring the the respective component type.

//----------------------------------------------------------


function  f_behaviour1()  runs on PTC1_CT
{

//periodic sending

while (condition1)

{
  port1.send(message1);
  
  T1.start 
  T1.timeout;
  
}

}

//----------------------------------------------------------
function  f_behaviour2()  runs on PTC2_CT
{

//periodic reception

while (condition2)
T1.start;

alt 
{
  []port.receive(?) { 
    T1.stop; 
    //log incoming message 
  } 
  
  []T1.timeout; 
  
}//endalt

}//endfunction



The problem with f_behaviour1() is that it will run indefinitely, the component wil never reach the state done.
Internal control ports connecting the PTCs to the MTC can be used to synchronize components:

                                                                         +-------------------------+
                                                         +--------------->sync                     |
            +-------------------------+                  |               |         PTC3            |
            |                         |         +--------+               |                         |
            |                         |         |               +-------------------------+        |
            |                         <---------+               |                         |        |
            |                         <------------------------^+sync     PTC2            |        |
            |         MTC             |                         |                         |        |
            |                         |               +-------------------------+         |        |
            |                         |               |                         |         |        |
            |                         |               |                         |         |        |
            |                         |               |                         |         |        |
            |                         <--------------->sync                     |         +--------+
            |                         |               |                         |         |   |
            +-------------------------+               |       PTC1              |         |   |
                                                      |                         |         |   |
                                                      |                         +---------+   |
                                                      |                         |  |          |
                                                      |                         |  |          |
                                                      |                         |  |          |
                                                      +-------------------------+  |          |
                                                                    |              |          |
                                                                    |              |          |
            +                                                       |              |          |        +
            |                                                       |              |          |        |
            +-------------------------------------------------------v--------------v----------v--------+
            |                                             SUT                                          |
            +                                                                                          +



//----------------------------------------------------------

function  f_behaviour1_sync()  runs on PTC1_CT
{

//periodic sending

while (condition1)

{
  port1.send(message1);
  
  T1.start 
  alt
  {
    []syncport.receive("halt") {
      condition1:=false  }
  }
  []T1.timeout;
  
}

}//endwhile
}//endfunction


//----------------------------------------------------------

function  f_behaviour2_sync()  runs on PTC2_CT
{

//periodic reception

while (condition2)
T1.start;

alt 
{
  
  []syncport.receive("halt") {
    condition2:=false  }
}

[]port.receive(?) { 
  T1.stop; 
  //log incoming message 
} 

[]T1.timeout; 

}//endalt

}//endfunction




to be continued...
Re: TTCN Titan Testport for socketCAN [message #1741002 is a reply to message #1741001] Mon, 22 August 2016 10:13 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Now, about your code snippet :

it should work with minimal modifications


:
type component TimedComponent {
    port SocketCAN_PT pt_socketCAN 
    timer Tl_timer := 0.2
}
type component SocketCAN_comptype {
    port SocketCAN_PT pt_socketCAN
    timer Tl_timer := 0.2
}



control 

{


  var SocketCAN_comptype v_raw_responder_ref := SocketCAN_comptype.create("Raw_responder")
  var SocketCAN_comptype v_raw_initator_ref := SocketCAN_comptype.create("Raw_initator")
  
  map(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  map(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)



  
  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_send
  v_frame_to_send := {canfd_frame := 
                       {can_id := 21, 
                        can_flags := '00000000'B, 
                        can_pdu := '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'O}
                    }

  v_raw_responder_ref.start(f_raw_responder(v_raw_responder_ref, c_if_name, v_frame_to_send))
  v_raw_initator_ref.start(f_raw_initiator(v_raw_initator_ref, c_if_name, v_frame_to_send))

....
  
 // Tl_timer.start;
 // Tl_timer.timeout;
 

//f_raw_responder  , f_raw_initiator  will have a "runs on clause" referring to SocketCAN_comptype
//termination of PTCs depends on termination of the above two functions

//this statement waits for termination of the two components 
 all components.done;
 
  unmap(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  unmap(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)

 //this kills the PTCs 
 all components.kill;
 
}


 :




whatever is in the control part will be executed on the MTC; when control terminates, execution and MTC terminates as well;


the only significant change is that I have added statements which will wait for the PTCs to terminate

please be aware that if the function the component was started with does not terminate, the PTCs will not terminate either



I'll come back with more.


Best regards
Elemer



Re: TTCN Titan Testport for socketCAN [message #1741006 is a reply to message #1741002] Mon, 22 August 2016 11:11 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi again,

the use of the "control" section in my previous example may be confusing;

of course if the code is part of a test case, the control section has no role there.

BR Elemer

Re: TTCN Titan Testport for socketCAN [message #1741034 is a reply to message #1741006] Mon, 22 August 2016 13:27 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I have attached the corrected tc_can_raw1 and the log files generated.

Here are the changes I have made:

1.
template SocketCAN_Result tr_result(SocketCAN_Result_code v_result_code) := {          
     result_code   := v_result_code,
     err           := *,
     err_text      := *
}



when opening the socket ,

{ id := 0, result := { result_code := SUCCESS (1), err := omit, err_text := omit } }


is returned, so instead of "?", "*" should be used to match with omit


2.
I have removed "from v_client" from everywhere,

Here's why:

tc_can_raw1 runs on MTC which starts the two PTCs with

f_raw_responder
and
f_raw_initiator

and these two functions will invoke the functions which open sockets etc.

but v_client is not initialized on the PTCs

However you don't need this information.




:

  var SocketCAN_comptype v_client
:
  // receive response
  alt {
    [] pt_socketCAN.receive(SocketCAN_ioctl_result:{ifr := ?, result := tr_result(SUCCESS)}) /*from v_client*/ -> value v_result

:


3. I have changed termination to depend on termination of the PTCs , not a timer:


testcase tc_can_raw1() runs on TimedComponent system SocketCAN_comptype
{
  var SocketCAN_comptype v_raw_responder_ref := SocketCAN_comptype.create("Raw_responder")
  
  var SocketCAN_comptype v_raw_initator_ref := SocketCAN_comptype.create("Raw_initator")
  
  //connect(v_raw_responder_ref:pt_time, mtc:pt_time)
  //connect(v_raw_initator_ref:pt_time, mtc:pt_time)
  
  map(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  map(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)
 
  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_send
  v_frame_to_send := {canfd_frame := 
                       {can_id := 21, 
                        can_flags := '00000000'B, 
                        can_pdu := '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'O}
                    }
  v_raw_responder_ref.start(f_raw_responder(v_raw_responder_ref, c_if_name, v_frame_to_send))
  v_raw_initator_ref.start(f_raw_initiator(v_raw_initator_ref, c_if_name, v_frame_to_send))
  

  /*
  // activate raw CAN FD frames:
  f_setsockopt(v_raw1_ref, v_socket1_id, {fd_frames := Enable})
  
  var SocketCAN_setsockopt_commandu v_command

  // send mesage of v_socket1_id
  f_send_data(v_raw1_ref, 
              v_socket1_id, 
              v_ifu1,
              v_frame_send2)

  // receive message over v_socket2_id
  v_receive_result := receive_data(v_raw2_ref, v_socket2_id)
  
  b := match(v_receive_result, {id := v_socket2_id, ifr := ?, frame := v_frame_send1, timestamp := ?})

  // deactivate raw CAN FD frames:
  f_setsockopt(v_raw1_ref, v_socket1_id, {fd_frames := Disable})
  */    
  
 // Tl_timer.start;
 // Tl_timer.timeout;

all component.done;


  unmap(v_raw_responder_ref:pt_socketCAN, system:pt_socketCAN)
  unmap(v_raw_initator_ref:pt_socketCAN, system:pt_socketCAN)

all component.kill;
}




Other issues:

> Should I use templates to check responses.
Yes , that's the way to do it.


> Can the "RAW Encoder and Decoder" used also in conjunction with ASN.1 code instead of TTCN code?

No , but ASN.1 has it's own binary codecs, derived from BER or PER .
BER is supported directly by Titan; in some cases there are solutions for PER too.
You need to verify which binary encoding you need. Likely it's BER, but this is a guess only.

>Are the TTCN data structures by the TTCN compiler converted the ASN.1 code as intermediate step?

It's in fact the opposite: Titan contains an ASN.1 compiler, so it can process ASN.1 structural definitions (to an extent). This means that TTCN-3 templates can be written directly against ASN.1 definitions.


I have created the repo for CAN bus test port:

http://git.eclipse.org/c/

Here's the workflow:

https://wiki.eclipse.org/Git#Your_Git_identify_at_eclipse.org

I believe for the moment simplest is that we commit on your behalf.


Best regards

Elemer









  • Attachment: CAN.tgz
    (Size: 7.36KB, Downloaded 300 times)
Re: TTCN Titan Testport for socketCAN [message #1741043 is a reply to message #1741034] Mon, 22 August 2016 14:05 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

regarding this:

Pixit:
- FD CAN support (yes / no) (by the hardware under test, the CAN-adapter and / or the LINUX kernel used.)
Pics:
- For RAW data (sending of CAN frames as broadcast to all CAN nodes listening):
the selected socket can interface e.g. "any", vcan0, "can0"
- For BCM (using the SocketCAN broadcast manager for all sorts of things like filtering received frames or cyclicly sending frames):
the selected socket can interface e.g. "any", vcan0, "can0"
- For ISO-TP (comming soon ..)
the selected socket can interface e.g. vcan0, "can0"
the source can_id, destination source can_id



I believe that these should be not module but test port parameters; they should not appear on TTCN-3 level at all, to keep the abstract test suite and the test port part separate
Pls. check with other ports how port parameters are being used used.
These are configurable from the config file e.g. :


[TESTPORT_PARAMETERS]
*.*.interface_name = "vcan0"
*.*.src_can_id="an id here"
*.*.dst_can_id="another id here" 



BR Elemer
Re: TTCN Titan Testport for socketCAN [message #1741085 is a reply to message #1741006] Mon, 22 August 2016 21:04 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Removed previous content as I did not see the message from Elmer (Mon, 22 August 2016 13:27 ) at the time of writing above for whatever reasons.

@Elemer:
The fix is working.

[Updated on: Fri, 02 September 2016 21:17]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1741103 is a reply to message #1741085] Tue, 23 August 2016 07:02 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


1.
template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {          
     result_code   := v_result_code,
     err           := ?
     err_text      := ?
}



has to be changed to


template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {          
     result_code   := v_result_code,
     err           := *,
     err_text      := *
}


as the result

{ id := 0, result := { result_code := SUCCESS (1), err := omit, err_text := omit } } 


will not match.

2. all "from v_client" have to be removed, for the reasons explained above


with these, tc_can_raw0 runs now to pass.

(see attached file)


And one more thing : typically test ports have a "debugging" parameter which restricts debug messages if set to "no"; in normal operation this level of details is not needed , in fact it makes reading more difficult.



Sorry I only come up with this now, but in the apiguide there's a chapter about writing test ports (ch 2), Logging is also explained in detail (see 2.6.1), but it may come handy in other areas as well.



Best regards
Elemer


Re: TTCN Titan Testport for socketCAN [message #1742528 is a reply to message #1741103] Fri, 02 September 2016 21:13 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

see my apologizes above. I did not see your message from Mon, 22 August 2016 13:27, when initially sending my previous post.
Also I had to retire my TTCN book from 2005 (first ed.) and to upgrade to 2011 (second ed. ). The book seemed quite outdated concerning handling of parallel test components. TTCN-3 seemed to have changed here.

Quote:
I have created the repo for CAN bus test port:
http://git.eclipse.org/c/
titan.TestPorts.SOCKET_CANasp.git CAN bus test port Elemer Lelik 10 days tm

It is called "SocketCAN" not "Socket_CAN". I think the name of the repository needs to be changed

The good thing of the SocketCAN Interface is, besides the Broadcast manager, that instances of the same CAN interface can be subscribed and all receive the same content.
Thus if a CAN frame is received via CAN, the same CAN frame is sent of all instances. If a frame is sent via the SocketCAN interface, the frame is send to the connected device as well as to all other subscribed instances.
Furthermore the SocketCAN has options to configure, whether a sent message is replicated to the sending interface as an incoming message as well and it provides also CAN frame filtering functionality, etc.

When writing test cases using parallel test components, I think this SocketCAN CAN frame "replication" functionality is quite useful.

Proprietary Windows CAN drivers however are usually quite stupid, they thus forward a CAN frames directly to the CAN bus. As WSL does currently not provide SocketCAN access, I am not sure whether proprietary Windows CAN drivers can be accessed from WSL / Cygwin. If this is the case, it might make sense to have a the same port interface SocketCAN_PT as with SocketCAN/Linux and emulate the SocketCAN functionality replicating the frames to all subscribed instances using a TTCN PTC.

There are some things I am not sure about:
- May WSL access to the installed Windows CAN drivers?
- The SocketCAN_PT interface needs to be declared either as internal (Windows driver case with SocketCAN emulation) or external (Linux with SocketCAN), while providing the same messages.
- Under such circumstances it might be useful to split the driver into a SocketCAN repository, a WSL repository providing SocketCAN emulation and a common SocketCAN repository.

Besides CAN_RAW and CAN_BCM, the SocketCAN provides also the ISOTP protocol in experimental stage. The ISOTP protocol is a simple segmentation / reassembly protocol on top of CAN frames (8Byte payload) or CAN FD frames (64 byte payload).
This protocol is used e.g. by car diagnostics or data upload for flashing a ECU to transfer bigger payloads. Other standards such as J1939 / ISO 11783 (Isobus) have similar segmentation / reassembly protocols on top of CAN data link layer.

There are multiple ways to implement such segmentation reassembly protocols:
- use the kernel module (e.g. ISOTP) ,if available (not available on WSL)
- to implement in TTCN and to provide e.g. an ISOTP port interface (TTCN internal) on top of it
- to implement it in C/C++ and provide e.g. an ISOTP port interface (TTCN external) on top of it

What is the best way to implement this?
I remember as a rule of thumb that all layers below the layer under test are not implemented in TTCN. The layer under test would be e.g. UDS (ISO14229) on top of the ISOTP (ISO 15765-2).

Quote:
I believe that these should be not module but test port parameters; they should not appear on TTCN-3 level at all, to keep the abstract test suite and the test port part separate

In CAN the layering is not so clean. It might be possible to have a cleaner Protocol specific layer on top of it, but not at the SocketCAN interface. (There are multiple completely different protocols concerning that behaviour.) I think the current CAN-ID and CAN-Interface parameters are just parameters for regression tests delivered with the CAN port testing CAN-BCM, CAN-RAW. As the upper layers are understood better, some intermediate layers/ports might be however introduced.
Here is the reason why:
- Even if working completely different, the lower layer of the CAN-Bus is a broadcast medium having similar characteristics as Ethernet.
- A CAN application might be interested in multiple CAN-IDs. There are e.g. some general Network Management broadcast IDs, the application might be interested besides. But, there are multiple completly different Network Management entities on top.
- Even the CAN-ID is interpreted differently concerning the application CAN-Basic, Can-Extended and PGNs.
- If using CAN as a so called Restbus simulation, then there may be multiple ECU devices simulated each having application dependent one or multiple CAN-IDs, connected via different CAN interfaces from the test system. E.g. CAN-GatewayECUs have multiple can busses. Thus may be even more than one physical SocketCAN device attached over multiple network interfaces.

Quote:
Pls. check with other ports how port parameters are being used used.

I have looked in very many of the test ports, but did not find any configuration files in the /src directory at all. Do you have any special ports in mind?

Best regards,
Michael

[Updated on: Wed, 28 September 2016 17:30]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1743272 is a reply to message #1742528] Tue, 13 September 2016 17:01 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

sorry for the slow response, I was away from the keyboard for a while as I will be for the rest of the week.


>It is called "SocketCAN" not "Socket_CAN".

That should be no problem to amend.

Let me come back to your questions beginning of the coming week; I need some time to go through the details.

Best regads
Elemer
Re: TTCN Titan Testport for socketCAN [message #1743676 is a reply to message #1743272] Sun, 18 September 2016 20:36 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

please see attached update of the code and the readme-file.

1. SocketCAN interface names
SocketCAN interface names may (and should) now be configured in the cfg-files.

2. Handling multiple Interfaces:
Not sure, if I got handling of the variables "debugging" and "can_interface_name" and the usage of the function reset_configuration() correct when using multiple instances.
See also SocketCAN.cfg

3. Separate TTCN-Ports for RAW, BCM and ISOTP:
While I had started with one TTCN-port representing the Socket-CAN interface, the more I look at it now, it should be 3 different Socket-CAN TTCN-Ports:


    - TTCN Port CAN-RAW (open(=RAW),ioctl(..), bind(..), setsockopt(..), send_data(..), close())
    - TTCN Port CAN-BCM(open(=BCM),ioctl(..), connect(..), write(..), close())
    - TTCN Port CAN-ISOTP(open(=ISOTP),ioctl(..), bind(..), setsockopt(..), send_data(..), close())

It would allow to get rid of lots of TTCN union records and on the C++ side getting rid of lots of if- and switch statements.

4. Issues with Titan:
Convertion here:
c_XXXX is a constant, e_XXXX is an enumeration, v_XXXX is a variable

4a) Usage of enumerations in Constants and Variable definitions:

  v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }

works, the following fails:
  v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) or4b 
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) or4b
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }


See "SocketCAN_BCM_test.ttcn".

4b)
This works:
  v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }


but if the opcode is initialized with an enumeration instead the integer number 3 the following fails:
  v_bcm_read_status_frame := {
    opcode := enum2int(e_CAN_BCM_TX_READ), // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }


see e_CAN_BCM_TX_READ in opcode in "SocketCAN_BCM_test.ttcn".

4c) Usage of enums in ranges

The following works:

const e_Phase c_testcase_complete := e_testcase_complete
(0 .. enum2int(c_testcase_complete)) 

but that fails:
(0 .. enum2int(e_testcase_complete))

see file: "SocketCANtest.ttcn" line 240

4d) Using negations in template ranges:
The following fails:
template integer a:= (1 .. !10)
template integer a:= (1 .. !v_value10)
template integer a:= (1 .. !e_enum10)


4e) Initialization of an enumeration variable with a specific enumeration value:
The following works:
  var  e_Phase          v_phase := c_firstPhase

, but this fails:
  var  e_Phase          v_phase := e_firstPhase


See "SocketCANtest.ttcn"".

4f) Matching received enumeration variables according to a specific enumeration value range:

where:
  var PhaseEndInd v_PhaseEndInd := {phase := v_phase, phase_int := enum2int(v_phase)}
  pt_sync.send(v_PhaseEndInd)

Due to Titan matching problems on the received side, besides the enumeration "phase", also its integer value needs to be transferred as "phase_int" as attributes.

The following works:
[] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}


, but this fails:
[] pt_sync.receive (PhaseEndInd: {phase :=  (p_phase .. c_testcase_complete), phase_int :=?}){}

and this fails also:
[] pt_sync.receive (PhaseEndInd: {phase :=  (p_phase .. e_testcase_complete), phase_int :=?}){}


4g) Defining Enumerations using binary or hexadecimal values instead of integer values:

The following works:
type enumerated BcmFlags_enum {
  e_CAN_BCM_SETTIMER            (1),
  e_CAN_BCM_RX_RTR_FRAME        (1024)
}

, but the following additions all fail:

type enumerated BcmFlags_enum {
  e_CAN_BCM_SETTIMER            (1),
  e_CAN_BCM_RX_RTR_FRAME        (1024),
  e_CAN_BCM_RX_RTR_FRAME_test1 ('0101'B),
  e_CAN_BCM_RX_RTR_FRAME_test2 (bit2int('0111'B)),
  e_CAN_BCM_RX_RTR_FRAME_test3 ('FFE'H),
  e_CAN_BCM_RX_RTR_FRAME_test4 (oct2int('FFF'H)),
  e_CAN_BCM_RX_RTR_FRAME_test5 ('FFFE'O),
  e_CAN_BCM_RX_RTR_FRAME_test6 (oct2int('FFFF'O))
}


See file "Bcm.ttcn".

Best regards,
Michael

[Updated on: Mon, 19 September 2016 05:00]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1743677 is a reply to message #1743676] Sun, 18 September 2016 20:54 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

Please update the installation instructions for Eclipse Titan on Eclipse Neon (or future releases.) on Linux / Windows. They seem to be outdated.
https://projects.eclipse.org/projects/tools.titan/downloads

Also the following link to to the user documentation is currently broken:
https://projects.eclipse.org/projects/tools.titan (search for "Eclipse Titan course material (recommended)")

Thanks a lot!

Best regards,
Michael
Re: TTCN Titan Testport for socketCAN [message #1743843 is a reply to message #1743677] Tue, 20 September 2016 08:39 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-broken link to user doc:

should be fixed by now

-4a to 4g : thank you, I will write TRs about these , should be fixed soonest


I'll come back about the rest

BR
Elemer

[Updated on: Tue, 20 September 2016 08:53]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1743844 is a reply to message #1743843] Tue, 20 September 2016 08:41 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I'm trying to compile on SuSe:



cat /etc/SuSE-release
SUSE Linux Enterprise Desktop 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1


and receive the following:



esekilxxen1846 [10:26] [titan.TestPorts.SocketCANasp_0920/titan.TestPorts.SocketCANasp/src] -> make                                               
/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/bin/compiler -L  \                                                                                       
        Bcm.ttcn Can.ttcn CanError.ttcn General_Types.ttcn Raw.ttcn SocketCAN_PortType.ttcn SocketCANtest.ttcn SocketCAN_Types.ttcn SocketCAN_RAW_test.ttcn SocketCAN_BCM_test.ttcn  - Bcm.ttcn Can.ttcn CanError.ttcn General_Types.ttcn Raw.ttcn SocketCAN_PortType.ttcn SocketCANtest.ttcn SocketCAN_Types.ttcn SocketCAN_RAW_test.ttcn SocketCAN_BCM_test.ttcn                                                                                    
Notify: Parsing TTCN-3 module `Bcm.ttcn'...                                                                                                       
Notify: Parsing TTCN-3 module `Can.ttcn'...                                                                                                       
Notify: Parsing TTCN-3 module `CanError.ttcn'...                                                                                                  
Notify: Parsing TTCN-3 module `General_Types.ttcn'...                                                                                             
Notify: Parsing TTCN-3 module `Raw.ttcn'...                                                                                                       
Notify: Parsing TTCN-3 module `SocketCAN_PortType.ttcn'...                                                                                        
Notify: Parsing TTCN-3 module `SocketCANtest.ttcn'...                                                                                             
Notify: Parsing TTCN-3 module `SocketCAN_Types.ttcn'...                                                                                           
Notify: Parsing TTCN-3 module `SocketCAN_RAW_test.ttcn'...                                                                                        
Notify: Parsing TTCN-3 module `SocketCAN_BCM_test.ttcn'...                                                                                        
Notify: Checking modules...                                                                                                                       
Notify: Generating code...                                                                                                                        
Notify: File `Bcm.hh' was generated.                                                                                                              
Notify: File `Bcm.cc' was generated.                                                                                                              
Notify: File `Can.hh' was generated.                                                                                                              
Notify: File `Can.cc' was generated.                                                                                                              
Notify: File `CanError.hh' was generated.                                                                                                         
Notify: File `CanError.cc' was generated.                                                                                                         
Notify: File `General_Types.hh' was generated.                                                                                                    
Notify: File `General_Types.cc' was generated.                                                                                                    
Notify: File `Raw.hh' was generated.                                                                                                              
Notify: File `Raw.cc' was generated.                                                                                                              
Notify: File `SocketCAN_BCM_test.hh' was generated.                                                                                               
Notify: File `SocketCAN_BCM_test.cc' was generated.                                                                                               
Notify: File `SocketCAN_PortType.hh' was generated.                                                                                               
Notify: File `SocketCAN_PortType.cc' was generated.                                                                                               
Notify: File `SocketCAN_RAW_test.hh' was generated.                                                                                               
Notify: File `SocketCAN_RAW_test.cc' was generated.                                                                                               
Notify: File `SocketCAN_Types.hh' was generated.                                                                                                  
Notify: File `SocketCAN_Types.cc' was generated.                                                                                                  
Notify: File `SocketCANtest.hh' was generated.                                                                                                    
Notify: File `SocketCANtest.cc' was generated.                                                                                                    
Notify: 20 files were updated.                                                                                                                    
touch compile                                                                                                                                     
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o Bcm.o Bcm.cc                                                       
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o Can.o Can.cc                                                       
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o CanError.o CanError.cc                                             
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o General_Types.o General_Types.cc                                   
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o Raw.o Raw.cc                                                       
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCAN_PortType.o SocketCAN_PortType.cc                         
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCANtest.o SocketCANtest.cc                                   
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCAN_Types.o SocketCAN_Types.cc                               
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCAN_RAW_test.o SocketCAN_RAW_test.cc                         
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCAN_BCM_test.o SocketCAN_BCM_test.cc                         
g++  -c -DLINUX -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -W -Wall -o SocketCAN_PT.o SocketCAN_PT.cc
SocketCAN_PT.cc: In member function 'virtual void SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)':
SocketCAN_PT.cc:134: error: aggregate 'canfd_frame frame' has incomplete type and cannot be defined
SocketCAN_PT.cc:135: error: 'CANFD_MTU' was not declared in this scope
SocketCAN_PT.cc:151: error: 'CAN_MTU' was not declared in this scope
SocketCAN_PT.cc:199: warning: cannot pass objects of non-POD type 'const class INTEGER' through '...'; call will abort at runtime
SocketCAN_PT.cc:211: warning: cannot pass objects of non-POD type 'const class INTEGER' through '...'; call will abort at runtime
SocketCAN_PT.cc:227: error: field 'frame' has incomplete type
SocketCAN_PT.cc:307: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:308: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:309: error: 'CAN_MAX_DLEN' was not declared in this scope
SocketCAN_PT.cc:312: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc: In member function 'void SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)':
SocketCAN_PT.cc:973: error: 'CAN_MAX_DLEN' was not declared in this scope
SocketCAN_PT.cc:1048: error: field 'frame' has incomplete type
SocketCAN_PT.cc:1099: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:1100: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:1102: error: 'CANFD_MAX_DLEN' was not declared in this scope
SocketCAN_PT.cc:1110: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:1112: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)::<anonymous>' has no member named 'frame'
SocketCAN_PT.cc:1120: error: invalid application of 'sizeof' to incomplete type 'canfd_frame'
make: *** [SocketCAN_PT.o] Error 1



What do you think?

BR Elemer



[Updated on: Tue, 20 September 2016 10:44]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1743876 is a reply to message #1743844] Tue, 20 September 2016 10:43 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

>- May WSL access to the installed Windows CAN drivers?

I would not think so; I believe at the moment WSL should be regarded as a curiosity only and not as a serious development platform;
even if used during development, the results should be validated against one or more established Linux platforms.
So WSL should not be relied upon and should not influence SocketCAN or any other port implementation.
This if course may change in the future depending on the direction WSL takes.

If for some reason SocketCAN Windows drivers have to be reused, maybe this can be done with a server engaging these drivers, server which can be connected remotely (say via TCP)
by the client application.




There are multiple ways to implement such segmentation reassembly protocols:
>
- use the kernel module (e.g. ISOTP) ,if available (not available on WSL)
- to implement in TTCN and to provide e.g. an ISOTP port interface (TTCN internal) on top of it
- to implement it in C/C++ and provide e.g. an ISOTP port interface (TTCN external) on top of it

What is the best way to implement this?


Simplest seems to be using kernel module ;

In general unnecessary proliferation of test ports should not be encouraged, that is one should not write a SocketCAN test port and an ISOTP test port with only small differences in the code; if possible , a configuration option
should chose one functionality or the other.


Best regards
Elemer

Re: TTCN Titan Testport for socketCAN [message #1743935 is a reply to message #1743844] Tue, 20 September 2016 18:44 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

again it is the problem of the not documented versioning of the SocketCAN interface "can.h", "raw.h" and "bcm.h".
For your information I have attached my versions of thise files. It would be helpfull to see yours.

My version of can.h defined the data structures of canfd_frame and can_frame. But CAN FD does not seem to be in mine version supported yet. Still my kernel uses CAN-FD data frames to transport between kernel and userspace for BCM as CAN-FD is a "superset" of CAN. CANFD calls the length parameter "len", while CAN calls it "can_dlc" (data length code) and CANFD provides an additional flags parameters, not available in CAN. CANFD has 64 bytes of payload, while CAN only 8 bytes.

Your kernel does currently not know about the CANFD frames and thus uses CAN frames for data transfer internally between kernel and userspace API.

Here is an updated Version of the file "SocketCAN_PT.cc". with some more #ifdef directives. Hope this version works now.

In the following a pieces of the BCM section of
https://www.kernel.org/doc/Documentation/networking/can.txt is provided:

    struct bcm_msg_head {
            __u32 opcode;                   /* command */
            __u32 flags;                    /* special flags */
            __u32 count;                    /* run 'count' times with ival1 */
            struct timeval ival1, ival2;    /* count and subsequent interval */
            canid_t can_id;                 /* unique can_id for task */
            __u32 nframes;                  /* number of can_frames following */
            struct can_frame frames[0];
    };

See frames size of [0]. Maybe in you kernel the size is different than 0.

CAN BCM frames:
    struct {
            struct bcm_msg_head msg_head;
            struct can_frame frame[N];
    } msg;


CAN BCM fd frames:
    struct {
            struct bcm_msg_head msg_head;
            struct canfd_frame frame[N]
    } msg;


where N maybe up to e.g. 256 and is dependent on the number of frames to be sent.

Best regards,
Michael
  • Attachment: can.h
    (Size: 7.53KB, Downloaded 357 times)
  • Attachment: bcm.h
    (Size: 3.90KB, Downloaded 266 times)
  • Attachment: SocketCAN_PT.cc
    (Size: 54.49KB, Downloaded 297 times)
  • Attachment: raw.h
    (Size: 2.71KB, Downloaded 269 times)
Re: TTCN Titan Testport for socketCAN [message #1744077 is a reply to message #1743935] Thu, 22 September 2016 08:46 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

>Please update the installation instructions for Eclipse Titan on Eclipse Neon (or future releases.) on Linux / Windows. They seem to be outdated.

The documents here are updated only when a new version is released and new binaries are published; we are trying to keep the documents in sync with the code;
the freshest docs can be found in github.



Your code builds and executes flawlessly on Ubuntu 16,.04 which was probably your platform used for development.

On Ubuntu 14.04 the following error is thrown:
make
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o Bcm.o Bcm.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o Can.o Can.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o CanError.o CanError.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o General_Types.o General_Types.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o Raw.o Raw.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_BCM_test.o SocketCAN_BCM_test.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_PortType.o SocketCAN_PortType.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_RAW_test.o SocketCAN_RAW_test.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_Types.o SocketCAN_Types.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCANtest.o SocketCANtest.cc
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_PT.o ../src/SocketCAN_PT.cc
../src/SocketCAN_PT.cc: In member function 'virtual void SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)':
../src/SocketCAN_PT.cc:199:34: error: cannot pass objects of non-trivially-copyable type 'const class INTEGER' through '...'
         ifr.ifr_name, nbytes, len);
                                  ^
../src/SocketCAN_PT.cc:211:34: error: cannot pass objects of non-trivially-copyable type 'const class INTEGER' through '...'
         ifr.ifr_name, nbytes, len);
                                  ^
make: *** [SocketCAN_PT.o] Error 1



both for the old and new SocketCAN_PT.cc

on Suse with the new SocketCAN_PT.cc the following happens:

make                      
Creating dependency file for SocketCANtest.cc                                                                            
Creating dependency file for SocketCAN_Types.cc                                                                          
Creating dependency file for SocketCAN_RAW_test.cc                                                                       
Creating dependency file for SocketCAN_PortType.cc                                                                       
Creating dependency file for SocketCAN_BCM_test.cc                                                                       
Creating dependency file for Raw.cc                                                                                      
Creating dependency file for General_Types.cc                                                                            
Creating dependency file for CanError.cc                                                                                 
Creating dependency file for Can.cc
Creating dependency file for Bcm.cc
Creating dependency file for ../src/SocketCAN_PT.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o Bcm.o Bcm.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o Can.o Can.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o CanError.o CanError.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o General_Types.o General_Types.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o Raw.o Raw.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCAN_BCM_test.o SocketCAN_BCM_test.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCAN_PortType.o SocketCAN_PortType.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCAN_RAW_test.o SocketCAN_RAW_test.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCAN_Types.o SocketCAN_Types.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCANtest.o SocketCANtest.cc
g++ -c -DLINUX -I. -I/proj/TTCN/Releases/TTCNv3_daily_LMWP3.1/include -I. -I../src -Wall -O2  -o SocketCAN_PT.o ../src/SocketCAN_PT.cc
../src/SocketCAN_PT.cc: In member function 'virtual void SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)':
../src/SocketCAN_PT.cc:161: error: 'CANFD_MTU' was not declared in this scope
../src/SocketCAN_PT.cc:196: error: 'struct can_frame' has no member named 'len'
../src/SocketCAN_PT.cc:235: warning: cannot pass objects of non-POD type 'const class INTEGER' through '...'; call will abort at runtime
../src/SocketCAN_PT.cc:247: warning: cannot pass objects of non-POD type 'const class INTEGER' through '...'; call will abort at runtime
../src/SocketCAN_PT.cc:250: error: 'struct can_frame' has no member named 'flags'
../src/SocketCAN_PT.cc:263: error: field 'frame' has incomplete type
../src/SocketCAN_PT.cc:347: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
../src/SocketCAN_PT.cc:348: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
../src/SocketCAN_PT.cc:348: error: 'CAN_MAX_DLEN' was not declared in this scope
../src/SocketCAN_PT.cc:351: error: 'struct SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)::<anonymous>' has no member named 'frame'
../src/SocketCAN_PT.cc: In member function 'void SocketCAN__PortType::SocketCAN__PT_PROVIDER::outgoing_send(const SocketCAN__Types::SocketCAN__write__data&)':
../src/SocketCAN_PT.cc:1014: error: 'CAN_MAX_DLEN' was not declared in this scope
make: *** [SocketCAN_PT.o] Error 1





I have attached, raw.h, can.h , bcm.h from SuSe.

Obviously they are different from yours although difference is not marked with any kind of versioning information.

My guess is that content differs from the kernel version to kernel version.

This is a problem as it's difficult to produce a code that compiles on several platforms.

One solution would be to restrict the number of usable platforms stating that e.g. this code will work on Ubuntu 16.04 only; but this decreases usability.



Best regards
Elemer











  • Attachment: bcm.h
    (Size: 3.90KB, Downloaded 325 times)
  • Attachment: can.h
    (Size: 7.53KB, Downloaded 467 times)
  • Attachment: raw.h
    (Size: 2.71KB, Downloaded 298 times)
Re: TTCN Titan Testport for socketCAN [message #1744150 is a reply to message #1744077] Thu, 22 September 2016 18:16 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

thanks for the feedback. I tried to compile now all flag combinations. So hopefully no compile errors more. I think the versions of the files you uploaded belong to Ubuntu 16.04 (which I am using), not to the Suse version you compiled. They do not match to your errors and are identical to my files.

> This is a problem as it's difficult to produce a code that compiles on several platforms.
There was a bug in my changes causing the new trouble in Ubuntu 14.04. Currently there are only 2 flag combinations.

Please find attached a new version.

Best regards,
Michael

[Updated on: Thu, 22 September 2016 20:39]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744188 is a reply to message #1744150] Fri, 23 September 2016 09:42 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi MIchael,

sorry, you are right, I managed to confuse myself with the header files. Sad

The ones attached should belong to SuSe 11 now.


Good news is now your code coded compiles on SuSe ( I could not run it as I don't have the rights to config interfaces on this server). In the afternoon I'll try with Ubuntu 14.04 as well.


If I have your permission I would commit the code to git on Monday.
I would also assign some version to it , maybe structure it to align with the rest of the ports..

If any further changes to the code I believe simplest is that you send me the new version and I'll commit it.
However you are welcome to register , sign the CLA etc. and access the repo yourself.


Thank you for your efforts and best regards
Elemer

  • Attachment: bcm.h
    (Size: 2.01KB, Downloaded 284 times)
  • Attachment: can.h
    (Size: 3.25KB, Downloaded 528 times)
  • Attachment: raw.h
    (Size: 0.29KB, Downloaded 317 times)
Re: TTCN Titan Testport for socketCAN [message #1744322 is a reply to message #1744188] Sun, 25 September 2016 10:08 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

feel free to do so.

There are multiple port interfaces "vcan0", "vcan1" assigned to system in the configuration file. Could you please explain how to access them from the PTCs?
I am referring here to your examples from 22. August.

I could not find any suitable examples.

Assumed I have defined the CAN-Interfaces in the configuration file as following:
"
system.pt_socketCAN_VCAN_IFA.SocketCAN_can_interface_name := "vcan0"
system.pt_socketCAN_VCAN_IFA.SocketCAN_debugging := "YES"
system.pt_socketCAN_VCAN_IFB.SocketCAN_can_interface_name := "vcan1"
system.pt_socketCAN_VCAN_IFB.SocketCAN_debugging := "YES"


Do I have then to define the function f_open_socket(...) in "SocketCANtest.ttcn" once for each interface (as f_open_socket_ifA(...) and f_open_socket_ifB (...))? I was not able to provide the port as a function parameter.

Best regards,
Michael

[Updated on: Sun, 25 September 2016 22:28]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744357 is a reply to message #1744322] Mon, 26 September 2016 09:57 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

two things:

1) I mentioned that in Ubu 14.04 an error is thrown:


make 
g++  -c -DLINUX -I. -I/home/james00/Titan_5.5.0_gcc4.8_ubuntu14.04_64//include -I. -I../src -Wall -O2  -o SocketCAN_PT.o ../src/SocketCAN_PT.cc
../src/SocketCAN_PT.cc: In member function 'virtual void SocketCAN__PortType::SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int)':
../src/SocketCAN_PT.cc:243:34: error: cannot pass objects of non-trivially-copyable type 'const class INTEGER' through '...'
         ifr.ifr_name, nbytes, len);
                                  ^
../src/SocketCAN_PT.cc:255:34: error: cannot pass objects of non-trivially-copyable type 'const class INTEGER' through '...'
         ifr.ifr_name, nbytes, len);
                                  ^
make: *** [SocketCAN_PT.o] Error 1




I suggest changing

log("Received a CAN frame from interface %s of %d bytes and with payload length %d",
						ifr.ifr_name, nbytes, len);


to


log("Received a CAN frame from interface %s of %d bytes and with payload length %d",
ifr.ifr_name, nbytes, len.get_long_long_val());



or
log("Received a CAN frame from interface %s of %d bytes and with payload length %d",
ifr.ifr_name, nbytes, (int)len);



len is of type INTEGER, but log expects a c++ inetger ; apparently not all compilers can do the conversion unassisted.


2) I'm not sure I understand exactly what your question refers to,

but instead of system, a component name or id can be used, or even a "*" as wildcard:


*.pt_socketCAN_VCAN_IFA.SocketCAN_can_interface_name := "vcan0"
*.pt_socketCAN_VCAN_IFA.SocketCAN_debugging := "YES"
*.pt_socketCAN_VCAN_IFB.SocketCAN_can_interface_name := "vcan1"
*.pt_socketCAN_VCAN_IFB.SocketCAN_debugging := "YES"


means that every port with name "pt_socketCAN_VCAN_IFA" in every component (hence the PTCs as well) will have the interface name set to "vcan0"


component ids may change, so this is the simplest solution and I don't remember using anything more complicated than this.






Best regards
Elemer



Re: TTCN Titan Testport for socketCAN [message #1744471 is a reply to message #1744357] Tue, 27 September 2016 10:46 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I have committed the test port to

http://git.eclipse.org/c/
titan.TestPorts.SocketCANasp.git


you can clone anonymously with:

git clone http://git.eclipse.org/gitroot/titan/titan.TestPorts.SocketCANasp


or
git clone git://git.eclipse.org/gitroot/titan/titan.TestPorts.SocketCANasp


I have also added a revision R1A to track changes.

Best regards
Elemer





Re: TTCN Titan Testport for socketCAN [message #1744593 is a reply to message #1744471] Wed, 28 September 2016 17:12 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

thank you.

There is one further issue with TTCN templates and matching.

As said before the interpretation of the CAN-ID is very much dependent on the upper layer protocol used. There are multiple of those and they may even be used in combinations.

Thus the problem is that the 4 byte CAN-ID of type INTEGER or OCTETSTRING is e.g. an Error code and Extended CAN-ID carrying a 29-bBit number or a basic CAN-ID carrying an 11-bit number and some flags.

As it is not a bitstring a match operator fails.
Example:
template bitstring a_CAN_EFF_FLAG   := '1???????????????????????????????'B length (32) // EFF/SFF is set in the MSB
template bitstring a_CAN_SFF_FLAG   := '0???????????????????????????????'B length (32) // EFF/SFF is set in the MSB

function f_test1() runs on PTC { 
  const SocketCAN_CAN_or_CAN_FD_frame a := {
    can_frame := {
      can_id        := 123,
      can_pdu       := '123456'O
    }
  }
  var boolean b
  b := match (a, a_SocketCAN_CAN_frame(bit2int(a_CAN_EFF_FLAG), ?))
}

template SocketCAN_CAN_or_CAN_FD_frame a_SocketCAN_CAN_frame(
  template CAN_id p_can_id, 
  template CAN_PDU p_can_pdu) := { 
  can_frame := {
    can_id := p_can_id, 
    can_pdu := p_can_pdu
  }
}


which results when copied into e.g. file SocketCAN_RAW_test.ttcn in this error:
SocketCAN_RAW_test.ttcn: In TTCN-3 module `SocketCAN_RAW_test':
 SocketCAN_RAW_test.ttcn:59.1-68.1: In function definition `f_test1':
  SocketCAN_RAW_test.ttcn:67.3-77: In variable assignment:
   SocketCAN_RAW_test.ttcn:67.49-76: In actual parameter list of template `@SocketCAN_RAW_test.a_SocketCAN_CAN_or_CAN_FD_frame':
    SocketCAN_RAW_test.ttcn:67.50-72: In parameter #1 for `p_can_id':
     SocketCAN_RAW_test.ttcn:67.50-72: In the operand of operation `bit2int()':
      SocketCAN_RAW_test.ttcn:67.58-71: error: Reference to a value was expected instead of template `@Can.a_CAN_EFF_FLAG'
Notify: Error found in the input modules. Code will not be generated.


I understand this error, however is there a way to use bit matches on integer or octet string values. I my eye it does not make any sense to make a can-id a bitstring by default to enable matching, as it is usually always seen as an octetstring and I do not want to see can-ids as bitsting in log files.

Best regards,
Michael

See also:
https://chemnitzer.linux-tage.de/2012/vortraege/folien/1044_SocketCAN.pdf
Slides 5 and slide 10.

[Updated on: Wed, 28 September 2016 17:29]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744639 is a reply to message #1744593] Thu, 29 September 2016 08:08 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

such a type conversion will not work over templates with unspecified parts, however it will work over the values to be matched:
 b := match (int2bit(a.can_frame.can_id,32), a_CAN_EFF_FLAG)  and match(oct2bit(a.can_frame.can_pdu), ?)


is equivalent in intention with your code in verifying the MSB ;

however the second part is always a match , so it can be simplified to:
b := match (int2bit(a.can_frame.can_id,32), a_CAN_EFF_FLAG);



I hope this helps

Best regards

Elemer




[Updated on: Thu, 29 September 2016 09:01]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744714 is a reply to message #1744639] Thu, 29 September 2016 15:48 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

this solution does not work with receive statements, where I need it:

var SocketCAN_receive_CAN_or_CAN_FD_frame v_result

 
template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_or_CAN_FD_frame(
  template SocketCAN_socketid p_socketid, 
  template SocketCAN_CAN_or_CAN_FD_frame p_frame) := { 
  // recieved CAN or CAN FD frame
  id        := p_socketid,
  ifr       := ?,
  frame     := p_frame, 
  timestamp := ?
}

function f_receive_data(template SocketCAN_socketid p_socket_id, template SocketCAN_CAN_or_CAN_FD_frame p_frame_expected)
runs on PTC { 
  var SocketCAN_receive_CAN_or_CAN_FD_frame v_result

  timer t_guard
  t_guard.start(c_guard)

  // receive frame or timeout
  alt {

    [] pt_socketCAN.receive(a_SocketCAN_receive_CAN_or_CAN_FD_frame(p_socket_id, p_frame_expected)) -> value v_result
    {
      log("SocketCan:Expected frame received", v_result)
    }
    [] pt_socketCAN.receive(?) -> value v_result
    {
      log("SocketCan:Other CAN-Frame received, ignoring:", v_result)
      repeat}
    [] t_guard.timeout {
      log("timeout!")
      setverdict(fail)}
  }
}


where p_frame_expected is the received CAN-frame of type SocketCAN_CAN_or_CAN_FD_frame and I want to test for e.g. CAN_EFF_FLAG or additionally multiple concatenated 11-bit or 29-bit CAN values or error flags. The point is that I might be interested only in a set of CAN-values and ignore others relevant to other CAN nodes.

[Updated on: Fri, 30 September 2016 06:19]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744784 is a reply to message #1744714] Fri, 30 September 2016 08:42 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi MIchael,

I see your point;
here's my proposal:

templates for integer value ranges can be easily written; for your previous example the below templates

template integer t_CAN_EFF_FLAG := (2147483648..4294967295) 
template integer t_CAN_SFF_FLAG := (0..2147483647) 


will test if the MSB is set or not:
 b := match (a, a_SocketCAN_CAN_frame(t_CAN_EFF_FLAG, ?))


for other can_id ranges similar templates can be written.

Could this be an option?


Best regards

Elemer



Re: TTCN Titan Testport for socketCAN [message #1744889 is a reply to message #1744784] Sat, 01 October 2016 17:14 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

I finally converted the CAN_id type from Integer to OCT4. Is there a sensible way to convert above integer based templates to octetstring such as:

template octetstring t_CAN_EFF_FLAG := ('80000000'O..'FFFFFFFF'O) 
template octetstring t_CAN_SFF_FLAG := ('00000000'O..'7FFFFFFF'O) 
or 
template octetstring t_CAN_EFF_FLAG := '(80..FF)???'O
template octetstring t_CAN_SFF_FLAG := '(00..7F)???'O


Both approaches failed.

[Updated on: Sat, 01 October 2016 17:16]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1744938 is a reply to message #1744889] Mon, 03 October 2016 07:38 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


there is a way:


template octetstring t_CAN_SFF_FLAG:=(
'00???'O,'01???'O,'02???'O,'03???'O,'04???'O,
'05???'O,'06???'O,'04???'O,'08???'O,'09???'O,
'10???'O,  and so on until
'7F???'O
);


You can specify your template as a list ; in this case this list will have to have 128 elements for each of both templates. So calling this sensible would be a push.

But we have to understand the root cause of the problem: what we are trying to do is to find some structure in something essentially unstructured.
Matching octetstrings or bitstrings (that is what's coming on the line undecoded) is unusual as one is losing all the advantages of using structured templates.
Typically test ports are sitting at the boundary of the structured and unstructured world ( well, the correct terminology is abstract and transfer syntax)
and converting between structured and line representation. Whenever this is possible. But we are past that, so I'm proposing the following workaround:

Later revisions of the standard introduced decmatch which permits decoding and matching in one fell swoop as in the example below:

type record MyBinaryMessage
 {
 octetstring payload
 }

 type record MyPayload
 {
 integer field1,
 integer field2
 }
template MyBinaryMessage mw_t1 :=
 {
 // The payload field can be matched only if it contains an encoded value of the MyPayload
 // type and if the field1 of the decoded value is equal to 1.
 payload := decmatch MyPayload:{field1 := 1, field2 := ? }
 } 



so we should try to use this concept:

module test2
{



const integer       CAN_MAX_DLEN   :=   8;
const integer       CANFD_MAX_DLEN :=  64;

type bitstring BIT1  length(1)  with { variant "" };
type bitstring BIT29 length(29) with { variant "" };

type octetstring       CAN_id length (4);      
type bitstring           CAN_flags length (8);  

type octetstring         CAN_PDU;

type record CAN_frame {
  CAN_id              can_id,                                // 32 bit CAN_ID + EFF/RTR/
  CAN_PDU             can_pdu length (0 .. CAN_MAX_DLEN)
};

type record CANFD_frame {
  CAN_id              can_id,                                // 32 bit CAN_ID + EFF/RTR/
  CAN_flags           can_flags,                             // only used with CAN FD  
  CAN_PDU             can_pdu   length (0 .. CANFD_MAX_DLEN)
};

type union SocketCAN_CAN_or_CAN_FD_frame {
  CAN_frame                        can_frame,
  CANFD_frame                      canfd_frame
};



/*
* Controller Area Network Identifier structure
*
* bit 0-28	: CAN identifier (11/29 bit)  0..536870911
* bit 29	: error frame flag (0 = data frame, 1 = error frame)
* bit 30	: remote transmission request flag (1 = rtr frame)
* bit 31	: frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/



type record  CAN_Id 
{
  BIT1  fff,
  BIT1  rtxf,
  BIT1  eff,
  BIT29 CAN_identifier //this could also be integer  in range  0..536870911 if more convenient
}




type record CAN_frame_s {
  CAN_Id              can_id,                                // 32 bit CAN_ID + EFF/RTR/
  CAN_PDU             can_pdu length (0 .. CAN_MAX_DLEN)
}with { variant " "};

type record CANFD_frame_s {
  CAN_Id              can_id,                                // 32 bit CAN_ID + EFF/RTR/
  CAN_flags           can_flags,                             // only used with CAN FD  
  CAN_PDU             can_pdu   length (0 .. CANFD_MAX_DLEN)
}with { variant " "};

type union SocketCAN_CAN_or_CAN_FD_frame_s {
  CAN_frame_s                        can_frame,
  CANFD_frame_s                      canfd_frame
}with { variant " "};


type record MessageType {
  octetstring payload
}




type port loopbackPort message { 
  inout MessageType
} with {extension "internal"}


type component GeneralComp {	    	    
  port loopbackPort messagePort
}	

testcase TC_001() runs on GeneralComp {

  var SocketCAN_CAN_or_CAN_FD_frame_s v_testMessage;
  var MessageType Message;

  v_testMessage:= { 
    can_frame := {
      can_id        := {fff:='1'B,rtxf:='0'B, eff:='0'B, CAN_identifier:= '00010001101000101011001111000'B},
      can_pdu       := '123456'O
    }
  } 

  Message.payload := bit2oct(encvalue(v_testMessage));		//encode message to payload

  template MessageType mw_matchingTemplate:= {  			
    payload :=  decmatch SocketCAN_CAN_or_CAN_FD_frame_s: { 
      can_frame := {
        can_id := {fff:='1'B, rtxf:=?, eff:=?, CAN_identifier:=? },
        can_pdu := ?
      }
    }
  } 

  connect(self:messagePort, self:messagePort);
  messagePort.send(Message);	//send message

  alt {
    [] messagePort.receive(mw_matchingTemplate) {
      setverdict(pass);
    }
    [] messagePort.receive {
      setverdict(fail);
    }
  }

}

control{
  execute(TC_001());
}



}with { encode "RAW"}





I have kept the initial set of type for SocketCAN_CAN_or_CAN_FD_frame,
but I have introduced a set of shadow ( or structured if you prefer) definitions for SocketCAN_CAN_or_CAN_FD_frame_s , in which can_id is not an opaque octetstring but a structured type. We can use this new set to decode the binary payload; to do this I have added RAW codec variants ( I did not check if these are 100 % correct; they are empty meaning that default is assumed; maybe some tweaking is needed) to the types and a final encode RAW instruction at the end of the module

With this , the payload can be decoded and matched to see if can_id contains the wanted structure.


Please be aware that support for decmatch , and its' counterpart @decoded is not yet present in the published binaries; you need to download the source code from github and build your own. Release is to be expected in November.


Maybe this offers some relief

Best regards
Elemer




[Updated on: Mon, 03 October 2016 09:08]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745067 is a reply to message #1744938] Tue, 04 October 2016 18:04 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
not sure what fff:='1'B,rtxf:='0'B refers to. I think they should be called:

type record  CAN_Id 
{
  BIT1  eff,
  BIT1  rtr,
  BIT1  err,
  BIT29 CAN_identifier //this could also be integer  in range  0..536870911 if more convenient
}


can.h:
#define CAN_EFF_FLAG 0x80000000U
/* extended frame format */
#define CAN_RTR_FLAG 0x40000000U
/* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error frame */


But to make it even worse, in US Truck Standard J1939 (and I also agriculture Isobus Standard) the 29 Bit CAN-ID is further split for:
- PDU1 type messages (peer to peer communications) into:
3 Bit Priority
1 Bit Reserved
1 Bit Data Page
8 Bit PDU Format (condition: must be < 240)
8 Bit PDU Specific = Destination address
8 Bit Source Address

while the following assembly of above is called 24-Bit Parameter Group Number (PGN):
6 Bit Zero = 0
1 Bit Reserved
1 Bit Data Page
8 Bit PDU Format (condition: must be < 240)
8 Bit := 0x00 (always zero)


- PDU2 type messages (broadcast communications) into:
3 Bit Priority
1 Bit Reserved
1 Bit Data Page
8 Bit PDU Format (condition: must be >=  240)
8 Bit PDU Specific = Group Extension
8 Bit Source Address


while the following assembly of above is called 24-Bit Parameter Group Number (PGN):
6 Bit Zero = 0
1 Bit Reserved
1 Bit Data Page
8 Bit PDU Format (condition: must be >=  240)
8 Bit PDU Specific = Group Extension


type record CAN_identifier {
BIT3 priority,
BIT1 reseved, 
BIT1 datapage, 
OCT1 pduformat,
OCT1 pdu_specific, // Group Extension for pduformat >= 240, destination address for pduformat < 240
OCT1 source_address
}

type OCT3 PGN // Assembeled from CAN_identifier

This is just an example for a crude interpretation of the 29-Bit CAN-IDs.

[Updated on: Sat, 08 October 2016 08:16]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745100 is a reply to message #1745067] Wed, 05 October 2016 08:08 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

if we want to accommodate several flavors of the protocol, than I believe the correct solution would be that a test port configuration parameter should switch between them.
I assume that within one test session the flavors are not mixed, and the right one can be determined unequivocally.

This means that say for a certain value of the config parameter, the test port will send to the upper layer the structure corresponding to flavor 1, for another value the structure corresponding to flavor 2 etc.

Test cases will have to be either written separately for different flavors or branched based on a similar parameter.

The above assumes that the test port code has to be modified accordingly.

What's you opinion?

Best regards

Elemer



Re: TTCN Titan Testport for socketCAN [message #1745150 is a reply to message #1745100] Wed, 05 October 2016 18:28 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

> I assume that within one test session the flavors are not mixed, and the right one can be determined unequivocally.
As the CAN-BUS is always an island, they are indeed mixed sometimes. UDS with IsoTP Protocol for Diagnostics is for example sometimes used in conjunction with ISOBUS and I heard of usecases of CANopen in conjunction with J1939.
I assume this is handled, by just subscribing for the interesting events and by ignoring the unknown. Thus when designing the CAN-BUS island, care need to be taken that no collisions of event occur.

What I do not know, is whether the same test case will have to handle both types. However, if I want to build for example a Gateways "router" from one CAN-Bus to another, as it occurs in cars, it might be necessary to handle both types within the same "test case". Perhaps it might be more sensible here to have running 2 independent routers, one for example for ISOBUS traffic and one for UDS/IsoTP traffic at the same time.

> The above assumes that the test port code has to be modified accordingly.
If there would be a TTCN-protocol-translation-component based solution I would at the moment, rather go this that. E.g. J1939/Isobus has build on top of PGNs and their CAN-Payload network management and some segmentation / reassembly to transfer payloads greater 8-Bytes. The network management provides node attach / detach and some node "keep-alive" while attached. There even had been some SocketCAN mailing list discussion on including the ISOBUS functionality as a kernel module, however it had been rejected in favor of using an userspace application, as with these CAN-solutions frequently only the subscribing application knows how to handle it. The sad thing is: if you have unstructured data and later-on try to structure it, you are often in trouble.

Lets go for the most flexible solution.

What do you think?

Best regards,
Michael

Please find attached 2 links to get an idea of ISOBUS applications:
http://can-newsletter.org/uploads/media/raw/f804fa73211fe307dc57570275ff0e4d.pdf
http://can-newsletter.org/uploads/media/raw/817cbc01babe3a121f8ab81a87fc91f7.pdf

[Updated on: Thu, 06 October 2016 17:50]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745169 is a reply to message #1745150] Wed, 05 October 2016 23:44 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Actually the CAN_identifier is never seen as a bitstring, however always seen as an octetsting OCT4hould be

type record  CAN_Id 
{
  BIT1  eff,
  BIT1  rtr,
  BIT1  err,
  OCT4 CAN_identifier   // contains 29- or 11-Bit CAN-ID
}


See as an example the second column from candump:

  vcan0  1CE6F726   [8]  A8 A1 73 00 91 3E 00 00
  vcan0  1CE726FD   [8]  A8 00 56 FF 18 00 00 00
  vcan0  1CE6FD26   [8]  A8 00 56 00 18 00 00 00
  vcan0  1CE726FD   [8]  A8 00 56 FF 11 00 00 00
  vcan0  1CE6FD26   [8]  A8 00 56 00 11 00 00 00
  vcan0  1CE726F8   [8]  FF 00 04 FF FF FF FF FF

Re: TTCN Titan Testport for socketCAN [message #1745308 is a reply to message #1745169] Fri, 07 October 2016 12:01 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


I agree,

in case several flavors will coexist, there's no better option for the test port but to pass it
as a piece of unstructured data to the upper layer and let it figure out.

I would not give any opinion regarding design choices in test cases; I'd suggest you proceed by trial-and-error.


Best regards
Elemer


Re: TTCN Titan Testport for socketCAN [message #1745381 is a reply to message #1745308] Sun, 09 October 2016 18:16 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

I started analyzing real traffic, which has EFF frames where the highest bit of uint32 is set. int2oct(can_id, 4) seems to treat these numbers as negative integer number, which it can not convert to an octet string. This results in a dynamic test case error "SocketCAN_PT.cc", e.g. line 250

const INTEGER can_id = frame.can_id;
:
:
frameref.can__id() = int2oct(can_id, 4);  


Note: There are some more places with the same int2oct(..) problems in "SocketCAN_PT.cc".

As a preliminary workaround this solves the issue, however it works only in absence of CAN ERROR and RTR frames and makes 11-bit CAN (SFF-CanIDs) indistinguishable from 29-Bit (EFF-CanIDs).
frameref.can__id() = int2oct(can_id & 0x1fffffff, 4);


Besides the currectly OCT4 CAN_id type should be changed to the more structured approach:

type bitstring BIT29 length(29)
type enumerated RTR { RTROccured } 
type union CAN_id {
  OCT4 can_eff, // 29-bit can address
  OCT2 can_sff, // 11-bit can address
  RTR  can_rtr, 
  BIT29 can_err  // up to 29 can error bits
}

[Updated on: Sun, 09 October 2016 18:36]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745394 is a reply to message #1745381] Mon, 10 October 2016 07:46 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-don't forget that instead of the built-in int2oct you can use your own integer-to-octetstring conversion say myownint2oct() with whatever logic you see fit
-I can see some disadvantages in using OCT4 to accomodate 29 or 11 bits; why not use a straight and honest bitstring ? I understand it's more difficult to read, but the user should only be confronted with the messages decoded into structures which are more readable anyhow
- You will probably use the RAW codec at some stage so maybe it's a good idea to create structures that are adapted to it;

for instance CROSSTAG permits an easy decision between union alternatives:

type union AnyPdu {
  PduType1 type1,
  PduType2 type2,
  PduType3 type3
}
  with { variant "" }

type record PduWithId {
  INT1    protocolId,
  AnyPdu  pdu
}
with {
   variant (pdu) "CROSSTAG( type1, { protocolId = 1,
                                     protocolId = 11 }; 
                            type2, protocolId = 2; 
                            type3, protocolId = 3)" 
}



so you can use the most significant bits(eff, sff etc.) to predict the content that follows.


Best regards

Elemer
Re: TTCN Titan Testport for socketCAN [message #1745453 is a reply to message #1745394] Tue, 11 October 2016 06:34 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
>-I can see some disadvantages in using OCT4 to accomodate 29 or 11 bits; why not use a straight and honest bitstring ? I understand it's more difficult to read, but the user should only be confronted with the messages decoded into structures which are more readable anyhow
I understand. But CAN is not build bottom up like ASN.1, but Top-Down. People are used to read these hex numbers and the encoding of the messages of the CAN-island is usually described in a "database". Each upper layer CAN-based standard (CAN-Network/dbc , UDS/ODX, ..) builds usually its own propitiatory Database Standard. Unless there will be written code generators from the database formats to ASN.1/TTCN there are no upper layer message encoder / decoder available. E.g. ODX is more than ASN.1, it e.g. contains translation texts and explanations in various spoken languages for vehicle diagnostic testers.

[Updated on: Tue, 11 October 2016 14:50]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745502 is a reply to message #1745453] Tue, 11 October 2016 17:24 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
>-don't forget that instead of the built-in int2oct you can use your own integer-to-octetstring conversion say myownint2oct() with whatever logic you see fit
Here is the error message:
Dynamic test case error: The first argument (value) of function int2oct() is a negative integer value: -1662572803.

int2oct is declared as friend in OCTETSTRING, as it accesses internal data structures of octetstring. My own function can not do that.

Addfunc.cc provides this function below. I do not see why can_id, which has been declared as unsigned int __u32 and is converted to INTEGER becomes a negative INTEGER number at all.

OCTETSTRING int2oct(const INTEGER& value, int length)
{
..
}
Re: TTCN Titan Testport for socketCAN [message #1745553 is a reply to message #1745502] Wed, 12 October 2016 12:41 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

INTEGER in Titan is a signed integer (it has an int constructor), so it's not a direct equivalent of uint32.

This piece of code:

  uint32_t myInt = UINT32_MAX; // For testing the max value of unisgned int32
  INTEGER myInteger;
  myInteger.set_long_long_val(myInt);
  OCTETSTRING myOctet = int2oct(myInteger, 4);


will convert correctly unsigned integers to OCTETSTRING using set_long_long_val().


I hope this helps.


Best regards

Elemer
Re: TTCN Titan Testport for socketCAN [message #1745688 is a reply to message #1745553] Fri, 14 October 2016 14:32 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Currently preparing Isobus decoding. It shares parts of its decoding with the Standards J1939 (and also NMEA)

1. Titan TTCN Crosstag implementation for J1939/Isobus:
Here Extended CAN identfier (EFF bis set), can be further decoded into:

type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional,
  INT2b prio,
  BIT1  res, 
  BIT1  dp,
  OCT1  pf,
  OCT1  ps,
  OCT1  sa
} 

type record CAN_frame_j1939 {
  J1939               can_j1939,
  CAN_PDU             can_pdu length (0 .. CAN_MAX_DLEN)
}


Now pf contains the a value. If pf is equal to 230, the can_pdu contains a further data structure to be interpreted as vt2ec message (message from VT to ECU) , with 231 as ecu2vt message (message from ECU to VT).
This would look like:

type union AnyIsoBusPdu {
  CAN_PDU vt2ecu length (0 .. CAN_MAX_DLEN),  // Message Virtual Terminal (VT) to ECU
  CAN_PDU ecu2vt length (0 .. CAN_MAX_DLEN)   // Message ECU to Virtual Terminal (VT)
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record Can_pduWithID {
  INT1          pf,
  AnyIsoBusPdu  can_pdu
}
with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu, cantype = 230; 
  ecu2vt, cantype = 231)" 
}

Is there a way to merge this as above pf and cn_pdu are different data structures?

2. The can_pdu contains in first place again a protocol discriminator and which is used to determine the message type and looks e.g. like the following:

type record WorkingSetMaintenanceReq
{
    Commandparam commandparam ('11111111'B),
    WorkingSetMaintenanceBitMask         bitMask,
    e_WorkingSetMaintenanceVersionNumber versionNumber,
    OCT1    reserved4  ('FF'O),
    OCT1    reserved5  ('FF'O),
    OCT1    reserved6  ('FF'O),
    OCT1    reserved7  ('FF'O),
    OCT1    reserved8  ('FF'O)
} with { encode "RAW" }

type record DummyVTStatusRes
{
    Commandparam commandparam ('11111110'B)
} with { encode "RAW" }

type union TopLevelMessage_VT2ECU_PDU
{
// put all VT2ECU request messages here
    VTStatusReq                    vtStatusReq,
// put all VT2ECU response messages here
    GetMemoryRes                   getMemoryRes,
    GetNumberOfSoftKeysRes         getNumberOfSoftKeysRes,
    GetTextFontDataRes             getTextFontDataRes,
    GetHardwareRes                 getHardwareRes,
    GetSupportedWidecharsRes       getSupportedWidecharsRes,
    GetWindowMaskDataRes           getWindowMaskDataRes,
    GetSupportedObjectsRes         getSupportedObjectsRes
}
with {variant "TAG	(
// put all VT2ECU request messages here
    vtStatusReq, 	commandparam = '11111110'B;
// put all VT2ECU response messages here
    getMemoryRes,                  commandparam = '11000010'B;
    getNumberOfSoftKeysRes,        commandparam = '11000000'B;
    getTextFontDataRes,            commandparam = '11000011'B;
    getHardwareRes,                commandparam = '11000111'B;
    getSupportedWidecharsRes,      commandparam = '11000001'B;
    getWindowMaskDataRes,          commandparam = '11000100'B;
    getSupportedObjectsRes,        commandparam = '11000101'B;) 
"; encode "RAW"} 

type union TopLevelMessage_ECU2VT_PDU
{
// put all ECU2VT request messages here
    GetMemoryReq                    getMemoryReq,
    GetNumberOfSoftKeysReq          getNumberOfSoftKeysReq,
    GetTextFontDataReq              getTextFontDataReq,
    GetHardwareReq                  getHardwareReq,
    GetSupportedWidecharsReq        getSupportedWidecharsReq,
    GetWindowMaskDataReq            getWindowMaskDataReq,
    GetSupportedObjectsReq          getSupportedObjectsReq,
    WorkingSetMaintenanceReq        workingSetMaintenanceReq
// put all ECU2VT response messages here
    //Dummy_ECU2VT_Res                dummy_ECU2VT_Res
}
with {variant "TAG	(
// put all ECU2VT request messages here
    getMemoryReq,                 commandparam = '11000010'B;
    getNumberOfSoftKeysReq,       commandparam = '11000000'B;
    getTextFontDataReq,           commandparam = '11000011'B;
    getHardwareReq,               commandparam = '11000111'B;
    getSupportedWidecharsReq,     commandparam = '11000001'B;
    getWindowMaskDataReq,         commandparam = '11000100'B;
    getSupportedObjectsReq,       commandparam = '11000101'B;
    workingSetMaintenanceReq,     commandparam = '11111111'B;
// put all ECU2VT response messages here
    //dummy_ECU2VT_Res, 	          commandparam = '00000000'B;
    ) "; encode "RAW"} 


3. Strange encoding of e.g. BIT1 as BIT32, OCT1 as OCT4 by Titan:

I am using the following encoding function:

function canid2j1939(in CAN_id p_can_id) return J1939 {
  var octetstring v_priority    // BIT3
  var octetstring v_reserved    // BIT1
  var octetstring v_datapage    // BIT1
  var octetstring v_pduformat   // OCT1
  var octetstring v_pduspecifc  // OCT1
  var octetstring v_sourceaddress  // OCT1
  var PGN  v_pgn
  var J1939 v_j1939

  v_priority   := bit2oct(oct2bit(p_can_id and4b ISOBUS_PRIORITY_MASK) >> 26)   // shift 26 bits
  v_reserved   := bit2oct(oct2bit(p_can_id and4b ISOBUS_RESERVED_MASK) >> 25)   // shift 25 bits
  v_datapage   := (p_can_id and4b ISOBUS_DATAPAGE_MASK) >> 3    // shift 24 bits = 3 octets
  v_pduformat  := (p_can_id and4b ISOBUS_PDUFORMAT_MASK) >> 2   // shift 16 bits = 2 octets
  v_pduspecifc := (p_can_id and4b ISOBUS_PDUSPECIFIC_MASK) >> 1 // shift  8 bits = 1 octet
  v_sourceaddress := (p_can_id and4b ISOBUS_SOURCEADDRESS_MASK)

  if (oct2int(v_pduformat) < 240) {
    v_pgn := oct2int(bit2oct(oct2bit(v_reserved) << 17) or4b (v_datapage << 2) or4b (v_pduformat << 1))
  } else  {
    v_pgn := oct2int(bit2oct(oct2bit(v_reserved) << 17) or4b (v_datapage << 2) or4b (v_pduformat << 1) or4b(v_pduspecifc))
  }
  v_j1939 := {pgn :=  v_pgn, prio := oct2int(v_priority), res := oct2bit(v_reserved), dp := oct2bit(v_datapage), pf := v_pduformat, ps := v_pduspecifc, sa := v_sourceaddress}
  return v_j1939
}


dp is e.g. declared as BIT1, however decoded as '00000000000000000000000000000000'B, similarly pf is of type OCT1, but decoded as OCT4 (pf := '000000E7'O). See below:

@michael-desktop: Message with id 1372 was extracted from the queue of pt_socketCAN.
3@michael-desktop: SocketCan:Expected frame received{ id := 0, ifr := { if_name := "vcan0", if_index := 3 }, frame := { can_frame := { can_id := '9CE726FD'O, can_pdu := 'A80056FF00000000'O } }, timestamp := { tv_sec := 1476455491, tv_usec := 288394 } }
3@michael-desktop: Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 59136, prio := 7, res := '00000000000000000000000000000000'B, dp := '00000000000000000000000000000000'B, pf := '000000E7'O, ps := '00000026'O, sa := '000000FD'O }, can_pdu := 'A80056FF00000000'O }
4@michael-desktop: Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 59136, prio := 7, res := '00000000000000000000000000000000'B, dp := '00000000000000000000000000000000'B, pf := '000000E7'O, ps := '00000026'O, sa := '000000FD'O }, can_pdu := 'A80056FF00000000'O } id 1369
4@michael-desktop: Matching on port pt_isobus succeeded:  matched
4@michael-desktop: Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 59136, prio := 7, res := '00000000000000000000000000000000'B, dp := '00000000000000000000000000000000'B, pf := '000000E7'O, ps := '00000026'O, sa := '000000FD'O }, can_pdu := 'A80056FF00000000'O } id 1369
4@michael-desktop: Message with id 1369 was extracted from the queue of pt_isobus.
4@michael-desktop: received: { can_j1939 := { pgn := 59136, prio := 7, res := '00000000000000000000000000000000'B, dp := '00000000000000000000000000000000'B, pf := '000000E7'O, ps := '00000026'O, sa := '000000FD'O }, can_pdu := 'A80056FF00000000'O }
3@michael-desktop: SocketCAN test port (pt_socketCAN): entering SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()
3@michael-desktop: SocketCAN test port (pt_socketCAN): Received a CAN frame from interface vcan0 of 16 bytes and with payload length 8
3@michael-desktop: Message enqueued on pt_socketCAN from system @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : { id := 0, ifr := { if_name := "vcan0", if_index := 3 }, frame := { can_frame := { can_id := '9CE6FD26'O, can_pdu := 'A800560000000000'O } }, timestamp := { tv_sec := 1476455491, tv_usec := 292359 } } id 1373
3@michael-desktop: SocketCAN test port (pt_socketCAN): leaving SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()
3@michael-desktop: Matching on port pt_socketCAN succeeded:  matched
3@michael-desktop: Receive operation on port pt_socketCAN succeeded, message from system(): @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : { id := 0, ifr := { if_name := "vcan0", if_index := 3 }, frame := { can_frame := { can_id := '9CE6FD26'O, can_pdu := 'A800560000000000'O } }, timestamp := { tv_sec := 1476455491, tv_usec := 292359 } } id 137


Did I miss some encoding options or is this a titan bug?

[Updated on: Fri, 14 October 2016 14:53]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745711 is a reply to message #1745688] Sat, 15 October 2016 10:50 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

1. ..Is there a way to merge this as above pf and cn_pdu are different data structures?

You can e.g. use the nested notation , as below:


type record CAN_frame_j1939 {
  record { // Error & RTR Frames are not considered here
  PGN   pgn optional,
  INT2b prio,
  BIT1  res, 
  BIT1  dp,
  OCT1  pf,
  OCT1  ps,
  OCT1  sa
}                can_j1939,
 union  {
  CAN_PDU vt2ecu length (0 .. CAN_MAX_DLEN),  // Message Virtual Terminal (VT) to ECU
  CAN_PDU ecu2vt length (0 .. CAN_MAX_DLEN)   // Message ECU to Virtual Terminal (VT)
  // other upper layer isobus protocols like Task Comtroller are added here ...
}             can_pdu 
}

with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu, can_j1939.pf = 'E6'O;  //230
  ecu2vt, can_j1939.pf = 'E7'O)" //231 
}



or something like:


type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional,
  Priority prio,
  BIT1  res, 
  BIT1  dp,
  OCT1  pf,
  OCT1  ps,
  OCT1  sa
} with { variant "" }

type union AnyIsoBusPdu {
  CAN_PDU vt2ecu length (0 .. CAN_MAX_DLEN),  // Message Virtual Terminal (VT) to ECU
  CAN_PDU ecu2vt length (0 .. CAN_MAX_DLEN)   // Message ECU to Virtual Terminal (VT)
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record CAN_frame_j1939 {
  J1939               can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu, can_j1939.pf = 'E6'O;  //230
  ecu2vt, can_j1939.pf = 'E7'O)" //231 
}


Whichever is more convenient

2. I 'm not sure if there is a question here, but you can continue decoding VT2ECU messages based on Commandparam in the same manner.

3. Can you please send me the full log , and preferably the whole code ( do a make archive, this will collect and zip all files that are relevant);

I should also see the file names/line numbers in the log , so pls. use the following:

LogSourceInfo := Yes
SourceInfoFormat:= Single


Best regards

Elemer

Re: TTCN Titan Testport for socketCAN [message #1745714 is a reply to message #1745711] Sat, 15 October 2016 19:12 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
To 1. & 2.)
It was unclear to me, how to trigger the encoding / decoding process. However it is solved now.

Finally I got one isobus message deocded. Note that the current Isobus decoder just decodes some of the messages, thus many messages will fail to decode.

 Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 58880, prio := 7, res := '00000000000000000000000000000000'B, dp := '00000000000000000000000000000000'B, pf := '000000E6'O, ps := '000000FF'O, sa := '00000026'O }, can_pdu := { vt2ecu := { vtStatusReq := { commandparam := '11111110'B, sourceAddressOfActiveWorkingSetMaster := 'F8'O, objectIDOfTheVisibleDataAlarmMaskOfTheActiveWorkingSet := 'E903'O, objectIDOfTheVisibleSoftKeyMaskOfTheActiveWorkingSet := 'A10F'O, vtBusyCodes := vtIsBusyUpdatingVisibleMask (0), vtFunctionCode := 'FF'O } } } } id 1
4@michael-desktop: Message with id 1 was extracted from the queue of pt_isobus.


However after adding further parameters:

type OCT8 NAME 
type OCT3 RequestForAddressClaimed
type NAME AddressClaimed
type record CommandedAddress {
  NAME          name,
  SourceAddress newSourceAddress
}


type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional,
  Priority       prio,
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa
} with { variant "" }

type union AnyIsoBusPdu {
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)
  RequestForAddressClaimed requestForAddressClaimed,
  AddressClaimed addressClaimed,
  CommandedAddress commandedAddress
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record CAN_frame_j1939 {
  J1939               can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.pf = 'E6'O;  //230
  ecu2vt,                   can_j1939.pf = 'E7'O;  //231
  requestForAddressClaimed, can_j1939.pf = 'EA'O;  //234
  addressClaimed,           can_j1939.pf = 'EE'O;  //238
  commandedAddress,         can_j1939.pf = 'FE'O)" //254
}


I get the following warning:

Isobus.ttcn: In TTCN-3 module `Isobus':
 Isobus.ttcn:25.1-77: In external function definition `encode_AnyIsoBusPdu':
  Isobus.ttcn:25.38-58: In formal parameter list:
   Isobus.ttcn:25.39-57: In parameter `pdu':
    Isobus.ttcn:63.1-70.1: In type definition `AnyIsoBusPdu':
     Isobus.ttcn:71.8-17: warning: This variant does not belong to an encode
 Isobus.ttcn:37.1-34: In type definition `INT24nb':
  Isobus.ttcn:37.43-52: warning: This variant does not belong to an encode
 Isobus.ttcn:53.1-61.1: In type definition `J1939':
  Isobus.ttcn:61.10-19: warning: This variant does not belong to an encode
 Isobus.ttcn:73.1-76.1: In type definition `CAN_frame_j1939':
  Isobus.ttcn:75.3-29: In record field `can_pdu':
   Isobus.ttcn:77.3-82.50: warning: This variant does not belong to an encode
Isobustest.ttcn: In TTCN-3 module `Isobustest':
 Isobustest.ttcn:39.1-44.1: In type definition `Can_IDs':
  Isobustest.ttcn:45.8-17: warning: This variant does not belong to an encode
 Isobustest.ttcn:47.1-50.1: In type definition `Can_IDwithType':
  Isobustest.ttcn:49.3-18: In record field `can_ids':
   Isobustest.ttcn:52.3-56.24: warning: This variant does not belong to an encode

[Updated on: Sun, 16 October 2016 15:36]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1745754 is a reply to message #1745714] Mon, 17 October 2016 08:23 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi MIchael,

there are earlier forum posts detailing the RAW codec:

https://www.eclipse.org/forums/index.php/t/1070954/
https://www.eclipse.org/forums/index.php/t/1071180/
https://www.eclipse.org/forums/index.php/t/1071394/



Basically you need three things to have in place:


-tag types with "variant " instructions (if empty , defaults will be assumed, which is likely incorrect)
-add a final "with {encoding RAW"}" instruction to the modules containing the types ( the warnings you mention are due to this one missing )
-declare a pair of external functions to be used at encoding decoding ( or use encvalue/decvalue which will connect automatically to the autogenerated codec)


It takes an amount of tweaking to have the encoding instructions in place; What I typically do when working with RAW is:

1)write an amount of templates and encode them
2) I decode the resulting binary samples

If the above two are OK , then at least the codec is internally consistent

3) Now I try to collect as many as possible real-world samples and try to decode them


The aim is to unfold the incoming binary into a structure as detailed as possible.

To continue the previous example,
you can replace

type union AnyIsoBusPdu {
  CAN_PDU vt2ecu length (0 .. CAN_MAX_DLEN),  // Message Virtual Terminal (VT) to ECU
  CAN_PDU ecu2vt length (0 .. CAN_MAX_DLEN)   // Message ECU to Virtual Terminal (VT)
  // other upper layer isobus protocols like Task Comtroller are added here ...
}



with

type union AnyIsoBusPdu {
  CAN_PDU vt2ecu length (0 .. CAN_MAX_DLEN),  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU    ecu2vt   // Message ECU to Virtual Terminal (VT)
  // other upper layer isobus protocols like Task Comtroller are added here ...
}


etc. so RAW will continue the analysis.





Best regards

Elemer


Re: TTCN Titan Testport for socketCAN [message #1745757 is a reply to message #1745754] Mon, 17 October 2016 08:59 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

OK, so you have now , according to the latest attachment,
1) types tagged with variants (it has to be checked if the correct ones-see test procedure above)
also, each type that is relevant better have a ""with variant' instruction, even if empty; it make things clearer for the reader
(If I remember correctly , Titan will apply defaults even if no instruction is present )


2) external function declared and used
3) you are missing the final "with {encoding RAW"}" at the end of Isobus.ttcn and Isobustest.ttcn (as you noticed, encoding works without this but it warns that misleading situations may appear)

So I believe you are on the right track now
Smile

BR Elemer


Re: TTCN Titan Testport for socketCAN [message #1746047 is a reply to message #1745757] Thu, 20 October 2016 19:11 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

With the "with {encoding RAW"}" at the end of Isobus.ttcn and Isobustest.ttcn the warnings disappear.

I think you meant:

  
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)


I had this already in my previous post.

Here the current code:
type OCT8 NAME 
type OCT3 RequestForAddressClaimed
type NAME CannotClaimSourceAddress
type NAME AddressClaimed

type record CommandedAddress {
  NAME          name,
  SourceAddress newSourceAddress
}


type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional,
  Priority       prio,
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa
} with { variant "" }

type union AnyIsoBusPdu {
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)
  RequestForAddressClaimed requestForAddressClaimed,
  AddressClaimed addressClaimed,
  CannotClaimSourceAddress cannotClaimSourceAddress,
  CommandedAddress commandedAddress
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record CAN_frame_j1939 {
  J1939               can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.pf = 'E6'O;  //230
  ecu2vt,                   can_j1939.pf = 'E7'O;  //231
  requestForAddressClaimed, can_j1939.pf = 'EA'O;  //234
  addressClaimed,           {can_j1939.pf = 'EE'O,can_j1939.ps = 'FF'O};  //238 all and conjuction needed!!!!!!
  cannotClaimSourceAddress, {can_j1939.pf = 'EE'O,can_j1939.ps = 'FF'O,can_j1939.sa = 'FE'O}; //238 all and conjuction needed!!!!!!
  commandedAddress,         {can_j1939.pf = 'FE'O,can_j1939.ps = 'D8'O})" //254 all and conjuction needed!!!!!!
}


The intended behaviour is as following:
If can_j1939.pf = 'E6'O, it is a vt2ecu message using further decoding with comparam as done in TopLevelMessage_VT2ECU_PDU,
If can_j1939.pf = 'E7'O; it is a ecu2vt message using further decoding with comparam as done in TopLevelMessage_ECU_PDU2VT,
If can_j1939.pf = 'EA'O; a requestForAddressClaimed as OCT3 is expected following
If can_j1939.pf = 'EE'O and can_j1939.ps = 'FF'O, then addressClaimed is expected to follow as NAME (=OCT8)
Etc.

Despite the fact that I miss the and conjunction between the conditions, when started it always matches even if e.g. pf is '26'O instead of 'EA'O.

3@michael-desktop: decode_AnyIsoBusPdu(): Stream before decoding: 'A800560000000000'O
3@michael-desktop: decode_AnyIsoBusPdu(): Decoded @Isobus.AnyIsoBusPdu: { requestForAddressClaimed := 'A80056'O }
3@michael-desktop: decode_AnyIsoBusPdu(): Warning: Data remained at the end of the stream after successful decoding: '0000000000'O
3@michael-desktop: Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := '26'O ("&"), ps := 'FD'O, sa := 'E6'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
4@michael-desktop: Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := '26'O ("&"), ps := 'FD'O, sa := 'E6'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } } id 770

Re: TTCN Titan Testport for socketCAN [message #1746078 is a reply to message #1746047] Fri, 21 October 2016 10:21 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

could you please attach the result of make archive, including the config file used when executing.

It appears that you are calling decode_AnyIsoBusPdu(); but you should try to decode a CAN_frame_j1939 structure, as can_j1939 contains the information to help choosing between variants;
so you should declare and call a function decode_CAN_frame_j1939.


As it is now ,


type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional, // no length info!!!!
  Priority       prio, // type INT2b Priority
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa  // type OCT1 SourceAddress
} with { variant "" }


cannot be decoded, as there is insufficient information.


type integer INT24nb (0..16777215) with { variant "" }

should contain length info (it is unclear on how many bits it will be encoded) and if you want to use optional, you need an extra piece of info to see if it is present or not.


Again I recommend you try a few encodings first to see if the result is what
you expect , and then try decoding.

Not every structure, even if encodable, can be properly decoded;
e.g.
type record Somerecord {
octetstring os1,
octestring os2
}


can be encoded, but decoding is impossible, as there is no info about boundaries between the octetstrings.

Simplest thing is to specify length :

  type octetstring OCT10 length(10) with { variant "FIELDLENGTH(10)" };

type record Somerecord {
OS10  os1,
OS10  os2
}



and simpler protocols are constructed based on length info.



BR Elemer






Re: TTCN Titan Testport for socketCAN [message #1746089 is a reply to message #1746078] Fri, 21 October 2016 13:22 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

to give you some pointers:


with the below additions


type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(28), COMP(nosign), BYTEORDER(last)" };
//I'm not sure this is correct but I assumed it has to be aligned to octet boundaries , so I made it 28 bits 


type record J1939 { // Error & RTR Frames are not considered here
  PGN   pgn optional,  //28 bits
  Priority       prio,  //2bits
  BIT1           res,   //1 bit
  BIT1           dp,   //1 bit 
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa
} with { variant "" }

external function encode_CAN_frame_j1939(in CAN_frame_j1939 pdu) return octetstring 
with { extension "prototype(convert) encode(RAW)" }
external function decode_CAN_frame_j1939(in octetstring data) return CAN_frame_j1939
with { extension "prototype(convert) decode(RAW)" }



this test case:
testcase tc_encdec() runs on MTC_CT

{

template CAN_frame_j1939 t_CAN_frame_j1939 :=  { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := '26'O /*E6'O*/, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
log(encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log(decode_CAN_frame_j1939(encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))

template CAN_frame_j1939 t_CAN_frame_j1939_2 :=  { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := 'EE'O , ps := 'FD'O, sa := 'E6'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
log(encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_2)))
log(decode_CAN_frame_j1939(encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_2))))

}


will be executed as below:

15:10:34.993192 '00226040EEFDE6A80056AAABBCC778'O
15:10:34.993416 { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := 'EE'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
15:10:34.993518 '00226040EAFDE6A80056'O
15:10:34.993551 { can_j1939 := { pgn := 140800, prio := 0, res := '1'B, dp := '0'B, pf := 'EA'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }



Please be aware that whatever value you enter for pf, the encoder will change it to the right value for the given choice.



BR Elemer

Re: TTCN Titan Testport for socketCAN [message #1746094 is a reply to message #1746089] Fri, 21 October 2016 14:38 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

Here a first feedback. I start to understand where the problem is.

The J1939-record is encoded into the CAN-ID which is used to send the CAN-frame, however it is not encoded into the 8 byte CAN pdu.
Thus when receiving the CAN-Frame the CAN-ID needs to be decoded into the J1939-format. Then depending on its fileds the RAW decoder on the can-PDU applied.

This is not what you are doing in the second post (encoder example). To save space, J1939 uses the can ID already as "protocol discriminator".

Michael

[Updated on: Fri, 21 October 2016 15:09]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746144 is a reply to message #1746094] Sun, 23 October 2016 18:18 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

you are right. It is the right way to go to start encoding first.

For J1939 like Isobus the TTCN-PDU is the CAN-ID appeneded with the CAN-PDU. This way the RAW encoder can be used.

The PGN is redundant information and not encoded. Thus I removed it. It is just another way to communicate verbally.I added it in the past, as it might be used for matching upon reception. But that is not important.

I corrected the priority is 3 bit and prepended it with 3 bits to be ignored. Thus the J1939 CAN-ID has 32 Bit. This works nicely.

There is a problem, that the RAW encoder applies an "or"-conjunction between the elements in the brackets separated by commas, however I need here an "and"-conjunction between the elements:
{can_j1939.pf = 'EE'O AND can_j1939.ps = 'FF'O AND can_j1939.sa = 'FE'O}

Is there a way to express that when using the RAW encoder?

Here is the encoder:
type OCT1 DestinationAddress
type OCT1 SourceAddress
//type BIT3 Priority 

type bitstring Priority length(3)
with {
variant "ALIGN(right)";
variant "FIELDLENGTH(6)"
}

type OCT8 NAME 
type OCT3 RequestForAddressClaimed
type NAME CannotClaimSourceAddress
type NAME AddressClaimed

type record CommandedAddress {
  NAME          name,
  SourceAddress newSourceAddress
}


type record J1939 { // Error & RTR Frames are not considered here
  //PGN   pgn optional,
  //BIT3           ignore,
  Priority       prio,
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa
} with { variant "" }

type union AnyIsoBusPdu {
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)
  RequestForAddressClaimed requestForAddressClaimed,
  CannotClaimSourceAddress cannotClaimSourceAddress,
  AddressClaimed addressClaimed,
  CommandedAddress commandedAddress
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record CAN_frame_j1939 {
  J1939               can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.pf = 'E6'O;  //230
  ecu2vt,                   can_j1939.pf = 'E7'O;  //231
  requestForAddressClaimed, can_j1939.pf = 'EA'O;  //234
  cannotClaimSourceAddress, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O, can_j1939.sa = 'FE'O}; //238 all and conjuction needed!!!!!!
  addressClaimed,           {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O};  //238 all and conjuction needed!!!!!!
  commandedAddress,         {can_j1939.pf = 'FE'O, can_j1939.ps = 'D8'O})" //254 all and conjuction needed!!!!!!
}


You see it failing in the first encoding where "addressClaimed := 'A80056AAABBCC778'O" is decoded to "cannotClaimSourceAddress := 'A80056AAABBCC778'O" as they both share can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O:
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: '00EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '00EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { cannotClaimSourceAddress := 'A80056AAABBCC778'O } }
MTC@michael-desktop: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { cannotClaimSourceAddress := 'A80056AAABBCC778'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EAFDC0A80056'O
MTC@michael-desktop: '00EAFDC0A80056'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EAFDC0A80056'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '00EAFDC0A80056'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
MTC@michael-desktop: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { requestForAddressClaimed := 'A80056'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := '1122334455667788'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EEFDC01122334455667788'O
MTC@michael-desktop: '00EEFDC01122334455667788'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := '1122334455667788'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EEFDC01122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '00EEFDC01122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := '1122334455667788'O } }
MTC@michael-desktop: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := '1122334455667788'O } }


See attachments:
ttcn3_start SocketCAN SocketCAN.cfg Isobustest.tc_encdec

[Updated on: Sun, 23 October 2016 18:22]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746145 is a reply to message #1746144] Sun, 23 October 2016 18:54 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Looks like the encoding of the bits prio := '000'B, res := '0'B, dp := '0'B is not working as expected.

The first byte should contain bit 7 - 5 to be padding (ignored), bit 4 - 2 as priority, bit 1 as res, bit 0 as dp.

MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '05EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: '05EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '05EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '05EEFDE6A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '001'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { cannotClaimSourceAddress := 'A80056AAABBCC778'O } }


More importantly the decoding of the prio is not working correctly. prio := '110'B decodes to prio := '001'B

[Updated on: Sun, 23 October 2016 19:12]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746224 is a reply to message #1746145] Tue, 25 October 2016 15:06 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


please attach the result of make archive including the cfg file used when executing.

CROSSTAG will not take "and" conjunctions as you described above;
instead you need to replace the double alternatives with a new union and analyze it in a new step in dependency of a new parameter.
Protocols are usually constructed in a way that header fields indicate the coming content; one discriminator should be sufficient to help deciding between message types.


I'm pretty sure this cannot be right:


cannotClaimSourceAddress, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O, can_j1939.sa = 'FE'O}; //238 all and conjuction needed!!!!!!
addressClaimed, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O}; //238 all and conjuction needed!!!!!!
commandedAddress, {can_j1939.pf = 'FE'O, can_j1939.ps = 'D8'O})" //254 all and conjuction needed!!!!!!

Where can I find the description of fields in J1939 header?

Best regards

Elemer


Re: TTCN Titan Testport for socketCAN [message #1746239 is a reply to message #1746224] Tue, 25 October 2016 20:10 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

the ISOBUS standard is defined in ISO 11783 e.g. ISO 11783-3 (Data Link Layer), ISO 11783-4 (Network Layer), ISO 11783-5 (Network Management), ISO 11783-6 (Virtual Terminal).

At the moment I am using the Book:
A Comprehensible Guide to J1939 Paperback June 18, 2008
by Wilfried Voss (Author)
ISBN-13: 978-0976511632

It contains J1939 which was the basis of ISO 11783-3 (Data Link Layer), ISO 11783-4 (Network Layer), ISO 11783-5 (Network Management). But there will be deviations for Isobus.
I do not have them at hand at the moment, but I have read them in the past.

> I'm pretty sure this cannot be right:
Above is taken from the book, which provides a good overview for the middle layers.
The CAN-Protocols are not as clean as the better structured Telecom Protocols. They stuff as much as possible into the 8-Byte CAN PDU and its CAN-ID due to timing and bandwidth constraints.

ISO 11783-6 (Virtual Terminal) "application protocol" is the basis for: IsobusMessageTypes.ttcn

>instead you need to replace the double alternatives with a new union and analyze it in a new step in dependency of a new parameter.
Ok. I will try that.

[Updated on: Tue, 25 October 2016 20:12]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746296 is a reply to message #1746239] Wed, 26 October 2016 14:53 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Interpretation (left to right vs. right to left) of Octetstrings and Bitstrings.

testcase tc_substr() runs on MTC_CT

{
var OCT4      v_oct4 := '98ECE526'O
var bitstring v_bitstring //:= '10011000111011001110010100100110'B
v_bitstring := oct2bit(v_oct4)
log("v_oct4: ", v_oct4)
log("v_bitstring: ", v_bitstring)
log("substr(v_bitstring, 26, 3): ", substr(v_bitstring, 26, 3))

log ("v_oct4[2]:", v_oct4[2])
log ("v_oct4[1]:", v_oct4[1])
log ("v_oct4[0]:", v_oct4[0])
}


Result:
MTC@michael-desktop: Test case tc_substr started.
MTC@michael-desktop: Initializing variables, timers and ports of component type Isobustest.MTC_CT inside testcase tc_substr.
MTC@michael-desktop: Component type Isobustest.MTC_CT was initialized.
MTC@michael-desktop: v_oct4: '98ECE526'O
MTC@michael-desktop: v_bitstring: '10011000111011001110010100100110'B
MTC@michael-desktop: substr(v_bitstring, 26, 3): '100'B
MTC@michael-desktop: v_oct4[2]:'E5'O
MTC@michael-desktop: v_oct4[1]:'EC'O
MTC@michael-desktop: v_oct4[0]:'98'O


I would have expected e.g. v_oct4[0] to be '26'O.
Re: TTCN Titan Testport for socketCAN [message #1746366 is a reply to message #1746296] Thu, 27 October 2016 14:18 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi , Michael,

well , both representations , starting from right or left, can be justified, but the standard specifies that indexing should start from left;

see for example page 45 of the core language standard:

EXAMPLE 1: Accessing an existing element
 // Given
 v_myBitString := '11110111'B;
 // Then doing
 v_myBitString[4] := '1'B;
 // Results in the bitstring '11111111'B 


and many other examples throughout the text of the standard.

But don't forget, this is the abstract representation so here the indexing order does not matter much.
What will become in the transfer representation (on the wire) is specified by the binary encoding, in our case the RAW codec.


Best regards

Elemer
Re: TTCN Titan Testport for socketCAN [message #1746373 is a reply to message #1746366] Thu, 27 October 2016 16:31 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


the reason I said

cannotClaimSourceAddress, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O, can_j1939.sa = 'FE'O}; //238 all and conjuction needed!!!!!!
addressClaimed, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O}; //238 all and conjuction needed!!!!!!
commandedAddress, {can_j1939.pf = 'FE'O, can_j1939.ps = 'D8'O})" //254 all and conjuction needed!!!!!!


can't be right is that the above is unclear:
-In which case the "addressClaimed" condition appears? When can_j1939.sa is different from 'FE'O?
-what happens when can_j1939.pf = 'EE'O but can_j1939.ps != 'FF'O?
-what happens when can_j1939.pf = 'FE'O but can_j1939.ps != 'D8'O?


Regarding the "and" conjunction: this has not been implemented as it was not needed so far;

only one level of decision can be implemented in CROSSTAG, e.g.:
type union CCAorAC
{

  CannotClaimSourceAddress cannotClaimSourceAddress,
  AddressClaimed addressClaimed

}
with { variant "" }


type union AnyIsoBusPdu {
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)
  RequestForAddressClaimed requestForAddressClaimed,
  CCAorAC                           cCAorAC,
  CommandedAddress commandedAddress
  // other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }

type record CAN_frame_j1939 {
  J1939               can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.pf = 'E6'O;  //230
  ecu2vt,                   can_j1939.pf = 'E7'O;  //231
  requestForAddressClaimed, can_j1939.pf = 'EA'O;  //234
  cCAorAC,                  can_j1939.pf = 'EE'O;
  commandedAddress,         can_j1939.pf = 'FE'O)" 
  
}


now the substructures e.g. cCAorAC can be analyzed further;

for example if the result is cCAorAC then an auxiliary structure


type record CAN_frame_j1939_0 {
  J1939                 can_j1939,
  CCAorAC               cCAorAC 
}with {
  variant (cCAorAC) "CROSSTAG( 
   cannotClaimSourceAddress,can_j1939.sa = 'FE'O;
   addressClaimed, OTHERWISE  //??
  )"
  
} 



can be assembled and a new function to decode it declared etc.

Now let me add that using the built-in RAW is not compulsory;in some cases we opted ourselves for using external C functions to decode/encode , e.g. for reasons of speed. So if you decide this is not the way to go, there are other options.
Yet I believe this could be the fastest implementationwise.

Best regards
Elemer






Re: TTCN Titan Testport for socketCAN [message #1746463 is a reply to message #1746373] Sat, 29 October 2016 16:46 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

please find attached pdf derived from the book 'A Comprehensible Guide to J1939' for a more accurate specification.

I have added the further decoding of the ps and sa. While encoding works, it is not correct. The values for ps and ss (source address) are not encoded correctly.

I have set them to '00'O by default and expect them to become overwritten with the correct encoding value.

As sa and ps are not encoded correctly, e.g. in the test case 'tc_encdec_addressClaimed' the encoded message 'addressClaimed' becomes decoded as 'cannotClaimSourceAddress' message.

Please find the attached archive.

Please use SocketCAN.cfg

with especially the following test cases:

Isobustest.tc_encdec_commandedAddress
Isobustest.tc_encdec_requestForAddressClaimed
Isobustest.tc_encdec_cannotClaimSourceAddress
Isobustest.tc_encdec_addressClaimed

MC2> smtc Isobustest.tc_encdec_commandedAddress
MC2> MTC@michael-desktop: Executing test case tc_encdec_commandedAddress in module Isobustest.
MTC@michael-desktop: Test case tc_encdec_commandedAddress started.
MTC@michael-desktop: Initializing variables, timers and ports of component type Isobustest.MTC_CT inside testcase tc_encdec_commandedAddress.
MTC@michael-desktop: Component type Isobustest.MTC_CT was initialized.
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cA := { commandedAddress := { name := '1122334455667788'O, newSourceAddress := '99'O } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '05FE0000112233445566778899'O
MTC@michael-desktop: '05FE0000112233445566778899'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cA := { commandedAddress := { name := '1122334455667788'O, newSourceAddress := '99'O } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '05FE0000112233445566778899'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '05FE0000112233445566778899'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '001'B, res := '0'B, dp := '1'B, pf := 'FE'O, ps := '00'O, sa := '00'O }, can_pdu := { cA := { commandedAddress := { name := '1122334455667788'O, newSourceAddress := '99'O } } } }
MTC@michael-desktop: { can_j1939 := { prio := '001'B, res := '0'B, dp := '1'B, pf := 'FE'O, ps := '00'O, sa := '00'O }, can_pdu := { cA := { commandedAddress := { name := '1122334455667788'O, newSourceAddress := '99'O } } } }
MTC@michael-desktop: Terminating component type Isobustest.MTC_CT.
MTC@michael-desktop: Component type Isobustest.MTC_CT was shut down inside testcase tc_encdec_commandedAddress.
MTC@michael-desktop: Waiting for PTCs to finish.
MTC@michael-desktop: Setting final verdict of the test case.
MTC@michael-desktop: Local verdict of MTC: none
MTC@michael-desktop: No PTCs were created.
MTC@michael-desktop: Test case tc_encdec_commandedAddress finished. Verdict: none
MC@michael-desktop: Test execution finished.
smtc IsIsobustest.tc_encdec_requestForAddressClaimed
MC2> MTC@michael-desktop: Executing test case tc_encdec_requestForAddressClaimed in module IsIsobustest.
MTC@michael-desktop: Dynamic test case error: Module IsIsobustest does not exist.
MTC@michael-desktop: Performing error recovery.
MC@michael-desktop: Test execution finished.
smtc Isobustest.tc_encdec_cannotClaimSourceAddress
MC2> MTC@michael-desktop: Executing test case tc_encdec_cannotClaimSourceAddress in module Isobustest.
MTC@michael-desktop: Test case tc_encdec_cannotClaimSourceAddress started.
MTC@michael-desktop: Initializing variables, timers and ports of component type Isobustest.MTC_CT inside testcase tc_encdec_cannotClaimSourceAddress.
MTC@michael-desktop: Component type Isobustest.MTC_CT was initialized.
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EE00001122334455667788'O
MTC@michael-desktop: '00EE00001122334455667788'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EE00001122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '00EE00001122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: Terminating component type Isobustest.MTC_CT.
MTC@michael-desktop: Component type Isobustest.MTC_CT was shut down inside testcase tc_encdec_cannotClaimSourceAddress.
MTC@michael-desktop: Waiting for PTCs to finish.
MTC@michael-desktop: Setting final verdict of the test case.
MTC@michael-desktop: Local verdict of MTC: none
MTC@michael-desktop: No PTCs were created.
MTC@michael-desktop: Test case tc_encdec_cannotClaimSourceAddress finished. Verdict: none
MC@michael-desktop: Test execution finished.
smtc Isobustest.tc_encdec_addressClaimed
MC2> MTC@michael-desktop: Executing test case tc_encdec_addressClaimed in module Isobustest.
MTC@michael-desktop: Test case tc_encdec_addressClaimed started.
MTC@michael-desktop: Initializing variables, timers and ports of component type Isobustest.MTC_CT inside testcase tc_encdec_addressClaimed.
MTC@michael-desktop: Component type Isobustest.MTC_CT was initialized.
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { aC := { addressClaimed := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EE00001122334455667788'O
MTC@michael-desktop: '00EE00001122334455667788'O
MTC@michael-desktop: encode_CAN_frame_j1939(): Encoding @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { aC := { addressClaimed := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: encode_CAN_frame_j1939(): Stream after encoding: '00EE00001122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Stream before decoding: '00EE00001122334455667788'O
MTC@michael-desktop: decode_CAN_frame_j1939(): Decoded @Isobus.CAN_frame_j1939: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }
MTC@michael-desktop: { can_j1939 := { prio := '000'B, res := '0'B, dp := '0'B, pf := 'EE'O, ps := '00'O, sa := '00'O }, can_pdu := { cCAorAC := { cCA := { cannotClaimSourceAddress := { name := '1122334455667788'O } } } } }



[Updated on: Sun, 30 October 2016 15:19]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746491 is a reply to message #1746463] Mon, 31 October 2016 08:11 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I have found a workaround for this issue; the problem is that CROSSTAG cannot interpret "and" conjunctions.
So I have created an internal structure


type record J1939mod { // Error & RTR Frames are not considered here
  //PGN   pgn optional,
  //BIT3           ignore,
  Priority       prio,
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa,
  OCT3           comp
} with { variant "FIELDORDER(msb)" }


type record CAN_frame_j1939mod {
  J1939mod            can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.comp = 'E60000'O;  //230
  ecu2vt,                   can_j1939.comp = 'E70000'O;  //231
  requestForAddressClaimed, can_j1939.comp = 'EA0000'O;  //234
  cannotClaimSourceAddress, can_j1939.comp = 'EEFFFE'O; //238 all and conjuction needed!!!!!!
  addressClaimed,           can_j1939.comp = 'EEFF00'O;  //238 all and conjuction needed!!!!!!
  commandedAddress,         can_j1939.comp = 'FED800'O)" //254 all and conjuction needed!!!!!!
}

external function encode_CAN_frame_j1939mod(in CAN_frame_j1939mod pdu) return octetstring 
with { extension "prototype(convert) encode(RAW)" }
external function decode_CAN_frame_j1939mod(in octetstring data) return CAN_frame_j1939mod
with { extension "prototype(convert) decode(RAW)" }



which encodes/decodes based on a field comp (which is the concatenation of pf, ps and sa) exactly 3 bytes long.




So now encoding works as follows:



step 1: the CAN_frame_j1939 is mapped to this modified structure CAN_frame_j1939mod
step 2: this structure is encoded; the result contains an auxiliary 3 byte header immediately after the original header
step 3: the aux header is removed

and the decoding flow:

step 1: aux header is inserted after the original header
step 2: decoding is done based on the modified structural rules
step 3: the resulting structure is mapped to the original CAN_frame_j1939 structure



f_encode_CAN_frame_j1939 and f_decode_CAN_frame_j1939 should be called for enc/decoding


see attached zip file created by make archive (only Isobus and Isobustest has been edited)
(I have tested it to a degree, but please test it further)

Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1746614 is a reply to message #1746491] Tue, 01 November 2016 19:42 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

from what I have tested, it seems to work. However I have difficulties to understand, how the functions 'f_insert_aux_hdr(..)' and 'f_remove_aux_hdr(..)' are working.

What is not working is the encoding / decoding of the prio bits in the first byte. Here an example:

MTC@michael-desktop: encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := { name := 'A80056AAABBCC778'O } } }
MTC@michael-desktop: encode_CAN_frame_j1939mod(): Stream after encoding: '05E9FDE6EEFF00A80056AAABBCC778'O
MTC@michael-desktop: '05EEFFE6A80056AAABBCC778'O
MTC@michael-desktop: --------------------------------------------
MTC@michael-desktop: encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := { name := 'A80056AAABBCC778'O } } }
MTC@michael-desktop: encode_CAN_frame_j1939mod(): Stream after encoding: '05E9FDE6EEFF00A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939mod(): Stream before decoding: '05EEFFE6EEFF00A80056AAABBCC778'O
MTC@michael-desktop: decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '001'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O, comp := 'EEFF00'O }, can_pdu := { addressClaimed := { name := 'A80056AAABBCC778'O } } }
MTC@michael-desktop: { can_j1939 := { prio := '001'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O }, can_pdu := { addressClaimed := { name := 'A80056AAABBCC778'O } } }

The first byte should be encoded as following:
- BIT3 to be ignored, bit 7, 6, 5
- BIT3 priority (prio), bit 4, 3, 2
- BIT1 reserved (res), bit 1
- BIT1 datapage (dp), bit 0

Please check if the following alignment directive is correct:

Isobus.ttcn:
type bitstring Priority length(3)
with {
variant "ALIGN(right)";
variant "FIELDLENGTH(6)"
}

type record J1939 { // Error & RTR Frames are not considered here
  //PGN   pgn optional,
  //BIT3           ignore,
  Priority       prio,
  BIT1           res, 
  BIT1           dp,
  OCT1           pf,
  OCT1           ps,
  SourceAddress  sa
} with { variant "FIELDORDER(msb)" }


Please find the attached archive and note that I have done some changes outside of your scope in the files IsobusMessageTypes.ttcn IsobusNMMessageTypes.ttcn Isobus_Templates.ttcn Isobustest.ttcn Isobus.ttcn.

Best regards,
Michael

[Updated on: Wed, 02 November 2016 07:06]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746674 is a reply to message #1746614] Wed, 02 November 2016 19:25 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

OK,

let's go step by step:

-"prio" will not be set -and is not supposed to be set-by the RAW codec , as there are no instructions referring to its value; in fact this information cannot be derived from the structure of the message.
The RAW codec can only tell that if for instance pf&ps&sa == 'EEFFFE'O this means that the choice is cannotClaimSourceAddress and vice versa, so translates structural info into header values and back. But prio is not connected to any structural info.
(In fact RAW will set only the value of comp, see below).

This means that the user will have to set the prio value correctly when sending (e.g. in the template), there's no way for the RAW to guess that.
In reception, it will be set by the other side so it's not our concern.

-let' s take a a look at
function f_insert_aux_hdr(in octetstring p_os) return octetstring
//---------------------------------------------------------------------------
{
var OCT3 v_os
v_os[0]:=p_os[1];//pf
if(p_os[1] == 'FE'O)
{
if (p_os[2]=='D8'O) {v_os[1]:='D8'O;v_os[2]:='00'O;}
}

else if(p_os[1] == 'EE'O)
{
    if (p_os[2] == 'FF'O) 
        { if (p_os[3]=='FE'O) {v_os[1]:='FF'O;v_os[2]:='FE'O;}
        else                  {v_os[1]:='FF'O;v_os[2]:='00'O;}
        }

} 
else  { v_os[1]:='00'O;v_os[2]:='00'O;}
return replace(p_os,4,0,v_os)//insert aux header
} 



We want o assemble this aux header of 3 octets as follows:

   if pf == 'E6'O  then                      aux header :=  'E60000'O;  //(pf&'00'O&'00'O)  vt2ecu is chosen   
   if pf == 'E7'O  then                      aux header :=  'E70000'O;  //(pf&'00'O&'00'O) ecu2vt is chosen 
   if pf == 'EA'O  then                      aux header :=  'EA0000'O;  //(pf&'00'O&'00'O) requestForAddressClaimed is chosen
   if pf == 'EE'O  and ps =='FF'O and 'sa'=='FE'O  then  aux header :=  'EEFFFE'O;  //(pf&ps&sa) cannotClaimSourceAddress is chosen
   if pf == 'EE'O  and ps =='FF'O and 'sa'!= 'FE'O then aux header :=  'EEFF00'O;  //(pf&ps&'00'O)  addressClaimed is chosen 
   if pf == 'FE'O  and ps =='D8'O then aux header :=  'FED800'O;  //(pf&ps&'00'O) commandedAddress is chosen


Wherever there is '00' in the aux header means that the value is not relevant and is sort of masked. The aux header is a way to implement the "and" conjunction.



The other function
//---------------------------------------------------------------------------
function f_remove_aux_hdr(in octetstring p_os) return octetstring
//---------------------------------------------------------------------------
{

p_os[1]:=p_os[4]; //pf := aux[0];
if (p_os[4] == 'EE'O)  
{
    if (p_os[6] == 'FE'O ) { //'EEFFFE' O
        p_os[2]:=p_os[5]; //ps := aux[1];
        p_os[3]:=p_os[6]; //sa := aux[2];
            }
    else    { //'EEFFXX'O
        p_os[2]:=p_os[5]; //ps := aux[1];
            }
} 
else  if  (p_os[4] == 'FE'O) //'FED8XX'O
{
p_os[2]:=p_os[5]; //ps := aux[1];
}

return replace(p_os,4,3,''O); //remove aux header
}


implements the following logic:
as I mentioned , RAW will only set the comp value, which is added as a 3 byte aux header following the 4 byte J1939 header:

   if vt2ecu is chosen                   aux header :=  'E60000'O;  (pf&'00'O&'00'O)
   if ecu2vt is chosen                   aux header :=  'E70000'O;  (pf&'00'O&'00'O)
   if requestForAddressClaimed is chosen aux header :=  'EA0000'O;  (pf&'00'O&'00'O)
   if cannotClaimSourceAddress is chosen aux header :=  'EEFFFE'O;  (pf&ps&sa)
   if addressClaimed is chosen           aux header :=  'EEFF00'O;  (pf&ps&'00'O)
   if commandedAddress is chosen         aux header :=  'FED800'O;  (pf&ps&'00'O)


What the first part of the function does is to copy values to pf, ps, and sa if they are relevant (that is if they are different than zero);
this is to simulate the RAW codec role of filling in the values at encoding.
the replace will then remove the aux header;



Now the functions will work for any value of pf , not only 'E6'O, 'E7'O etc.
if a message comes with say pf == 'A0'O , the error will be caught in the RAW codec,
but you can modify the functions to throw an error and not call the codec if you wish.





I hope this helps

Elemer
Re: TTCN Titan Testport for socketCAN [message #1746675 is a reply to message #1746674] Wed, 02 November 2016 19:32 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

oh yes, and the priority should be declared as:

type bitstring Priority length(3)
with {
variant "ALIGN(right)";
variant "FIELDLENGTH(3)"
}


with FIELDLENGTH 3

BR
Elemer
Re: TTCN Titan Testport for socketCAN [message #1746679 is a reply to message #1746675] Wed, 02 November 2016 21:08 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Sorry , disregard my previous entry.

I see now that something weird is going on with prio but I could not figure it out yet.

Re: TTCN Titan Testport for socketCAN [message #1746732 is a reply to message #1746679] Thu, 03 November 2016 19:21 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

as a temporary measure I suggest the following: let's concatenate the 3 bits of ignore and the 3 bits of prio into 6 bits:

type bitstring Priority length(6)
with {
variant "ALIGN(left)";
variant "FIELDLENGTH(6)"
}


so an enc/dec test becomes:

template CAN_frame_j1939 t_CAN_frame_j1939 :=  { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O /*E6'O*/, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log("--------------------------------------------")
log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
log("--------------------------------------------")




20:11:07.865460 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.865630 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Stream after encoding: '19E9FDE6EEFF00A80056AAABBCC778'O
20:11:07.865436 USER Isobustest.ttcn:447(testcase:tc_encdec) '19EEFFE6A80056AAABBCC778'O
20:11:07.865873 USER Isobustest.ttcn:448(testcase:tc_encdec) --------------------------------------------
20:11:07.865983 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.866112 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Stream after encoding: '19E9FDE6EEFF00A80056AAABBCC778'O
20:11:07.866199 DEBUG Isobustest.ttcn:435(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Stream before decoding: '19EEFFE6EEFF00A80056AAABBCC778'O
20:11:07.866288 DEBUG Isobustest.ttcn:435(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O, comp := 'EEFF00'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.865974 USER Isobustest.ttcn:449(testcase:tc_encdec) { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.866496 USER Isobustest.ttcn:450(testcase:tc_encdec) --------------------------------------------


This will work, and when we fix the codec issue,
we can split it again;

When matching incoming, you can use the wildcard ?(any value) , as in
template CAN_frame_j1939 t_CAN_frame_j1939x :=  { can_j1939 := { prio := '???110'B, res := '0'B, dp := '1'B, pf := 'E9'O , ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }


BR

Elemer
Re: TTCN Titan Testport for socketCAN [message #1746734 is a reply to message #1746679] Thu, 03 November 2016 19:26 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

as a temporary measure I suggest the following: let's concatenate the 3 bits of ignore and the 3 bits of prio into 6 bits:

type bitstring Priority length(6)
with {
variant "ALIGN(left)";
variant "FIELDLENGTH(6)"
}


so an enc/dec test becomes:

template CAN_frame_j1939 t_CAN_frame_j1939 :=  { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O /*E6'O*/, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log("--------------------------------------------")
log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
log("--------------------------------------------")




20:11:07.865460 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.865630 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Stream after encoding: '19E9FDE6EEFF00A80056AAABBCC778'O
20:11:07.865436 USER Isobustest.ttcn:447(testcase:tc_encdec) '19EEFFE6A80056AAABBCC778'O
20:11:07.865873 USER Isobustest.ttcn:448(testcase:tc_encdec) --------------------------------------------
20:11:07.865983 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O, comp := 'E90000'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.866112 DEBUG Isobustest.ttcn:426(function:f_encode_CAN_frame_j1939) encode_CAN_frame_j1939mod(): Stream after encoding: '19E9FDE6EEFF00A80056AAABBCC778'O
20:11:07.866199 DEBUG Isobustest.ttcn:435(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Stream before decoding: '19EEFFE6EEFF00A80056AAABBCC778'O
20:11:07.866288 DEBUG Isobustest.ttcn:435(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O, comp := 'EEFF00'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.865974 USER Isobustest.ttcn:449(testcase:tc_encdec) { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'EE'O, ps := 'FF'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }
20:11:07.866496 USER Isobustest.ttcn:450(testcase:tc_encdec) --------------------------------------------


This will work, and when we fix the codec issue,
we can split it again;

When matching incoming, you can use the wildcard ?(any value) , as in
template CAN_frame_j1939 t_CAN_frame_j1939x :=  { can_j1939 := { prio := '???110'B, res := '0'B, dp := '1'B, pf := 'E9'O , ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := 'A80056AAABBCC778'O } }


BR

Elemer
Re: TTCN Titan Testport for socketCAN [message #1746804 is a reply to message #1746734] Fri, 04 November 2016 19:05 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello,

I removed my previous post at this place, as there was an error in the size of the PGN type definition (32 instead of 24 bits) which was cause of the trouble.

Michael

[Updated on: Sat, 05 November 2016 09:32]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746830 is a reply to message #1746804] Sat, 05 November 2016 09:46 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-first , some cosmetic issues:

if you have 'with {encode "RAW"}' at the end of the file , that will refer to all type declarations contained in that file, so it's sufficient to have it once only
for visibility, it's better to have all types decorated with a 'with {variant "" }' instruction, event if it's empty (this meaning that defaults will apply)

I have edited IsobusNMMessageTypes and IsobusMessageTypes accordingly

- the decoding failed due to the wrong declaration in IsobusNMMessageTypes

type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(32), COMP(nosign), BYTEORDER(last)" encode "RAW"};


which I changed to:
type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(24), COMP(nosign), BYTEORDER(last)" encode "RAW"};




RequestForAddressClaimed is 3 bytes and should be encoded on 3 bytes ; please check

- I have removed the part with octetstring manipulation, that is not needed:

testcase tc_dec_requestForAddressClaimed() runs on MTC_CT
{

  var octetstring j1939_pdu
  j1939_pdu := '98EAFFFE00EE00'O

  //j1939_pdu := p_can_frame.can_id & p_can_frame.can_pdu
 /* j1939_pdu := replace(j1939_pdu, 3, 1, ''O)

  if (oct2int(j1939_pdu[1]) < oct2int('F0'O)) // pf < 240 
  {
    j1939_pdu[2] := '00'O // ps := '00'O
  }
*/
  log(j1939_pdu)
  log("--------------------------------------------")
  log(f_decode_CAN_frame_j1939(j1939_pdu))
  log("--------------------------------------------")
}



So now the decoding test case works:

09:49:10.925070 USER Isobustest.ttcn:526(testcase:tc_dec_requestForAddressClaimed) '98EAFFFE00EE00'O
09:49:10.925166 USER Isobustest.ttcn:527(testcase:tc_dec_requestForAddressClaimed) --------------------------------------------
09:49:10.925254 DEBUG Isobustest.ttcn:429(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Stream before decoding: '98EAFFFEEA000000EE00'O
09:49:10.925381 DEBUG Isobustest.ttcn:429(function:f_decode_CAN_frame_j1939) decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O, comp := 'EA0000'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } }
09:49:10.925236 USER Isobustest.ttcn:528(testcase:tc_dec_requestForAddressClaimed) { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } }
09:49:10.925605 USER Isobustest.ttcn:529(testcase:tc_dec_requestForAddressClaimed) --------------------------------------------



but the reception test is not OK:

09:32:18.316695 merged 3 WARNING Isobus.ttcn:161(function:can2j1939frame) decode_AnyIsoBusPdu(): Warning: Data remained at the end of the stream after successful decoding: '00EE00'O
09:32:18.316695 3 WARNING Isobus.ttcn:161(function:can2j1939frame) decode_AnyIsoBusPdu(): Warning: Data remained at the end of the stream after successful decoding: '00EE00'O
09:32:18.316783 merged 3 USER Isobus.ttcn:163(function:can2j1939frame) Higher layer octet pdustring: { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } }
09:32:18.316783 3 USER Isobus.ttcn:163(function:can2j1939frame) Higher layer octet pdustring: { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } }
09:32:18.316929 merged 3 PORTEVENT Isobustest.ttcn:248(function:f_behaviour_isobus) Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } }
09:32:18.316929 3 PORTEVENT Isobustest.ttcn:248(function:f_behaviour_isobus) Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } }
09:32:18.317148 merged 4 PORTEVENT Isobustest.ttcn:277(function:f_behaviour1_sync) Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } } id 1
09:32:18.317148 4 PORTEVENT Isobustest.ttcn:277(function:f_behaviour1_sync) Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } } id 1
09:32:18.317354 merged 4 MATCHING Isobustest.ttcn:283(function:f_behaviour1_sync) Matching on port pt_isobus succeeded:  matched
09:32:18.317354 4 MATCHING Isobustest.ttcn:283(function:f_behaviour1_sync) Matching on port pt_isobus succeeded:  matched
09:32:18.317495 merged 4 PORTEVENT Isobustest.ttcn:283(function:f_behaviour1_sync) Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } } id 1
09:32:18.317495 4 PORTEVENT Isobustest.ttcn:283(function:f_behaviour1_sync) Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 10021631 } } } id 1
09:32:18.317642 merged 4 PORTEVENT Isobustest.ttcn:283(function:f_behaviour1_sync) Message with id 1 was extracted from the queue of pt_isobus.
09:32:18.317642 4 PORTEVENT Isobustest.ttcn:283(function:f_behaviour1_sync) Message with id 1 was extracted from the queue of pt_isobus. 


the decoded pgn value differs(10010631 -'98EAFF'O instead of 60928-'EE00' O;)


I found some errors in function can2j1939frame and function j1939frame2can
so I rewrote them a bit; mainly encode_AnyIsoBusPdu and decode_AnyIsoBusPdu cannot work correctly as the AnyIsoBusPdu declaration does not have encoding instructions to assist the codec; so please use f_decode_CAN_frame_j1939 and f_encode_CAN_frame_j1939 instead as shown.

So now reception test seems to work correctly:

 Message with id 4 was extracted from the queue of pt_socketCAN.
3@GlobalWarning1: SocketCan:Expected frame received{ id := 0, ifr := { if_name := "vcan0", if_index := 4 }, frame := { can_frame := { can_id := '98EAFFFE'O, can_pdu := '00EE00'O } }, timestamp := { tv_sec := 1478338566, tv_usec := 342137 } }
3@GlobalWarning1: can_id'98EAFFFE'O
3@GlobalWarning1: can_pdu'00EE00'O
3@GlobalWarning1: decode_CAN_frame_j1939mod(): Stream before decoding: '98EAFFFEEA000000EE00'O
3@GlobalWarning1: decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O, comp := 'EA0000'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } }
3@GlobalWarning1: Higher layer octet pdustring: { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } }
3@GlobalWarning1: Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } }
4@GlobalWarning1: Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } } id 1
4@GlobalWarning1: Matching on port pt_isobus succeeded:  matched
4@GlobalWarning1: Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EA'O, ps := 'FF'O, sa := 'FE'O }, can_pdu := { requestForAddressClaimed := { pgn := 60928 } } } id 1
4@GlobalWarning1: Message with id 1 was extracted from the queue of pt_isobus.



I have also moved f_insert_aux_hdr ...etc. to Isobus.



see attached archive;

I hope this helps

Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1746836 is a reply to message #1746830] Sat, 05 November 2016 12:15 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

Thanks a lot.

When decoding live data I regularly find that there are warnings "decode_CAN_frame_j1939mod(): Warning: Data remained at the end of the stream after successful decoding: '04FFEBFE00'O"

When looking at those, I see that these are still unsupported messages. However instead of failing, they become decoded as requestForAddressClaimed := { pgn := 1054208 }.

3@michael-desktop: Message enqueued on pt_socketCAN from system @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : { id := 0, ifr := { if_name := "vcan0", if_index := 4 }, frame := { can_frame := { can_id := '98ECF8F8'O, can_pdu := '10160004FFEBFE00'O } }, timestamp := { tv_sec := 1478347294, tv_usec := 821783 } } id 5
3@michael-desktop: Receive operation on port pt_socketCAN succeeded, message from system(): @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : { id := 0, ifr := { if_name := "vcan0", if_index := 4 }, frame := { can_frame := { can_id := '98ECF8F8'O, can_pdu := '10160004FFEBFE00'O } }, timestamp := { tv_sec := 1478347294, tv_usec := 821783 } } id 5
3@michael-desktop: Message with id 5 was extracted from the queue of pt_socketCAN.
3@michael-desktop: SocketCan:Expected frame received{ id := 0, ifr := { if_name := "vcan0", if_index := 4 }, frame := { can_frame := { can_id := '98ECF8F8'O, can_pdu := '10160004FFEBFE00'O } }, timestamp := { tv_sec := 1478347294, tv_usec := 821783 } }
3@michael-desktop: can_id'98ECF8F8'O
3@michael-desktop: can_pdu'10160004FFEBFE00'O
3@michael-desktop: decode_CAN_frame_j1939mod(): Warning: Data remained at the end of the stream after successful decoding: '04FFEBFE00'O
4@michael-desktop: Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { requestForAddressClaimed := { pgn := 1054208 } } } id 2
4@michael-desktop: Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { requestForAddressClaimed := { pgn := 1054208 } } } id 2
4@michael-desktop: Message with id 2 was extracted from the queue of pt_isobus.
3@michael-desktop: Higher layer octet pdustring: { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { requestForAddressClaimed := { pgn := 1054208 } } }
3@michael-desktop: Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { requestForAddressClaimed := { pgn := 1054208 } } }


You may reproduce it as following:

./initscript.sh
ttcn3_start SocketCAN SocketCAN_no_debug.cfg Isobustest.tc_Example001

and in another terminal

cansend vcan0 98ECF8F8#10160004FFEBFE00

Note:
Decoding for PF == 'EC'O is not implemented yet.

[Updated on: Sat, 05 November 2016 12:18]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1746837 is a reply to message #1746836] Sat, 05 November 2016 13:15 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I have added this new message in Isobus:

type OCT8 NewMessage;

type union AnyIsoBusPdu {
  TopLevelMessage_VT2ECU_PDU vt2ecu,  // Message Virtual Terminal (VT) to ECU
  TopLevelMessage_ECU2VT_PDU ecu2vt,   // Message ECU to Virtual Terminal (VT)
  RequestForAddressClaimed requestForAddressClaimed,
  NewMessage              newMessage,
  CannotClaimSourceAddress cannotClaimSourceAddress,
  AddressClaimed addressClaimed,
  CommandedAddress commandedAddress
  // other upper layer isobus protocols like Task Comtroller are added here ...
}

type record CAN_frame_j1939mod {
  J1939mod            can_j1939,
  AnyIsoBusPdu        can_pdu 
}with {
  variant (can_pdu) "CROSSTAG( 
  vt2ecu,                   can_j1939.comp = 'E60000'O;  //230
  ecu2vt,                   can_j1939.comp = 'E70000'O;  //231
  requestForAddressClaimed, can_j1939.comp = 'EA0000'O;  //234
  newMessage,               can_j1939.comp = 'EC0000'O;  
  cannotClaimSourceAddress, can_j1939.comp = 'EEFFFE'O; //238 all and conjuction needed!!!!!!
  addressClaimed,           can_j1939.comp = 'EEFF00'O;  //238 all and conjuction needed!!!!!!
  commandedAddress,         can_j1939.comp = 'FED800'O)" //254 all and conjuction needed!!!!!!
}


and I named it newMessage Smile please rename it approriately;

In lack of other info I assumed it's a field of 8 bytes.

Now it's decoded as below:
3@GlobalWarning1: Message with id 4 was extracted from the queue of pt_socketCAN.
3@GlobalWarning1: SocketCan:Expected frame received{ id := 0, ifr := { if_name := "vcan0", if_index := 4 }, frame := { can_frame := { can_id := '98ECF8F8'O, can_pdu := '10160004FFEBFE00'O } }, timestamp := { tv_sec := 1478351438, tv_usec := 30269 } }
3@GlobalWarning1: can_id'98ECF8F8'O
3@GlobalWarning1: can_pdu'10160004FFEBFE00'O
3@GlobalWarning1: Higher layer octet pdustring: { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { newMessage := '10160004FFEBFE00'O } }
3@GlobalWarning1: Sent on pt_isobus to 4 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { newMessage := '10160004FFEBFE00'O } }
4@GlobalWarning1: Message enqueued on pt_isobus from 3 @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { newMessage := '10160004FFEBFE00'O } } id 1
4@GlobalWarning1: Receive operation on port pt_isobus succeeded, message from 3: @Isobus.CAN_frame_j1939 : { can_j1939 := { prio := '100110'B, res := '0'B, dp := '0'B, pf := 'EC'O, ps := 'F8'O, sa := 'F8'O }, can_pdu := { newMessage := '10160004FFEBFE00'O } } id 1
4@GlobalWarning1: Message with id 1 was extracted from the queue of pt_isobus.



See attached.

BR

Elemer
Re: TTCN Titan Testport for socketCAN [message #1746838 is a reply to message #1746837] Sat, 05 November 2016 13:38 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Update:

encode_CAN_frame_j1939 , decode_CAN_frame_j1939 should not be used either;
f_encode_CAN_frame_j1939, f_decode_CAN_frame_j1939 should be used instead;

so I removed it to avoid confusion. See attached.

BR
Re: TTCN Titan Testport for socketCAN [message #1748467 is a reply to message #1746838] Wed, 23 November 2016 11:51 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

some feedback regarding enum etc. issues reported earlier:

4c) Usage of enums in ranges

The following works:


const e_Phase c_testcase_complete := e_testcase_complete
(0 .. enum2int(c_testcase_complete)) 


but that fails:
(0 .. enum2int(e_testcase_complete))




Not a fault: Reason:

The scope of the fields of the enumerated types are local to the enumerated type.

The first example works because the compiler can deduct the type of the argument of the enum2int function from the type
context which is provided by the const definition.

The failing example does not work because the compiler has no information about the of the e_testcase_complete
identifier. (It can be present in two different enumerated types)

See the TTCN3 standard section: C.1.30 Enumerated to integer (The inpar shall be a typed object



4a) Usage of enumerations in Constants and Variable definitions:


 v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }


works, the following fails:

 v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) or4b 
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) or4b
    ('00000000000000000000000000000001'B << enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }




type enumerated BcmFlags_enum {
  e_CAN_BCM_SETTIMER            (1),
  e_CAN_BCM_RX_RTR_FRAME        (1024),
  e_CAN_BCM_RX_RTR_FRAME_test1 ('0101'B),
  e_CAN_BCM_RX_RTR_FRAME_test2 (bit2int('0111'B)),
  e_CAN_BCM_RX_RTR_FRAME_test3 ('FFE'H),
  e_CAN_BCM_RX_RTR_FRAME_test4 (oct2int('FFF'H)),
  e_CAN_BCM_RX_RTR_FRAME_test5 ('FFFE'O),
  e_CAN_BCM_RX_RTR_FRAME_test6 (oct2int('FFFF'O))
}


Not a fault: Reason:
Same as above.





4b)
This works:

 v_bcm_read_status_frame := {
    opcode := 3, // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }



but if the opcode is initialized with an enumeration instead the integer number 3 the following fails:

  v_bcm_read_status_frame := {
    opcode := enum2int(e_CAN_BCM_TX_READ), // TX_READ
    flags  := 
    // workaround for titan constants instead of enums: 
    ('00000000000000000000000000000001'B << 0) or4b 
    ('00000000000000000000000000000001'B << 1) or4b 
    ('00000000000000000000000000000001'B << 4),
    count  := 0,
    ival1  := {0, 0},
    ival2  := {0, 0},
    can_id := 66,
    frames := {can_frame := {}}
  }

  
  type enumerated BcmOpcode_enum {
  e_CAN_BCM_TX_SETUP    (1),	  // create (cyclic) transmission task
  e_CAN_BCM_TX_DELETE   (2),	  // remove (cyclic) transmission task
  e_CAN_BCM_TX_READ     (3),	  // read properties of (cyclic) transmission task
  e_CAN_BCM_TX_SEND     (4),      // send one CAN frame
  e_CAN_BCM_RX_SETUP    (5),      // create RX content filter subscription
  e_CAN_BCM_RX_DELETE   (6),      // remove RX content filter subscription
  e_CAN_BCM_RX_READ     (7),      // read properties of RX content filter subscription
  e_CAN_BCM_TX_STATUS   (8),      // reply to TX_READ request
  e_CAN_BCM_TX_EXPIRED  (9),      // notification on performed transmissions (count=0)
  e_CAN_BCM_RX_STATUS   (10),     // reply to RX_READ request
  e_CAN_BCM_RX_TIMEOUT  (11),     // cyclic message is absent
  e_CAN_BCM_RX_CHANGED  (12)      // updated CAN frame (detected content change)
}



Not a fault: Reason:
Same as above.
A possible fix is to create a const definition.
const BcmOpcode_enum c_CAN_BCM_TX_READ := e_CAN_BCM_TX_READ;






4f) Matching received enumeration variables according to a specific enumeration value range:

where:

  var PhaseEndInd v_PhaseEndInd := {phase := v_phase, phase_int := enum2int(v_phase)}
  pt_sync.send(v_PhaseEndInd)


Due to Titan matching problems on the received side, besides the enumeration "phase", also its integer value needs to be transferred as "phase_int" as attributes.

The following works:

[] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}



, but this fails:

[] pt_sync.receive (PhaseEndInd: {phase :=  (p_phase .. c_testcase_complete), phase_int :=?}){}

and this fails also:

[] pt_sync.receive (PhaseEndInd: {phase :=  (p_phase .. e_testcase_complete), phase_int :=?}){}




Not a fault. Reason:

According to the TTCN3 standard, the value range maching mechanism in templates is only available for integer, float,
charstring and universal charstring types.

See standard: B.1.2.5 Value range


4g) Defining Enumerations using binary or hexadecimal values instead of integer values:

The following works:

type enumerated BcmFlags_enum {
  e_CAN_BCM_SETTIMER            (1),
  e_CAN_BCM_RX_RTR_FRAME        (1024)
}

, but the following additions all fail:

type enumerated BcmFlags_enum {
  e_CAN_BCM_SETTIMER            (1),
  e_CAN_BCM_RX_RTR_FRAME        (1024),
  e_CAN_BCM_RX_RTR_FRAME_test1 ('0101'B),
  e_CAN_BCM_RX_RTR_FRAME_test2 (bit2int('0111'B)),
  e_CAN_BCM_RX_RTR_FRAME_test3 ('FFE'H),
  e_CAN_BCM_RX_RTR_FRAME_test4 (oct2int('FFF'H)),
  e_CAN_BCM_RX_RTR_FRAME_test5 ('FFFE'O),
  e_CAN_BCM_RX_RTR_FRAME_test6 (oct2int('FFFF'O))
}


Although not an error, we kept it as an extension ( it will be present in 6.1.0, to be released soon), see reference guide:

4.34 Defining enumeration fields with values known at compile time
The standard explicitly says that the enumeration fields can have values that must be given as an integer literal. TITAN relaxes this restriction and allows bitstring, octetstring, hexstring literals. In addition, the fields can only be defined with values known at compile time.
For example:

const integer c_myint := 5;
type enumerated MyEnum {
  e_first (1), // allowed, integer literal
  e_second ('10'B), // allowed bitstring literal
  e_third ('43'O), // allowed octetstring literal
  e_fourth ('55'H), // allowed hexstring literal
  e_fifth (bit2int('1101'B)), // allowed value known at compile time
  e_sixth (oct2int('12'O)), // allowed value known at compile time
  e_seventh (2+3), // allowed value known at compile time
  e_eight (c_myint), // allowed value known at compile time
  e_ninth (f()), // not allowed, functions' return values are not known at 
                 // compile time
}

function f() return integer {
  return 3;
}



4d) Using negations in template ranges:
The following fails:

template integer a:= (1 .. !10)
template integer a:= (1 .. !v_value10)
template integer a:= (1 .. !e_enum10)





the first two will be fixed in a post-6.1.0 release;
the third is not legal due to not-supported-by-the-standard !e_enum10




4e) Initialization of an enumeration variable with a specific enumeration value:
The following works:

  var  e_Phase          v_phase := c_firstPhase

, but this fails:
  var  e_Phase          v_phase := e_firstPhase




This we could not reproduce; could you please clarify?



Best regards
Elemer



Re: TTCN Titan Testport for socketCAN [message #1749087 is a reply to message #1748467] Thu, 01 December 2016 17:33 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

I see. I think I was trying to refer to this example:

to 4e):

template integer a:= (1 .. !enum2int(e_enum10))


fails, but this works:
template integer a:= (1 .. !enum2int(c_enum10))


Example:
[] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(e_testcase_complete)))}){}


fails, but this works:
[] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}


See:
SocketCANtest.ttcn, line 173
Re: TTCN Titan Testport for socketCAN [message #1749088 is a reply to message #1749087] Thu, 01 December 2016 17:41 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
But what I actually wanted to do is the following:

[] pt_sync.receive (PhaseEndInd: {phase :=(p_phase .. e_testcase_complete), phase_int :=  ?}){}


using phase_int besides phase was just a workaround to enable matching and logging of the enum values at the same time.

Where phase is type of enumeration, not int:

type record PhaseEndInd   {
  e_Phase phase, 
  integer phase_int
}


type enumerated e_Phase {
  e_open_socket, 
  e_testbody1, 
  e_testbody2,
  e_testbody3,
  e_testbody4,
  e_testbody5,
  e_testbody6,
  e_testbody7,
  e_testbodyEnd,
  e_close_socket,
  e_testcase_complete
}

[Updated on: Thu, 01 December 2016 17:52]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1749091 is a reply to message #1749088] Thu, 01 December 2016 18:01 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
to 4f)

> According to the TTCN3 standard, the value range maching mechanism in templates is only available for integer, float, charstring and universal charstring types.


Maybe the standard is a bit to strict here for variables of the type of the same enumeration.

Other unrelated issue:
Also I needed something to go from one enum value to the next one. Here is what I used:

int2enum( enum2int(p_currentPhase)+1, v_nextPhase)


This might cause trouble as the enums are not necessary ordered in logical order, as I have seen in the past if there are enums not starting at 0 and having unassigned gaps.

[Updated on: Thu, 01 December 2016 20:30]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1749389 is a reply to message #1749091] Tue, 06 December 2016 08:05 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-about 4e: this will not work for the same reason as some others in this group: enumerated values belonging to an enumerated type have a local significance only;
but one can create and use a matching constant instead.
-Deviating from the standard even in the direction of relaxing it takes a strong justification as it decreases the portability of the code.
-As the above enum types you have created yourself , it should be possible to order them appropriately, as in :


type enumerated e_Phase {
  e_open_socket(0), 
  e_testbody1(1), 
  e_testbody2(2),
  e_testbody3(3),
  e_testbody4(4),
  e_testbody5(5),
  e_testbody6(6),
  e_testbody7(7),
  e_testbodyEnd(8),
  e_close_socket(9),
  e_testcase_complete(10)
}



Best regards

Elemer





Re: TTCN Titan Testport for socketCAN [message #1750423 is a reply to message #1749389] Tue, 20 December 2016 22:33 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
> -Deviating from the standard even in the direction of relaxing it takes a strong justification as it decreases the portability of the code.

Might be better to improve the standard and make a change request to keep the portability.
Re: TTCN Titan Testport for socketCAN [message #1750438 is a reply to message #1750423] Wed, 21 December 2016 06:43 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I hear you. Let me check for feasibility and also consult my colleague Gyorgy Rethy who is working with the standardization.
I'll come back to you.

BR

Elemer
Re: TTCN Titan Testport for socketCAN [message #1751059 is a reply to message #1750438] Wed, 04 January 2017 08:55 Go to previous messageGo to next message
Gyorgy Rethy is currently offline Gyorgy RethyFriend
Messages: 31
Registered: April 2015
Member
Hi Michael,

Is there a CAN-bus adapter you can recommend for a PC (or Raspberry Pi3 Smile) HW?

There seems to be quite some ... (http://elinux.org/CAN_Bus)

[Updated on: Wed, 04 January 2017 11:51]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1751174 is a reply to message #1751059] Thu, 05 January 2017 11:42 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,


back to the issue listed as 4f) Matching received enumeration variables according to a specific enumeration value range
and also related to your note about the enums not starting at zero/not being contiguous:

this is the very nature of the enumerated type; as a direct consequence,
it is indeed meaningless to use them in constructs in which you intend to step from one enum value to next, as in

for (v_enum:=int2enum(1); v_enum<=int2enum(10); v_enum:= int2enum(enum2int(v_enum)+1) 


For the same reason they cannot be used in value ranges, as in

...c_enum_value_0 .. c_enum_value_1...


I believe difficulties arise because you are trying to enforce usage of enums as integers which they are not;

to simplify things, my suggestion is you use straight integers with named values :

for instance

const integer e_open_socket:= 0;
const integer  e_testbody1:= 1; 
const integer  e_testbody2:= 2;
const integer  e_testbody3:= 3;
const integer  e_testbody4:= 4;
const integer  e_testbody5:= 5;
const integer  e_testbody6:= 6;
const integer  e_testbody7:= 7;
const integer  e_testbodyEnd:= 8;
const integer  e_close_socket:= 9;
const integer  e_testcase_complete:= 10; 



and then you can use both stepping over values -as in "add 1 to the value" - and value ranges.

( the inherent danger here is that invalid integer values might leak into your code:

var integer v_testbody:= e_testbody1;
:
v_testbody:= 13;



and you, the programmer has to take care to prevent this ;
one can use e.g. range subtypes of integer

type integer MyIntegerRange (0 .. 10); 


to restrict the range of possible values.

when using enumerated types , the type itself will help to keep things consistent, as you cannot attribute a value outside the given type to an enumerated value; and you see exactly the results of this consistency check when the compiler refuses ranges of enums etc. )



As an alternative I suppose functions can be written to step from one enum value within a type to the next value or whatever manipulation is needed but that would be overkill.

Of course similar functions can be made part of the language but at the moment I believe this would mean very little gain compared to the effort needed to be invested.

Best regards

Elemer












Re: TTCN Titan Testport for socketCAN [message #1752109 is a reply to message #1751059] Wed, 18 January 2017 21:58 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello György,

you should be able to use ANY SocketCAN capable device. What I think is recommended, is to have galvanic transceiver isolation in order to prevent some strange effects by current loops, when connecting 2 powered devices via the CAN-Bus.

I have in the past used for most of my tests a virtual can bus device (VCAN) and have a limited experience with real hardware on SocketCAN. The ISOBUS devices I used had been running on the same VCAN on my PC.

> Is there a CAN-bus adapter you can recommend for a PC (or Raspberry Pi3 Smile) HW?
After discussion with EMS Wünsche I bought:

http://www.ems-wuensche.com/product/datasheet/html/can-usb-adapter-converter-interface-cpcusb.html

Type: CPC-USB/ARM7-GTI where GTI stands for galvanic transceiver isolation.

Also you should inform about CAN-termination, as CAN-busses need to be terminated.
I found nice equipment for this purpose at Peak (120 Ohm terminator, T-Adapter). So you do not have to build such things by yourself.

But feel free to use any other supported vendor.

For better information, the SocketCAN kernel mailing list (linux-can@vger.kernel.org) might be the right place.

Br,
Michael

Re: TTCN Titan Testport for socketCAN [message #1752110 is a reply to message #1751059] Wed, 18 January 2017 22:06 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
SocketCAN send queue size and blocking send

The SocketCAN-Bus has by default a send queue length of 10 bytes. If you need blocking send behaviour see chapter 3.4 here:
http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf

(Link provided by Oliver Hartkopp on SocketCAN mailing list. )

[Updated on: Wed, 18 January 2017 22:07]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1752431 is a reply to message #1751174] Mon, 23 January 2017 17:31 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

you are right. It is not worth all the hassle just to have textual enumerations in the log files. I should better go with constants.

Michael
Re: TTCN Titan Testport for socketCAN [message #1752432 is a reply to message #1752431] Mon, 23 January 2017 17:38 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

when testing SAEJ1939 and ISOBUS messages, there is the problem that there is a segmentation reassembly layer build on top of the SocketCAN interface. It is responsible to segment / reassemble CAN-Messages consisting of more than 8 bytes.

To me it looks like that there needs this segmenetation / reassemby layer to be implemented between the Titan test port and the SocketCAN interface.

What is the best option to do so? Are there any examples for such segmentation / reassembly layer implementations?

Best regards,
Michael
Re: TTCN Titan Testport for socketCAN [message #1752468 is a reply to message #1752432] Tue, 24 January 2017 07:52 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

the first thing that comes to mind is a typical scenario for the TCP port: the messages incoming may be glued together or chunked.
It's the upper layer (or an extension to the TCP port) that has to deal with separating/reconstructing the messages.
This is usually done either with delimiters ( such as <...> for XML or {..} for JSON)
or length information contained in the message.

I can't give you a piece of code as solutions differs from protocol to protocol , but I can explain the algorithm.

Say we have the following binary chunks which will arrive in order over TCP: m1+m2+m3p1 m3p2 m3p3 m3p4+m4p1 m4p2+m5 where m3p1 means message 3 part 1 and so on

We need a buffer where these messages will be deposited and a message dissection function which identifies a complete message in the buffer,
extracts it (removes it from the buffer) and sends it to the upper layer(output of the port).

At start , the message buffer is empty. At reception of m1+m2+m3p1 this is deposited in the buffer. The dissection function will identify m1, extract it and send it;
buffer changes to m2+m3p1; this is done recursively until no complete message is identified; so m2 is sent, buffer changes to m3p1;

at reception of m3p2 this is added to the buffer : m3p1+m3p2
as this is not a complete message , nothing changes

same for m3p3 ; the buffer will be m3p1+m3p2+m3p3

at the reception of m3p4+m4p1, m3 is reassembled and sent, buffer changes to m4p1

finally , at the reception of m4p2+m5 , m4 is reassembled and sent, then m5 is also extracted ;
the buffer empties.

So you need a buffer (which you probably already have) and a dissection function which can identify complete messages.
In your case this can be done based on message length.


Segmentation I suppose should be simpler: again a function will have to dissect messages into chunks of appropriate length.


I hope this helps

Best regards
Elemer

[Updated on: Tue, 24 January 2017 09:25]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1754420 is a reply to message #1752468] Fri, 17 February 2017 14:59 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

yes. That is correct. My question was rather, whether this can be implemented in the test port itself or if that has to be a kernel driver.

Nevertheless, there is a kernel driver for J1939/Isobus for this purpose. I will try to use that.

Michael
Re: TTCN Titan Testport for socketCAN [message #1754421 is a reply to message #1754420] Fri, 17 February 2017 15:16 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello,

currently I am looking into using SocketCAN with plain CAN-Messages. No J1939/Isobus messages.
Here the CAN-ID is used as protocol discriminator.

My_can_matrix.ttcn:

 type union CAN_MatrixPayloadUnion
 {
   MESSAGE_TESTFRAME1        message_MyTestframe1,
   MESSAGE_TESTFRAME2        message_MyTestframe2,
   MESSAGE_TESTFRAME3        message_MyTestframe3,
   MESSAGE_EXTENDEDFRAME1    message_extendedFrame1
 }
  with {variant "" }
 
 type record CAN_MatrixUnion {
   CAN_id					can_id,
   CAN_MatrixPayloadUnion	can_pdu
} with {variant (can_pdu) "CROSSTAG(
   message_MyTestframe1,          can_id =  '00000123'O;
   message_MyTestframe2,          can_id =  '00000124'O;
   message_MyTestframe3,          can_id =  '00000125'O;
   message_extendedFrame1,        can_id =  '80000001'O;
 )"
 } 



CAN_matrix.ttcn:

external function f_encode_can_matrix(in CAN_MatrixUnion pdu) return octetstring 
with { extension "prototype(convert) encode(RAW)" }
external function f_decode_can_matrix(in octetstring data) return CAN_MatrixUnion
with { extension "prototype(convert) decode(RAW)" }





// there needs to be written a conversion function to convert the received
// can frames e.g. v_frame_to_send1.can_frame to the encoded / decoded can_frames
// the following conversion functions are just a first guess and not complete
// I might need to ask Ericsson for help or digg deep in the specs.

//---------------------------------------------------------------------------------------
function canframe2canmatrixframe(CAN_frame p_can_frame) return CAN_MatrixUnion {
  //--------------------------------------------------------------------------------------- 
  var CAN_MatrixUnion v_can_frame_can_matrix

  //log("can_id", p_can_frame.can_id)  
  //log("can_pdu", p_can_frame.can_pdu)

  v_can_frame_can_matrix:=f_decode_can_matrix(p_can_frame.can_id& p_can_frame.can_pdu)

  //log("Higher layer octet pdustring: ", v_can_frame_j1939)
  return v_can_frame_can_matrix
}

//---------------------------------------------------------------------------------------
function canmatrixframe2can(in CAN_MatrixUnion p_can_matrix_frame) return CAN_frame {
  //---------------------------------------------------------------------------------------
  var CAN_frame v_can_frame

  v_can_frame.can_id := p_can_matrix_frame.can_id
  v_can_frame.can_pdu := substr(f_encode_can_matrix(p_can_matrix_frame),0,4)//strip 4 byte can id
  return v_can_frame
}


I do not get this below correct without defining 2 templates, which is nonsense:.


CAN_matrix_test.ttcn:
testcase tc_encdec() runs on MTC_CT

{
     template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := {message_MyTestframe1 := {
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
    }
  }

  log(f_encode_can_matrix(valueof(t_message_testFrame1)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame1))))
  log("--------------------------------------------")
}


Perhaps a mapping function is missing.

Br,
Michael
PS:
Please find make archive attached.
Re: TTCN Titan Testport for socketCAN [message #1754473 is a reply to message #1754421] Sat, 18 February 2017 08:47 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

OK , let me see if I understand correctly:

You are saying that an attempt to encode

   template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := {message_MyTestframe1 := {
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
    }
  
}

terminates in an error:

DEBUG CAN_matrix_test.ttcn:49(testcase:tc_encdec) f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { can_id := <unbound>, test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '111'B } } }
09:08:54.077557 ERROR CAN_matrix_test.ttcn:49(testcase:tc_encdec) Dynamic test case error: While RAW-encoding type '@My_can_matrix.CAN_MatrixUnion': Encoding an unbound value.

while encoding/decoding this

 template CAN_MatrixPayloadUnion t_message_testFrame1x := { message_MyTestframe1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id := '00000123'O, // '...'O as this is anm octetstring
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
  }

    template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := t_message_testFrame1x
  }


works OK.


Is my understanding correct?

I believe you are making the assumption that , as they can_id is "fixed" in the type declaration:

type record MESSAGE_TESTFRAME1
{
        CAN_id                                     can_id ('00000123'O),
        Signal_SOME_11BIT_bitstring_TESTSIGNAL     test_sig_11_bit_bitstring_msb_coded,
        Signal_SOME_5BIT_bitstring_TESTSIGNAL      test_sig_5_bit_bitstring_msb_coded

} with {variant "" }





it should be assumed with the same value in the template, hence can be dropped.



This does not happen; if you add it in the template





 template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := {message_MyTestframe1 := {
      can_id := '00000123'O,
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
    }
  }
  


then the encoding /decoding loop will work.


Although your assumption is a fair one, you have to consider that the compiler and the codec are somewhat disconnected;

the subtyping information in the type declaration is being used e.g. during compilation, as it can be seen if you attempt a wrong value:


     template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := {message_MyTestframe1 := {
      can_id := '00000124'O,
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
    }
  }
  
  
  CAN_matrix_test.ttcn: In TTCN-3 module `CAN_matrix_test':
 CAN_matrix_test.ttcn:13.1-53.1: In testcase definition `tc_encdec':
  CAN_matrix_test.ttcn:36.7-45.3: In template definition `t_message_testFrame2':
   CAN_matrix_test.ttcn:39.21-44.5: In template for record field `can_pdu':
    CAN_matrix_test.ttcn:39.46-43.5: In template for union field `message_MyTestframe1':
     CAN_matrix_test.ttcn:40.17-27: In template for record field `can_id':
      CAN_matrix_test.ttcn:40.17-27: error: '00000124'O is not a valid value for type `octetstring' which has subtype ('00000123'O)
Notify: Error found in the input modules. Code will not be generated.




but this information does not propagate to the codec.




Now , the problem with this

 template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := {message_MyTestframe1 := {
      can_id := '00000123'O,
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '111'B         // '...'B as this is a bitstring
    }
    }
  }



is that you have to specify can_id twice, which does not seem very smart.

but why not declaring the below types without can_id ? It works the same and you don't have to use can_id twice.


type record MESSAGE_TESTFRAME1
{
      //  CAN_id                                     can_id ('00000123'O),
        Signal_SOME_11BIT_bitstring_TESTSIGNAL     test_sig_11_bit_bitstring_msb_coded,
        Signal_SOME_5BIT_bitstring_TESTSIGNAL      test_sig_5_bit_bitstring_msb_coded

} with {variant "" }

type record MESSAGE_TESTFRAME2
{
      //  CAN_id                                     can_id ('00000124'O),
        Signal_SOME_11BIT_integer_value_TESTSIGNAL test_sig_11_bit_integer_msb_coded,
        Signal_SOME_5BIT_integer_value_TESTSIGNAL test_sig_5_bit_integer_msb_coded

} with {variant "" }

type record MESSAGE_TESTFRAME3
{
     //   CAN_id                                     can_id ('00000125'O),
        Signal_SOME_1BYTE_octetstring_value_TESTSIGNAL test_sig_1_byte_octetstring_msb_coded,
        Signal_SOME_2BYTE_octetstring_value_TESTSIGNAL test_sig_2_byte_octetstring_msb_coded

} with {variant "" }

type record MESSAGE_EXTENDEDFRAME1
{
     //   CAN_id                                     can_id ('80000001'O), 
        // according to SocketCAN Extended frames have the bit 31 set,
        Signal_SOME_2BYTE_octetstring_value_TESTSIGNAL test_sig_2_byte_octetstring_msb_coded

} with {variant "" }

 type union CAN_MatrixPayloadUnion
 {
   // put all VT2ECU request messages here
   MESSAGE_TESTFRAME1        message_MyTestframe1,
   MESSAGE_TESTFRAME2        message_MyTestframe2,
   MESSAGE_TESTFRAME3        message_MyTestframe3,
   MESSAGE_EXTENDEDFRAME1    message_extendedFrame1
 }
  with {variant "" }
 
 type record CAN_MatrixUnion {
   CAN_id					can_id,
   CAN_MatrixPayloadUnion	can_pdu
} with {variant (can_pdu) "CROSSTAG(
   message_MyTestframe1,          can_id =  '00000123'O;
   message_MyTestframe2,          can_id =  '00000124'O;
   message_MyTestframe3,          can_id =  '00000125'O;
   message_extendedFrame1,        can_id =  '80000001'O;
 )"
 }  


I have attached the modified files

Please let me know if this helps


As for "My question was rather, whether this can be implemented in the test port itself or if that has to be a kernel driver. "

I see no reason why it could not be part of the test port, but if the kernel driver works just the same, I'd use that one.

Best regards

Elemer


Re: TTCN Titan Testport for socketCAN [message #1754478 is a reply to message #1754473] Sat, 18 February 2017 11:58 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

besides the above, I suppose can_id should appear only once in the encoded binary.

BR

Elemer
Re: TTCN Titan Testport for socketCAN [message #1754479 is a reply to message #1754473] Sat, 18 February 2017 13:39 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

I made minor updates to the files below.

CAN_matrix_test.ttcn:
testcase tc_encdec() runs on MTC_CT

{
  template CAN_MatrixPayloadUnion t_message_testFrame1 := { message_MyTestframe1 := {
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '11111'B         // '...'B as this is a bitstring
    }
  }

  log(f_encode_can_matrix(valueof(t_message_testFrame1)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame1))))
  log("--------------------------------------------")
}


My current problem is that I do not get the encode /decode functions working:

make:
...
CAN_matrix_test.ttcn: In TTCN-3 module `CAN_matrix_test':
 CAN_matrix_test.ttcn:13.1-26.1: In testcase definition `tc_encdec':
  CAN_matrix_test.ttcn:22.3-57: In log statement:
   CAN_matrix_test.ttcn:22.26-56: In actual parameter list of external function `@CAN_matrix.f_encode_can_matrix':
    CAN_matrix_test.ttcn:22.27-55: In parameter #1 for `pdu':
     CAN_matrix_test.ttcn:22.27-55: In the operand of operation `valueof()':
      CAN_matrix_test.ttcn:22.35-54: error: Type mismatch: a value or template of type `@My_can_matrix.CAN_MatrixUnion' was expected instead of `@My_can_matrix.CAN_MatrixPayloadUnion'
  CAN_matrix_test.ttcn:24.3-78: In log statement:
   CAN_matrix_test.ttcn:24.26-77: In actual parameter list of external function `@CAN_matrix.f_decode_can_matrix':
    CAN_matrix_test.ttcn:24.27-76: In parameter #1 for `data':
     CAN_matrix_test.ttcn:24.46-76: In actual parameter list of external function `@CAN_matrix.f_encode_can_matrix':
      CAN_matrix_test.ttcn:24.47-75: In parameter #1 for `pdu':
       CAN_matrix_test.ttcn:24.47-75: In the operand of operation `valueof()':
        CAN_matrix_test.ttcn:24.55-74: error: Type mismatch: a value or template of type `@My_can_matrix.CAN_MatrixUnion' was expected instead of `@My_can_matrix.CAN_MatrixPayloadUnion'
Notify: Errors found in the input modules. Code will not be generated.
make: *** No rule to make target 'compile', needed by 'SocketCAN_Types.hh'.  Stop.


Br,
Michael
Re: TTCN Titan Testport for socketCAN [message #1754481 is a reply to message #1754479] Sat, 18 February 2017 14:42 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

the codecs are written for the type CAN_MatrixUnion

external function f_encode_can_matrix(in CAN_MatrixUnion pdu) return octetstring 
with { extension "prototype(convert) encode(RAW)" }
external function f_decode_can_matrix(in octetstring data) return CAN_MatrixUnion
with { extension "prototype(convert) decode(RAW)" }


so a template of this type is expected:

  template CAN_MatrixUnion t_message_testFrame1 := {
      // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
      can_id     := '00000123'O, // '...'O as this is anm octetstring
      can_pdu    := { message_MyTestframe1 := {
      test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
      test_sig_5_bit_bitstring_msb_coded  := '11111'B         // '...'B as this is a bitstring
    }
  }
}  



and with this , the encoding works correctly in loop:

15:33:09.188010 PARALLEL CAN_matrix_test.ttcn:13(testcase:tc_encdec) Component type CAN_matrix_test.MTC_CT was initialized.
15:33:09.188067 DEBUG CAN_matrix_test.ttcn:28(testcase:tc_encdec) f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
15:33:09.188135 DEBUG CAN_matrix_test.ttcn:28(testcase:tc_encdec) f_encode_can_matrix(): Stream after encoding: '00000123AB5F'O
15:33:09.188059 USER CAN_matrix_test.ttcn:28(testcase:tc_encdec) '00000123AB5F'O
15:33:09.188203 USER CAN_matrix_test.ttcn:29(testcase:tc_encdec) --------------------------------------------
15:33:09.188242 DEBUG CAN_matrix_test.ttcn:30(testcase:tc_encdec) f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
15:33:09.188279 DEBUG CAN_matrix_test.ttcn:30(testcase:tc_encdec) f_encode_can_matrix(): Stream after encoding: '00000123AB5F'O
15:33:09.188308 DEBUG CAN_matrix_test.ttcn:30(testcase:tc_encdec) f_decode_can_matrix(): Stream before decoding: '00000123AB5F'O
15:33:09.188342 DEBUG CAN_matrix_test.ttcn:30(testcase:tc_encdec) f_decode_can_matrix(): Decoded @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
15:33:09.188240 USER CAN_matrix_test.ttcn:30(testcase:tc_encdec) { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
15:33:09.188418 USER CAN_matrix_test.ttcn:31(testcase:tc_encdec) --------------------------------------------
15:33:09.188449 PARALLEL CAN_matrix_test.ttcn:31(testcase:tc_encdec) Terminating component type CAN_matrix_test.MTC_CT.
15:33:09.188478 PARALLEL CAN_matrix_test.ttcn:31(testcase:tc_encdec) Component type CAN_matrix_test.MTC_CT was shut down inside testcase tc_encdec.
15:33:09.188508 EXECUTOR CAN_matrix_test.ttcn:31(testcase:tc_encdec) Waiting for PTCs to finish.
15:33:09.188595 VERDICTOP CAN_matrix_test.ttcn:31(testcase:tc_encdec) Setting final verdict of the test case.
15:33:09.188659 VERDICTOP CAN_matrix_test.ttcn:31(testcase:tc_encdec) Local verdict of MTC: none
15:33:09.188700 VERDICTOP CAN_matrix_test.ttcn:31(testcase:tc_encdec) No PTCs were created.
15:33:09.188729 TESTCASE CAN_matrix_test.ttcn:31(testcase:tc_encdec) Test case tc_encdec finished. Verdict: none
15:33:09.189213 STATISTICS - Verdict statistics: 1 none (100.00 %), 0 pass (0.00 %), 0 inconc (0.00 %), 0 fail (0.00 %), 0 error (0.00 %).



same for the rest:

 
    template CAN_MatrixUnion t_message_testFrame2 := {

      can_id     := '00000124'O, // '...'O as this is anm octetstring
      can_pdu    := { message_MyTestframe2 := {

      test_sig_11_bit_integer_msb_coded := 2047, // as this is a integer
    test_sig_5_bit_integer_msb_coded  := 2    // as this is a integer
    }
  }
  }


   log(f_encode_can_matrix(valueof(t_message_testFrame2)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame2))))
  log("--------------------------------------------")
  
  
   template CAN_MatrixUnion t_message_testFrame3 := {

      can_id     := '00000125'O, // '...'O as this is anm octetstring
      can_pdu    := { message_MyTestframe3 := {

    test_sig_1_byte_octetstring_msb_coded := 'FF'O,  // as this is a 1 Byte octetstring
    test_sig_2_byte_octetstring_msb_coded := '123F'O // as this is a 2 Byte octetstring
    }
  }
  }

  log(f_encode_can_matrix(valueof(t_message_testFrame3)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame3))))
  log("--------------------------------------------")
  
  
  
    template CAN_MatrixUnion t_message_extendedFrame1 := {

      can_id     := '80000001'O, // '...'O as this is anm octetstring
      can_pdu    := { message_extendedFrame1 := {

    test_sig_2_byte_octetstring_msb_coded := 'FFFF'O  // as this is a 2 Byte octetstring
    }
  }
  }

 log(f_encode_can_matrix(valueof(t_message_extendedFrame1)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_extendedFrame1))))
  log("--------------------------------------------")



see attached file and log.

Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1754494 is a reply to message #1754481] Sat, 18 February 2017 18:55 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

this is not what I need, however I think Titan makes even here an error when calculating the bits.

Sticking to your example in file "Bcm.GlobalWarning1-mtc.log":

15:40:18.346722 EXECUTOR - Executing test case tc_encdec in module CAN_matrix_test.
15:40:18.346886 TESTCASE CAN_matrix_test.ttcn:13(testcase:tc_encdec) Test case tc_encdec started.
15:40:18.346976 PARALLEL CAN_matrix_test.ttcn:13(testcase:tc_encdec) Initializing variables, timers and ports of component type CAN_matrix_test.MTC_CT inside testcase tc_encdec.
15:40:18.347068 PARALLEL CAN_matrix_test.ttcn:13(testcase:tc_encdec) Component type CAN_matrix_test.MTC_CT was initialized.
15:40:18.347192 DEBUG CAN_matrix_test.ttcn:28(testcase:tc_encdec) f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
15:40:18.347340 DEBUG CAN_matrix_test.ttcn:28(testcase:tc_encdec) f_encode_can_matrix(): Stream after encoding: '00000123AB5F'O
15:40:18.347175 USER CAN_matrix_test.ttcn:28(testcase:tc_encdec) '00000123AB5F'O


when concatenation '01010101011'B with '11111', I get ' 0101010101111111'B, which provides '557F'H and not 'AB5F' as calculated by Titan above.
Note:
Both fields have MSB encoding, but even when reverting the bits I do not get to 'AB5F'.

[Updated on: Sat, 18 February 2017 19:53]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1754495 is a reply to message #1754494] Sat, 18 February 2017 19:06 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Sticking to this example:

Encoded:
message_MyTestframe1_encoded := { 
  can_id := '00000123'O, 
  can_pdu := '557F'
}


Decoded:
message_MyTestframe1_decoded := { 
   test_sig_11_bit_bitstring_msb_coded := '01010101011'B, 
   test_sig_5_bit_bitstring_msb_coded := '11111'B 
}


Rationale:
A can-matrix receives CAN messages consisting of a CAN-ID and a CAN-PDU.
The CAN-ID determines the type ("encoding") of the CAN-PDU, thus it is the protocol discriminator, even if it is separated when the PDU is encoded.

[Updated on: Sat, 18 February 2017 19:38]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1754498 is a reply to message #1754494] Sat, 18 February 2017 22:00 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

well, Titan does what is instructed, most of the time at least Smile

I have made some corrections in CAN_matrix_general_types.ttcn and My_can_matrix.ttcn (attached), please use these.

The problem basically is the following:

when assembling a structure , e.g. a record, then the RAW coder has to be told how to concatenate the fields, what is the bitorder in fields etc.(even if there are instructions for the field type-those are valid for the stand-alone use of that type, not usage within a structure)

For example see the below additions:

type record MESSAGE_TESTFRAME1
{
        Signal_SOME_11BIT_bitstring_TESTSIGNAL     test_sig_11_bit_bitstring_msb_coded,
        Signal_SOME_5BIT_bitstring_TESTSIGNAL      test_sig_5_bit_bitstring_msb_coded

} with {variant "FIELDORDER(msb)"
         variant (test_sig_11_bit_bitstring_msb_coded) "BITORDERINFIELD(msb)" 
         variant (test_sig_5_bit_bitstring_msb_coded)  "BITORDERINFIELD(msb)"
}  


This is especially critical if the fields don't match octet boundaries, as the RAW coder will assume some defaults for FIELDORDER, BITORDERINFIELD, ALIGN etc. which may not match our purpose.


So with these corrections the encoding should work by and large;

But you were saying that this is not what you need; obviously I'm missing something so could you please explain where exactly you need to get?

BR
Elemer




Re: TTCN Titan Testport for socketCAN [message #1754504 is a reply to message #1754498] Sun, 19 February 2017 08:10 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi MIchael,

so if I understand correctly , in the encoding/sending direction you want to obtain this binary

|can_id|can_pdu|


and in the receiving| decoding direction from the same binary

|can_id|can_pdu| 


you want to extract the can_pdu structure and lose can_id. Is this correct?



In the encoding direction you can use f_encode_can_matrix() with a template of type CAN_MatrixUnion;
In the decoding direction you decode with f_decode_can_matrix() , resulting in a type CAN_MatrixUnion, but use only the can_pdu part of it;

you can write a wrapper around f_decode_can_matrix() to return CAN_MatrixPayloadUnion


Is this of any help?

BR Elemer
Re: TTCN Titan Testport for socketCAN [message #1754523 is a reply to message #1754504] Sun, 19 February 2017 13:20 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

I think I got it now, here my encoding / decoding wrapper functions:
//---------------------------------------------------------------------------------------
function canframe2canmatrixframe(CAN_frame p_can_frame) return CAN_MatrixUnion {
  //--------------------------------------------------------------------------------------- 
  var CAN_MatrixUnion v_can_frame_can_matrix

  //log("can_id", p_can_frame.can_id)  
  //log("can_pdu", p_can_frame.can_pdu)

  v_can_frame_can_matrix:=f_decode_can_matrix(p_can_frame.can_id& p_can_frame.can_pdu)

  //log("Higher layer octet pdustring: ", v_can_frame_can_matrix)
  return v_can_frame_can_matrix
}

//---------------------------------------------------------------------------------------
function canmatrixframe2can(in CAN_MatrixUnion p_can_matrix_frame) return CAN_frame {
  //---------------------------------------------------------------------------------------
  var CAN_frame v_can_frame

  v_can_frame.can_id := p_can_matrix_frame.can_id
  var octetstring v_encoded
  v_encoded := f_encode_can_matrix(p_can_matrix_frame)
  v_can_frame.can_pdu := substr(v_encoded,4,lengthof(v_encoded)-4)//strip 4 byte can id
  return v_can_frame
}
Re: TTCN Titan Testport for socketCAN [message #1754524 is a reply to message #1754523] Sun, 19 February 2017 13:31 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

still I have the feeling that the encoding / decoding is not working correctly. At least when I try to manually calculate the same, I do not come to the same value.

Encoded with fieldorder LSB:
  template CAN_MatrixUnion t_message_testFrame0 := {
    // please note that if it is an extended can address, it would be '0x80000122' as usual in socketCAN
    can_id     := '00000122'O, // '...'O as this is anm octetstring
    can_pdu    := { message_MyTestframe0 := {
        test_sig_11_bit_bitstring_lsb_coded := '01010101011'B, // '...'B as this is a bitstring
        test_sig_5_bit_bitstring_lsb_coded  := '11111'B         // '...'B as this is a bitstring
      }
    }
  }  


  log(f_encode_can_matrix(valueof(t_message_testFrame0)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame0))))
  log("--------------------------------------------")


Results in:
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000122'O, can_pdu := { message_MyTestframe0 := { test_sig_11_bit_bitstring_lsb_coded := '01010101011'B, test_sig_5_bit_bitstring_lsb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Stream after encoding: '00000122ABFA'O
MTC@michael-HP-Compaq-6735s: '00000122ABFA'O
MTC@michael-HP-Compaq-6735s: --------------------------------------------
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000122'O, can_pdu := { message_MyTestframe0 := { test_sig_11_bit_bitstring_lsb_coded := '01010101011'B, test_sig_5_bit_bitstring_lsb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Stream after encoding: '00000122ABFA'O
MTC@michael-HP-Compaq-6735s: f_decode_can_matrix(): Stream before decoding: '00000122ABFA'O
MTC@michael-HP-Compaq-6735s: f_decode_can_matrix(): Decoded @My_can_matrix.CAN_MatrixUnion: { can_id := '00000122'O, can_pdu := { message_MyTestframe0 := { test_sig_11_bit_bitstring_lsb_coded := '01010101011'B, test_sig_5_bit_bitstring_lsb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: { can_id := '00000122'O, can_pdu := { message_MyTestframe0 := { test_sig_11_bit_bitstring_lsb_coded := '01010101011'B, test_sig_5_bit_bitstring_lsb_coded := '11111'B } } }


but I calculate '557F'O istead of 'ABFA'O as encoded PDU

and encoded with fieldorder MSB:
template CAN_MatrixUnion t_message_testFrame1 := {
    // please note that if it is an extended can address, it would be '0x80000123' as usual in socketCAN
    can_id     := '00000123'O, // '...'O as this is anm octetstring
    can_pdu    := { message_MyTestframe1 := {
        test_sig_11_bit_bitstring_msb_coded := '01010101011'B, // '...'B as this is a bitstring
        test_sig_5_bit_bitstring_msb_coded  := '11111'B         // '...'B as this is a bitstring
      }
    }
  }  


  log(f_encode_can_matrix(valueof(t_message_testFrame1)))
  log("--------------------------------------------")
  log(f_decode_can_matrix(f_encode_can_matrix(valueof(t_message_testFrame1))))
  log("--------------------------------------------")


Results in:
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Stream after encoding: '00000123AADF'O
MTC@michael-HP-Compaq-6735s: '00000123AADF'O
MTC@michael-HP-Compaq-6735s: --------------------------------------------
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Encoding @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: f_encode_can_matrix(): Stream after encoding: '00000123AADF'O
MTC@michael-HP-Compaq-6735s: f_decode_can_matrix(): Stream before decoding: '00000123AADF'O
MTC@michael-HP-Compaq-6735s: f_decode_can_matrix(): Decoded @My_can_matrix.CAN_MatrixUnion: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }
MTC@michael-HP-Compaq-6735s: { can_id := '00000123'O, can_pdu := { message_MyTestframe1 := { test_sig_11_bit_bitstring_msb_coded := '01010101011'B, test_sig_5_bit_bitstring_msb_coded := '11111'B } } }


but I calculate 'D55F'O isstead of 'AADF'O as encoded pdu, but I am here not completely sure how to calculate this.

Please note that I made significant updates to "CAN_matrix_general_types.ttcn" by removing the FIEDORDER encoding, as it is not needed.

[Updated on: Sun, 19 February 2017 13:41]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1754525 is a reply to message #1754523] Sun, 19 February 2017 13:44 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

yes, this is sort of what I was thinking about.

You receive CAN_frame form the port:

type union SocketCAN_CAN_or_CAN_FD_frame {
  CAN_frame                        can_frame,
  CANFD_frame                      canfd_frame
}


which is decoded and mapped into CAN_MatrixUnion with
function canframe2canmatrixframe(CAN_frame p_can_frame) return CAN_MatrixUnion()



In the opposite direction you take a CAN_MatrixUnion and encode /map it onto a CAN_frame to be sent to the test port.

Yes, it looks consistent. Let's hope it works too...Smile


BR

Elemer

Re: TTCN Titan Testport for socketCAN [message #1754526 is a reply to message #1754525] Sun, 19 February 2017 13:55 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Yes. Same for CANFD_frame is still missing.

What is the reason for what that I am doing is, that CAN-Messages are usually described in CAN-Databases.
The next step is code generation of the CAN-Database to ASN.1 encoders / decoders. Lets see how it goes.

[Updated on: Sun, 19 February 2017 13:59]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1754531 is a reply to message #1754525] Sun, 19 February 2017 15:25 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

yes, but you have changed CAN_matrix_general_types and also My_can_matrix and you should not have to.
Please keep the one I have sent you as the BITORDER instructions there are important.
First the RAW encodes according to BITORDER and then
changes/keeps bitorder according to BITORDERINFIELD and
concatenates according to FIELDORDER tied to the structure.


So please use the attached CAN_matrix_general_types.ttcn

and in My_can_matrix change as below:

type record MESSAGE_TESTFRAME0
{
        BIT11_MSB     test_sig_11_bit_bitstring_lsb_coded,
        BIT5_MSB      test_sig_5_bit_bitstring_lsb_coded

} with {variant "FIELDORDER(msb)"
         variant (test_sig_11_bit_bitstring_lsb_coded) "BITORDERINFIELD(lsb)" 
         variant (test_sig_5_bit_bitstring_lsb_coded)  "BITORDERINFIELD(lsb)"
}

and it should work fine.

type record MESSAGE_EXTENDEDFRAME1
and
type record MESSAGE_TESTFRAME3
need empty variants

Please use the attached files with no unjustified changes.

see attached log too.

BR Elemer



Re: TTCN Titan Testport for socketCAN [message #1754580 is a reply to message #1754531] Mon, 20 February 2017 14:24 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

we had a similar problem earlier with something like:


type bitstring Priority length(3)
with {
variant "ALIGN(right)";
variant "FIELDLENGTH(6)"
}

type record J1939 { // Error & RTR Frames are not considered here
  //PGN   pgn optional,
  //BIT3           ignore,
  Priority       prio,
  BIT1           res, 
  BIT1           dp
} with { variant "FIELDORDER(msb)" }




producing a wrong encoding ;

With the below additions:

type bitstring Priority length(3)
with {
variant "ALIGN(right)";
variant "FIELDLENGTH(6)"
variant "BITORDER(msb)" 
}

type record J1939 { // Error & RTR Frames are not considered here
  //PGN   pgn optional,
  //BIT3           ignore,
  Priority       prio,
  BIT1           res, 
  BIT1           dp
} with { variant "FIELDORDER(msb)" 
         variant(prio) "BITORDERINFIELD(msb)"
}


the right encoding results.


Best regards
Elemer



Re: TTCN Titan Testport for socketCAN [message #1773050 is a reply to message #1754580] Wed, 20 September 2017 19:54 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

when running my TTCN-code with latest titan compiler I get some errors I'd like to discuss:

Issue 1:

../src/General_Types.ttcn: In TTCN-3 module `General_Types':
 ../src/General_Types.ttcn:245.3-41: In type definition `Verdicttypes':
  ../src/General_Types.ttcn:245.50-59: error: No encoding rules defined for type `@General_Types.Verdicttypes'
 ../src/General_Types.ttcn:247.3-40: In type definition `VerdicttypeSet':
  ../src/General_Types.ttcn:247.49-58: error: No encoding rules defined for type `@General_Types.VerdicttypeSet'
 ../src/General_Types.ttcn:375.3-52: In type definition `ListOfDummy_comptype':
  ../src/General_Types.ttcn:375.61-70: error: No encoding rules defined for type `@General_Types.ListOfDummy_comptype'
 ../src/General_Types.ttcn:376.3-46: In type definition `ListOfDummy_CT':
  ../src/General_Types.ttcn:376.55-64: error: No encoding rules defined for type `@General_Types.ListOfDummy_CT'


I have deleted these types in General_Types.ttcn. Where do I find the latest General_Types.ttcn matching to the compiler?

Issue 2:

module IsobusNMMessageTypes {

...

type record N_GP_Response
{
  Function                                  MsgFunction (129),
  OCT1                                      requestedParametrics [6 .. 255]
  // Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
  // this is the easiest way to handle it
} with {
  variant "" }
 
type record N_SP_Response
{
  Function                                  MsgFunction (132),
  PortPair                                  portPair, 
  OCT1                                      requestedParametrics [5 .. 255]
  // Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
  // this is the easiest way to handle it
} with {
  variant "" }

.....

}with { encode "RAW" }


With the following error message:

IsobusNMMessageTypes.ttcn: In TTCN-3 module `IsobusNMMessageTypes':
IsobusNMMessageTypes.ttcn:269.1-275.1: In type definition `N_GP_Response':
IsobusNMMessageTypes.ttcn:276.3-12: error: No encoding rules defined for type `@IsobusNMMessageTypes.N_GP_Response'
IsobusNMMessageTypes.ttcn:300.1-307.1: In type definition `N_SP_Response':
IsobusNMMessageTypes.ttcn:308.3-12: error: No encoding rules defined for type `@IsobusNMMessageTypes.N_SP_Response'
IsobusNMMessageTypes.ttcn:377.1-400.1: In type definition `NetworkMessage':
IsobusNMMessageTypes.ttcn:401.7-422.64: error: No encoding rules defined for type `@IsobusNMMessageTypes.NetworkMessage'

Seems to me that RAW encoding of records containing sets of variable size like:

OCT1                                      requestedParametrics [6 .. 255]


is currently not supported. When removing those lines , the code compiled.
Re: TTCN Titan Testport for socketCAN [message #1773073 is a reply to message #1773050] Thu, 21 September 2017 06:57 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael, good to have you back.

-regarding the first issue: we are restructuring the whole codec generation part of Titan in a way that will not be backwards compatible;
the scope of the exercise is to introduce multiple encoding as per the latest version of the standard (v 4.9.1)

to keep compatibility , please use the -e compiler switch:
 -e:             enforce legacy handling of 'encode' and 'variant' attributes
 


-as for the second issue , there are a number of unimplemented subtypings in Titan, this seems to be one of them; let me check and come back to you.

My suggestion is you move verification from types to templates and possibly to codec level as a temporary measure.



Best regards
Elemer



Re: TTCN Titan Testport for socketCAN [message #1773076 is a reply to message #1773073] Thu, 21 September 2017 07:45 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hello Elemer,

Quote:

My suggestion is you move verification from types to templates and possibly to codec level as a temporary measure.


Could you please explain this above a little bit more .

Michael
Re: TTCN Titan Testport for socketCAN [message #1773079 is a reply to message #1773076] Thu, 21 September 2017 09:05 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

sure,


First a few small issues:

-It's practical to have field names in small letters:

type record N_GP_Response
{
Function msgFunction (129), (instead of MsgFunction)
OCT1 requestedParametrics [6 .. 255]
// Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
// this is the easiest way to handle it
}

- range subtype restrictions should be formulated as

OCT1 requestedParametrics ('06'O .. 'FF'O) (not OCT1 requestedParametrics [6 .. 255] )

(please be aware of the paranthesis usage as well)

If you do that , than the compiler will tell you

 Subtyping.ttcn:6.1-12.1: In type definition `N_GP_Response':
  Subtyping.ttcn:9.3-75: In record field `requestedParametrics':
   Subtyping.ttcn:9.3-6: error: Range subtyping is not allowed for type `octetstring' 




there are several independent (not necessarily equivalent though) levels of verification possible in Titan:
-types
-templates
-codecs

If a rule cannot be expressed on subtyping level that it should be sought to express the same rule on another level:

for instance


template  N_SP_Response t_N_SP_Response_illegal_value :=
{
msgFunction:=....
portPair:=...
requestedParametrics := ('00'O, '01'O, '02'O, '03'O, '04'O, '05'O) 
}



expresses the same restriction on template level as
:
  OCT1                                       requestedParametrics ('06'O .. 'FF'O)
:


on type level

I don't have a generic recipe for these cases , but you get the idea.


Best regards
Elemer






[Updated on: Thu, 21 September 2017 10:48]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1773482 is a reply to message #1773079] Thu, 28 September 2017 14:08 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elmer,

when using octetstring instead of OCT1 the subtypining seems to work:

type record N_GP_Response
{
  Function                                  msgFunction (129),
  octetstring                               requestedParametrics [6 .. 255]
  // Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
  // this is the easiest way to handle it
} with {
  variant "" }


Re: TTCN Titan Testport for socketCAN [message #1773483 is a reply to message #1773482] Thu, 28 September 2017 14:21 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

-first and foremost , I have checked and the standard does not allow for octetstring range subtyping;

see 6.1.2.3 Ranges
TTCN-3 permits the specification of range constraints for the types integer, charstring, universal charstring and float (or derivations of these types).

Octetstring is not here.

-secondly , your declaration is not about subtyping, you declare an array of octetstrings of size min 6 and max 255, see 6.2.7 Arrays




Best regards
Elemer
Re: TTCN Titan Testport for socketCAN [message #1773494 is a reply to message #1773483] Thu, 28 September 2017 15:33 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Ok. How do you declare a list of bytes min 6 and max 255 bytes and use the RAW codec for encoding / decoding.
Is there a way?
Re: TTCN Titan Testport for socketCAN [message #1773498 is a reply to message #1773494] Thu, 28 September 2017 15:41 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Is this the way to go:

type record N_GP_Response
{
  Function                                  msgFunction (129),
  record length (6..255) of OCT1            requestedParametrics
  // Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
  // this is the easiest way to handle it
} with {
  variant "" }
Re: TTCN Titan Testport for socketCAN [message #1773542 is a reply to message #1773498] Fri, 29 September 2017 05:56 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
HI Michael,
this seems about right,

please let me know how it works.

Best regards
Elemer


Re: TTCN Titan Testport for socketCAN [message #1773682 is a reply to message #1773542] Mon, 02 October 2017 19:13 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

encoding and decoding works:

MTC@Donald: encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000001'B, res := '1'B, dp := '0'B, pf := '0A'O ("\n"), ps := '0B'O ("\v"), sa := '0C'O ("\f"), comp := '0A0000'O }, can_pdu := { networkMessage := { n_SP_Response := { msgFunction := 132, portPair := { fromPort := port_3 (3), toPort := port_4 (4) }, requestedParametrics := { '01'O, '02'O, '03'O, '04'O, '05'O, '06'O, '07'O ("\a") } } } } }
MTC@Donald: encode_CAN_frame_j1939mod(): Stream after encoding: '060A0B0CED000084030401020304050607'O
MTC@Donald: '06ED0B0C84030401020304050607'O
MTC@Donald: encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000001'B, res := '1'B, dp := '0'B, pf := '0A'O ("\n"), ps := '0B'O ("\v"), sa := '0C'O ("\f"), comp := '0A0000'O }, can_pdu := { networkMessage := { n_SP_Response := { msgFunction := 132, portPair := { fromPort := port_3 (3), toPort := port_4 (4) }, requestedParametrics := { '01'O, '02'O, '03'O, '04'O, '05'O, '06'O, '07'O ("\a") } } } } }
MTC@Donald: encode_CAN_frame_j1939mod(): Stream after encoding: '060A0B0CED000084030401020304050607'O
MTC@Donald: decode_CAN_frame_j1939mod(): Stream before decoding: '06ED0B0CED000084030401020304050607'O
MTC@Donald: decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: { can_j1939 := { prio := '000001'B, res := '1'B, dp := '0'B, pf := 'ED'O, ps := '0B'O ("\v"), sa := '0C'O ("\f"), comp := 'ED0000'O }, can_pdu := { networkMessage := { n_SP_Response := { msgFunction := 132, portPair := { fromPort := port_3 (3), toPort := port_4 (4) }, requestedParametrics := { '01'O, '02'O, '03'O, '04'O, '05'O, '06'O, '07'O ("\a") } } } } }
MTC@Donald: { can_j1939 := { prio := '000001'B, res := '1'B, dp := '0'B, pf := 'ED'O, ps := '0B'O ("\v"), sa := '0C'O ("\f") }, can_pdu := { networkMessage := { n_SP_Response := { msgFunction := 132, portPair := { fromPort := port_3 (3), toPort := port_4 (4) }, requestedParametrics := { '01'O, '02'O, '03'O, '04'O, '05'O, '06'O, '07'O ("\a") } } } } }


with:

testcase tc_encdec_networkMessage_N_SP_Response_pdu_with_template() runs on MTC_CT // using a template
{
  template CAN_frame_j1939 t_CAN_frame_j1939 :=  t_message ( '000001'B, '1'B, '0'B, '0A'O, '0B'O, '0C'O , 
  t_N_SP_Response_pdu(port_3, port_4, {'01'O,'02'O,'03'O,'04'O,'05'O,'06'O,'07'O}))
  log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
  log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
}


 template CAN_frame_j1939 t_message(Isobus.Priority prio_param, BIT1 res_param, BIT1 dp_param, 
 OCT1 pf_param, OCT1 ps_param, SourceAddress sa_param, template AnyIsoBusPdu t_can_pdu) 
 := { can_j1939 := {
   prio := prio_param, 
   res := res_param, 
   dp  := dp_param,
   pf  := pf_param,
   ps  := ps_param,
   sa  := sa_param},
   can_pdu := t_can_pdu
 }


template N_SP_Response t_N_SP_Response(template e_PortNumber t_fromPort, 
                                        template e_PortNumber t_toPort, 
                                        template RequestedParametrics requestedParametrics_param) := {  
   msgFunction := 132,
   portPair := {fromPort := t_fromPort, toPort := t_toPort},
   requestedParametrics := requestedParametrics_param
 }


and

type  record length (5..255) of OCT1 RequestedParametrics


type record N_SP_Response
{
  Function                                  msgFunction (132),
  PortPair                                  portPair, 
  RequestedParametrics                      requestedParametrics
  // Note: If total length below 8 bytes shall be padded to 8 bytes with reserved ('FF'O) within RequestedParametrics
  // this is the easiest way to handle it
} with {
  variant "" }


I had to define the type "RequestedParametrics" in the record N_SP_Response, as otherwise I was not able to use it in the template definition.

As this did not work, unsure if it should work:

template N_SP_Response t_N_SP_Response(template e_PortNumber t_fromPort, 
                                        template e_PortNumber t_toPort, 
                                        template record length (5..255) of OCT1 requestedParametrics_param // error, this line does not work
) := {  
   msgFunction := 132,
   portPair := {fromPort := t_fromPort, toPort := t_toPort},
   requestedParametrics := requestedParametrics_param
 }


[Updated on: Mon, 02 October 2017 19:54]

Report message to a moderator

Re: TTCN Titan Testport for socketCAN [message #1773694 is a reply to message #1773682] Tue, 03 October 2017 06:40 Go to previous message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
HI Michael,
thank you for your feedback.

the standard does not allow for this declaration style; however , if you must shy away from nominating the field type, you can use:
template N_SP_Response t_N_SP_Response(template e_PortNumber t_fromPort, 
                                        template e_PortNumber t_toPort, 
                                        template N_SP_Response.requestedParametrics requestedParametrics_param 
) := {  
   msgFunction := 132,
   portPair := {fromPort := t_fromPort, toPort := t_toPort},
   requestedParametrics := requestedParametrics_param
 }



which I think is just as good.


BR

Elemer
Previous Topic:Fuzzing of BER-encoded protocols in Titan
Next Topic:Logging in Eclipse Titan part III: Custom logger plug-ins
Goto Forum:
  


Current Time: Thu Mar 28 22:59:34 GMT 2024

Powered by FUDForum. Page generated in 0.15422 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top