Home » Eclipse Projects » Eclipse Titan » TTCN Titan Testport for socketCAN(Testport for CAN-bus)
| |
Re: TTCN Titan Testport for socketCAN [message #1722791 is a reply to message #1722788] |
Tue, 09 February 2016 08:10 |
|
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 #1739616 is a reply to message #1739565] |
Wed, 03 August 2016 10:19 |
|
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 |
Michael Josenhans 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 |
|
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 #1739972 is a reply to message #1739955] |
Sat, 06 August 2016 09:39 |
|
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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
|
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 |
|
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 |
|
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 #1740586 is a reply to message #1740552] |
Mon, 15 August 2016 22:28 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
|
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 #1741034 is a reply to message #1741006] |
Mon, 22 August 2016 13:27 |
|
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 317 times)
|
|
|
Re: TTCN Titan Testport for socketCAN [message #1741043 is a reply to message #1741034] |
Mon, 22 August 2016 14:05 |
|
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 #1741103 is a reply to message #1741085] |
Tue, 23 August 2016 07:02 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 #1743844 is a reply to message #1743843] |
Tue, 20 September 2016 08:41 |
|
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 |
|
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 |
Michael Josenhans 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 386 times) -
Attachment: bcm.h
(Size: 3.90KB, Downloaded 290 times) -
Attachment: SocketCAN_PT.cc
(Size: 54.49KB, Downloaded 319 times) -
Attachment: raw.h
(Size: 2.71KB, Downloaded 291 times)
|
|
|
Re: TTCN Titan Testport for socketCAN [message #1744077 is a reply to message #1743935] |
Thu, 22 September 2016 08:46 |
|
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 346 times) -
Attachment: can.h
(Size: 7.53KB, Downloaded 492 times) -
Attachment: raw.h
(Size: 2.71KB, Downloaded 325 times)
|
|
|
Re: TTCN Titan Testport for socketCAN [message #1744150 is a reply to message #1744077] |
Thu, 22 September 2016 18:16 |
Michael Josenhans 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 |
|
Hi MIchael,
sorry, you are right, I managed to confuse myself with the header files.
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 310 times) -
Attachment: can.h
(Size: 3.25KB, Downloaded 548 times) -
Attachment: raw.h
(Size: 0.29KB, Downloaded 337 times)
|
|
|
Re: TTCN Titan Testport for socketCAN [message #1744322 is a reply to message #1744188] |
Sun, 25 September 2016 10:08 |
Michael Josenhans 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 |
|
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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 #1745308 is a reply to message #1745169] |
Fri, 07 October 2016 12:01 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 #1745553 is a reply to message #1745502] |
Wed, 12 October 2016 12:41 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 |
|
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
BR Elemer
|
|
|
Re: TTCN Titan Testport for socketCAN [message #1746047 is a reply to message #1745757] |
Thu, 20 October 2016 19:11 |
Michael Josenhans 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 |
|
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 |
|
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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
|
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 |
|
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 |
Michael Josenhans 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 |
|
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 |
Michael Josenhans 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 |
|
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 #1746732 is a reply to message #1746679] |
Thu, 03 November 2016 19:21 |
|
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 |
|
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 #1746830 is a reply to message #1746804] |
Sat, 05 November 2016 09:46 |
|
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 |
Michael Josenhans 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 |
|
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 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 #1748467 is a reply to message #1746838] |
Wed, 23 November 2016 11:51 |
|
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 #1749088 is a reply to message #1749087] |
Thu, 01 December 2016 17:41 |
Michael Josenhans 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 |
Michael Josenhans 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 |
|
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 #1751174 is a reply to message #1751059] |
Thu, 05 January 2017 11:42 |
|
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 #1752468 is a reply to message #1752432] |
Tue, 24 January 2017 07:52 |
|
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 #1754421 is a reply to message #1754420] |
Fri, 17 February 2017 15:16 |
Michael Josenhans 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 |
|
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 #1754481 is a reply to message #1754479] |
Sat, 18 February 2017 14:42 |
|
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 |
Michael Josenhans 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 |
Michael Josenhans 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 |
|
Hi Michael,
well, Titan does what is instructed, most of the time at least
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 |
|
Hi MIchael,
so if I understand correctly , in the encoding/sending direction you want to obtain this binary
and in the receiving| decoding direction from the same binary
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 #1754524 is a reply to message #1754523] |
Sun, 19 February 2017 13:31 |
Michael Josenhans 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 |
|
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...
BR
Elemer
|
|
| |
Re: TTCN Titan Testport for socketCAN [message #1754531 is a reply to message #1754525] |
Sun, 19 February 2017 15:25 |
|
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 |
|
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 #1773073 is a reply to message #1773050] |
Thu, 21 September 2017 06:57 |
|
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 #1773079 is a reply to message #1773076] |
Thu, 21 September 2017 09:05 |
|
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 #1773483 is a reply to message #1773482] |
Thu, 28 September 2017 14:21 |
|
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 #1773682 is a reply to message #1773542] |
Mon, 02 October 2017 19:13 |
Michael Josenhans 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 |
|
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
|
|
|
Goto Forum:
Current Time: Mon Dec 30 17:26:53 GMT 2024
Powered by FUDForum. Page generated in 0.35899 seconds
|