Commit 5c8e8be1 authored by Lenard Nagy's avatar Lenard Nagy
Browse files

R4A version of SocketCAN test port


Signed-off-by: Lenard Nagy's avatarLenard Nagy <lenard.nagy@ericsson.com>
parent d9eb6042
# titan.TestPorts.SocketCANasp
# compiled with: Titan CRL 113 200/6 R5A
# GCC 7.3.0 Using OpenSSL 1.0.2n
# titan.TestPorts.SocketCANasp
Main project page:
......@@ -22,28 +19,33 @@ http%3A%2F%2Fwww.can-cia.de%2Ffileadmin%2Fresources%2Fdocuments%2Fproceedings%2F
http://www.can-cia.de/fileadmin/resources/documents/proceedings/2012_hartkopp.pdf
http://v2.can-newsletter.org/uploads/media/raw/46c15d02e1fdd3b04e671693ec548ff7.pdf
# See file: src/initscript.sh:
# See file: demo/initscript.sh:
#--------------------------------------
#!/bin/bash
# create a virtual can interface:
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 up
#!/bin/bash
# Add vcan module to kernel
sudo modprobe vcan
# Setup of virtual can vcan0
sudo ip link add dev vcan0 type vcan
# set it up at as a canfd can interface
# set it up at as a canfd capable can interface
sudo ip link set vcan0 mtu 72
sudo ip link set vcan0 up
# Setup of virtual can vcan1
sudo ip link add dev vcan1 type vcan
sudo ip link set vcan1 up
# or create a physical can interface
# sudo ip link set can0 up type can bitrate 1000000
# example configuration of a physical can bus interface
#sudo ip link set can0 up type can bitrate 1000000
ifconfig
ip a
#--------------------------------------
......@@ -56,10 +58,12 @@ source demo/initscript.sh
make clean; make
ttcn3_start SocketCAN SocketCAN.cfg
or
ttcn3_start SocketCAN CAN_matrix_test.cfg
or to run a certain testcase:
ttcn3_start SocketCAN SocketCAN.cfg SocketCANtest.tc_can_raw1 SocketCANtest.tc_can_bcm1
ttcn3_start SocketCAN SocketCAN.cfg SocketCAN_RAW_test.tc_can_raw_send_and_receive_can_frame SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FILTER
Review the newly created log files in the src directory
and use e.g. Wireshark to trace the CAN interfacce.
......@@ -78,16 +82,22 @@ Notes:
test interfaces for each interface have to be defined in the MTC.
-CAN RAW:
CAN and CANFD has been implemented and tested.
Depending on the availability of the C-code #define CANFD_SUPPORT
in src/SocketCAN_PT.cc CAN-FD support is enabled at compile time.
If you kernel does not have CANFD support comment out the #define CANFD_SUPPORT
the file "src/SocketCAN_PT.cc"
CAN FD has been implemented, however not been tested.
Depending on the availability of the C-code #define "CAN_FD_FRAME"
in /usr/include/linux/can/bcm.h, CAN-FD support is enabled at compile time.
The RAW setsockopt has path coverage. However no test coverage that insures
the setsockopt functionality provided by the kernel is working correctly.
For this purpose in the future might be added additional test cases.
-CAN BCM:
TX_SETUP, TX_DELETE have been tested, TX_READ is known to fail test cases.
The BCM has test coverage for TX_SETUP and TX_DELETE.
Some tests have indicated, that that SocketCAN BCM does not support concurrently
active BCM channels.
The BCM has test coverage for TX_SETUP and TX_DELETE. However no test coverage
that insures the BCM functionality provided by the kernel is working correctly.
For this purpose in the future might be added additional test cases.
Return values other than the error code by the BCM are not yet supported.
BCM wth CAN FD frames has not been tested yet.
-ISOTP:
Iso TP functionality has been added, however currently no options like padding
......@@ -103,13 +113,45 @@ Notes:
There is an endlessly running test case:
ttcn3_start SocketCAN SocketCAN.cfg Isotptest.tc_Isotp_Example001
-CAN J1939:
Configure CAN J1939 as following (requires Kernel 5.4 and compiled with can-j1939 kernel module):
sudo modprobe vcan
sudo ip link add vcan0 type vcan
sudo ip link set vcan0 up
sudo modprobe can-j1939
For the following test cases, the messages are so huge that screen output of the log file takes too long.
Thus comment out as following the following lines in J1939.cfg:
//FileMask := LOG_ALL | DEBUG | MATCHING
//ConsoleMask := LOG_ALL | DEBUG | MATCHING
ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_j1939_send_and_receive_message
ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_j1939_send_and_receive_message_parallel
Here above lines can be commented in:
ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_f_j1939_address_claim
ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_f_j1939_request_for_address_claimed
-Merging of logfiles:
To merge the logfies from multiple Parallel Test Componets (PTCs) from a
single run in timely order into sigle file, run in demo directory:
$ ./merge.sh
the merged and pretty printed log file is found in "demo/log_merged_pretty.txt"
single run in timely order into sigle file, run:
ttcn3_logmerge -o log_merged.txt *.log
The merged log-file is found at log_merged.txt
-Dunping CAN Frames using SocketCAN:
-Pretty printing the log file:
ttcn3_logformat -o log_merged_format.log log_merged.log
-Dumping CAN Frames using SocketCAN:
To dump all received can frames of e.g. "vcan0" run a seperate terminal:
$ candump "vcan0"
$ candump -td -d "vcan0"
-Spying J1939 CAN-Frames using SocketCAN (only for SocketCAN J1939):
$ j1939spy -td -P -b 4193977 vcan0
- Runnung ttcn compiler and merging logs:
rm *.log;make;ttcn3_start SocketCAN J1939.cfg J1939_Isobus_test.tc_can_j1939_IsobusVtEcuSimulation ;ttcn3_logmerge -o log_merged.log *.log;ttcn3_logformat -o log_merged_format.log log_merged.log;kate log_merged_format.log
2004 history | grep ttcn
......@@ -15,58 +15,27 @@
module Isobus {
import from General_Types all
import from Can all
import from IsobusCMMessageTypes all
import from IsobusNMMessageTypes all
import from IsobusVTMessageTypes all
import from J1939 all
// Note:
// SocketCAN Error frames are not considered here
// SocketCAN RTR frames are not considered here
// SocketCAN Basic frames are not considered here
external function encode_CAN_frame_j1939mod(in CAN_frame_j1939mod pdu) return octetstring
external function f_encode_J1939_message(in J1939_messageWithPGN pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function decode_CAN_frame_j1939mod(in octetstring data) return CAN_frame_j1939mod
external function f_decode_J1939_message(in octetstring data) return J1939_messageWithPGN
with { extension "prototype(convert) decode(RAW)" }
const octetstring ISOBUS_PRIORITY_MASK := '1C000000'O;
const octetstring ISOBUS_RESERVED_MASK := '02000000'O;
const octetstring ISOBUS_DATAPAGE_MASK := '01000000'O;
const octetstring ISOBUS_PDUFORMAT_MASK := '00FF0000'O;
const octetstring ISOBUS_PDUSPECIFIC_MASK := '0000FF00'O;
const octetstring ISOBUS_SOURCEADDRESS_MASK := '000000FF'O;
type J1939_Priority Priority
type record J1939_header { // 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)" }
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 J1939PDU_with_NAME
{
J1939_ADDR addr,
J1939_NAME name,
J1939_messageWithPGN pdu
} with {variant "" };
type union AnyIsoBusPdu {
type union Isobus_message {
ETP_DT etp_dt, // extended TP data transfer
ETP_CM etp_cm, // extended TP connection management
VT2ECU vt2ecu, // Message Virtual Terminal (VT) to ECU
......@@ -75,240 +44,35 @@ type union AnyIsoBusPdu {
TP_DT tp_dt, // TP data transfer
TP_CM tp_cm, // TP connection management
NetworkMessage networkMessage, // Network Message according ISO 11873-4
CannotClaimSourceAddress cannotClaimSourceAddress,
AddressClaimed addressClaimed,
//CannotClaimSourceAddress cannotClaimSourceAddress,
//AddressClaimed addressClaimed,
AddressClaimed addressClaimedOrCannotClaimSourceAddress,
CommandedAddress commandedAddress
// other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }
type record CAN_frame_j1939 {
J1939_header can_j1939,
AnyIsoBusPdu can_pdu
}with { variant "" }
type record CAN_frame_j1939mod {
J1939mod can_j1939,
AnyIsoBusPdu can_pdu
}with {
variant (can_pdu) "CROSSTAG(
etp_dt, can_j1939.comp = 'C70000'O; //199
etp_cm, can_j1939.comp = 'C80000'O; //200
vt2ecu, can_j1939.comp = 'E60000'O; //230
ecu2vt, can_j1939.comp = 'E70000'O; //231
requestForAddressClaimed, can_j1939.comp = 'EA0000'O; //234
tp_dt, can_j1939.comp = 'EB0000'O; //235
tp_cm, can_j1939.comp = 'EC0000'O; //236
networkMessage, can_j1939.comp = 'ED0000'O; //237
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!!!!!!
}
function j1939frame2can(in CAN_frame_j1939 p_can_frame_j1939, in Priority p_priority, in DestinationAddress p_da, in SourceAddress p_sa) return CAN_frame {
var CAN_frame v_can_frame
v_can_frame.can_id := pdu1_j1939id2canid(p_can_frame_j1939.can_j1939, p_priority, p_da, p_sa)
// v_can_frame.can_pdu := encode_AnyIsoBusPdu(p_can_frame_j1939.can_pdu)
v_can_frame.can_pdu := substr(f_encode_CAN_frame_j1939(p_can_frame_j1939),0,3)//strip 3 byte header
return v_can_frame
}
function pdu1_j1939id2canid(in J1939_header p_j1939, in Priority p_priority, in DestinationAddress p_da, in SourceAddress p_sa) return CAN_id{
var CAN_id v_can_id
v_can_id := bit2oct(oct2bit(p_sa) or4b (oct2bit(p_da) << 8) or4b (oct2bit(p_j1939.pf) << 16) or4b ((p_j1939.dp) << 24) or4b
((p_j1939.res) << 25) or4b (int2bit(p_priority, 32) << 26))
return v_can_id
}
/*
function j1939id2canid(in J1939 p_j1939) return CAN_id{
var CAN_id v_can_id
v_can_id := (p_j1939.sa << 0) or4b (p_j1939.ps << 8) or4b (p_j1939.pf << 16) or4b bit2oct(p_j1939.dp << 24) or4b
bit2oct(p_j1939.res << 25) or4b bit2oct(p_j1939.prio << 26)
return v_can_id
}
*/
function j1939id2canid(in J1939_header p_j1939) return CAN_id{
var CAN_id v_can_id
v_can_id := int2oct(
oct2int(p_j1939.sa) + oct2int(p_j1939.ps)*256 + oct2int(p_j1939.pf) * 256 * 256 +
bit2int(p_j1939.dp) * 256 * 256 * 256 + bit2int(p_j1939.res) * 256 * 256 * 256 * 2 +
p_j1939.prio * 256 * 256 * 256 * 2 * 2,
4 )
return v_can_id
}
//---------------------------------------------------------------------------------------
function can2j1939frame(CAN_frame p_can_frame) return CAN_frame_j1939 {
//---------------------------------------------------------------------------------------
var CAN_frame_j1939 v_can_frame_j1939
//log("can_id", p_can_frame.can_id)
//log("can_pdu", p_can_frame.can_pdu)
v_can_frame_j1939:=f_decode_CAN_frame_j1939(p_can_frame.can_id& p_can_frame.can_pdu)
//log("Higher layer octet pdustring: ", v_can_frame_j1939)
return v_can_frame_j1939
}
function canid2j1939(in CAN_id p_can_id) return J1939_header {
//---------------------------------------------------------------------------------------
var bitstring v_can_id_bitstring:= oct2bit(p_can_id)
var J1939_header v_j1939
v_j1939.prio :=bit2int(substr(v_can_id_bitstring, 0, 6)); //3 ,3
v_j1939.res :=v_can_id_bitstring[6];
v_j1939.dp :=v_can_id_bitstring[7];
v_j1939.pf :=p_can_id[1];//(p_can_id and4b ISOBUS_PDUFORMAT_MASK) >> 2 // shift 16 bits = 2 octets
v_j1939.ps :=p_can_id[2];// (p_can_id and4b ISOBUS_PDUSPECIFIC_MASK) >> 1 // shift 8 bits = 1 octet
v_j1939.sa :=p_can_id[3];//(p_can_id and4b ISOBUS_SOURCEADDRESS_MASK)
return v_j1939
}
//********************************************************************************-
//---------------------------------------------------------------------------
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;}
//log("replace(p_os,4,0,v_os) :",replace(p_os,4,0,v_os))
return replace(p_os,4,0,v_os)//insert aux header
}
//---------------------------------------------------------------------------
function f_remove_aux_hdr(in octetstring p_os) return octetstring
//---------------------------------------------------------------------------
{
//log("p_os :",p_os)
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];
}
//log("p_os :",p_os)
//log("replace(p_os,4,3,''O) :",replace(p_os,4,3,''O))
return replace(p_os,4,3,''O); //remove aux header
}
//---------------------------------------------------------------------------
function f_map_mod2frame(in CAN_frame_j1939mod p_frame) return CAN_frame_j1939
//---------------------------------------------------------------------------
{
var CAN_frame_j1939 v_CAN_frame_j1939
v_CAN_frame_j1939.can_pdu:=p_frame.can_pdu;
v_CAN_frame_j1939.can_j1939.prio:=p_frame.can_j1939.prio;
v_CAN_frame_j1939.can_j1939.res:=p_frame.can_j1939.res;
v_CAN_frame_j1939.can_j1939.dp:=p_frame.can_j1939.dp;
v_CAN_frame_j1939.can_j1939.pf:=p_frame.can_j1939.pf;
v_CAN_frame_j1939.can_j1939.ps:=p_frame.can_j1939.ps;
v_CAN_frame_j1939.can_j1939.sa:=p_frame.can_j1939.sa;
//log("v_CAN_frame_j1939 :",v_CAN_frame_j1939)
return v_CAN_frame_j1939
}
//---------------------------------------------------------------------------
function f_map_frame2mod(in CAN_frame_j1939 p_frame) return CAN_frame_j1939mod
//---------------------------------------------------------------------------
{
var CAN_frame_j1939mod v_CAN_frame_j1939mod
v_CAN_frame_j1939mod.can_pdu:=p_frame.can_pdu;
v_CAN_frame_j1939mod.can_j1939.prio:=p_frame.can_j1939.prio;
v_CAN_frame_j1939mod.can_j1939.res:=p_frame.can_j1939.res;
v_CAN_frame_j1939mod.can_j1939.dp:=p_frame.can_j1939.dp;
v_CAN_frame_j1939mod.can_j1939.pf:=p_frame.can_j1939.pf;
v_CAN_frame_j1939mod.can_j1939.ps:=p_frame.can_j1939.ps;
v_CAN_frame_j1939mod.can_j1939.sa:=p_frame.can_j1939.sa;
if (p_frame.can_j1939.pf == 'EE'O)
{
if (p_frame.can_j1939.ps == 'D8'O) {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&p_frame.can_j1939.ps&'00'O;
} else if (p_frame.can_j1939.ps == 'FF'O) {
if (p_frame.can_j1939.sa == 'FE'O) {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&p_frame.can_j1939.ps&p_frame.can_j1939.sa
} else {//??
v_CAN_frame_j1939mod.can_j1939.comp:=p_frame.can_j1939.pf&'0000'O;
}
} else {//??
v_CAN_frame_j1939mod.can_j1939.comp:=p_frame.can_j1939.pf&'0000'O;
}
} else {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&'0000'O;
}
//log("v_CAN_frame_j1939mod :",v_CAN_frame_j1939mod)
return v_CAN_frame_j1939mod;
}
//---------------------------------------------------------------------------
function f_encode_CAN_frame_j1939(in CAN_frame_j1939 pdu) return octetstring
//---------------------------------------------------------------------------
{
return f_remove_aux_hdr(encode_CAN_frame_j1939mod(f_map_frame2mod(pdu)))
type record J1939_messageWithPGN {
J1939_PGN pgn,
Isobus_message pdu
}
//---------------------------------------------------------------------------
function f_decode_CAN_frame_j1939(in octetstring data) return CAN_frame_j1939
//---------------------------------------------------------------------------
{
log("f_insert_aux_hdr(data)", f_insert_aux_hdr(data));
return f_map_mod2frame(decode_CAN_frame_j1939mod(f_insert_aux_hdr(data)))
with {
variant (pdu) "CROSSTAG(
etp_dt, pgn = '00C700'O; //199
etp_cm, pgn = '00C800'O; //200
vt2ecu, pgn = '00E600'O; //230
ecu2vt, pgn = '00E700'O; //231
requestForAddressClaimed, pgn = '00EA00'O; //234
tp_dt, pgn = '00EB00'O; //235
tp_cm, pgn = '00EC00'O; //236
networkMessage, pgn = '00ED00'O; //237
// cannotClaimSourceAddress, pgn = '00EEFFFE'O; //238 where the SA is 'FE'O
// addressClaimed, pgn = '00EEFFXX'O; //238 where the SA is XX != FE!
addressClaimedOrCannotClaimSourceAddress, pgn = '00EEFF'O; //238, the SA determies
// if it is addressClaimed (SA != 'FE'O)
// or it is cannotClaimSourceAddress (SA == 'FE'O)
commandedAddress, pgn = '00FED8'O)" //254
}
......
......@@ -9,8 +9,7 @@ module IsobusMessageTypes {
type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(24), COMP(nosign), BYTEORDER(last)" };
type INT24nb PGN
type bitstring BIT21 length(21) with { variant "FIELDLENGTH(21)" };
type integer INT2 (0..65535)
with { variant "FIELDLENGTH(16)" };
......
......@@ -5,6 +5,7 @@
module IsobusNMMessageTypes {
import from J1939 all
import from General_Types all
import from IsobusMessageTypes all
......@@ -20,39 +21,22 @@ with {
variant "FIELDLENGTH(6)"
}
type BIT1 SelfConfigurableAddressBits
type BIT3 IndustryGroupBits
type BIT4 DeviceClassInstanceBits
type BIT7 DeviceClassBits
type BIT1 ReservedBits
type BIT8 FunctionBits
type BIT5 FunctionInstanceBits
type BIT3 ECUInstanceBits
type BIT11 ManufacturerCodeBits
type BIT21 IdentityNumberBits
type record NAME {
SelfConfigurableAddressBits selfConfigurableAddressValue,
IndustryGroupBits industryGroupValue,
DeviceClassInstanceBits deviceClassInstanceValue,
DeviceClassBits deviceClassValue,
ReservedBits reserveValued,
FunctionBits functionValue,
FunctionInstanceBits functionInstanceValue,
ECUInstanceBits ecuInstancceValue,
ManufacturerCodeBits manufacturerCodeValue,
IdentityNumberBits identityNumberBits
} with { variant "FIELDORDER(msb)" }
type record CannotClaimSourceAddress
{
NAME name
J1939_NAME_RECORD_REVERSE_BYTE_ENCODING name
// or alternatively
// J1939_NAME name
} with { variant "" }
type record AddressClaimed
{
NAME name
J1939_NAME_RECORD_REVERSE_BYTE_ENCODING name
// or alternatively
// J1939_NAME name
} with { variant "" }
type record RequestForAddressClaimed {
......@@ -62,8 +46,10 @@ type record RequestForAddressClaimed {
type record CommandedAddress {
NAME name,
SourceAddress newSourceAddress
J1939_NAME_RECORD_REVERSE_BYTE_ENCODING name,
// or alternatively
// J1939_NAME name
SourceAddress newSourceAddress
} with { variant "" }
// --------- NetworkMessage -------------
......@@ -129,7 +115,7 @@ type record PGNEntry
{
INT1 maxTransferRate,
PGN pgn,
NAME name,
J1939_NAME name,
OCT8 nameQualifier
} with {variant "" };
......@@ -178,7 +164,7 @@ type record N_NTX_Request
type record SA_NAME_pair
{
SourceAddress sourceAddress,
NAME name
J1939_NAME name
} with {variant "" };
type record N_NTX_Response
......@@ -327,7 +313,7 @@ type record N_OC_Request
{
Function msgFunction (192),
PortPair portPair,
NAME nameOfCF
J1939_NAME nameOfCF
} with {
variant "" }
......@@ -335,7 +321,7 @@ type record N_CC_Request
{
Function msgFunction (193),
PortPair portPair,
NAME nameOfCF
J1939_NAME nameOfCF
} with {
variant "" }
......
This diff is collapsed.
This diff is collapsed.
module Isobus_Templates {
import from IsobusMessageTypes all
import from IsobusVTMessageTypes all
import from IsobusCMMessageTypes all
import from IsobusNMMessageTypes all
import from Isobus all
import from General_Types all
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 CAN_frame_j1939 t_network_message(Isobus.Priority prio_param, BIT1 res_param, BIT1 dp_param,
OCT1 pf_param, OCT1 ps_param, SourceAddress sa_param, template IsobusNMMessageTypes.NetworkMessage t_networkMessage)
:= { can_j1939 := {
prio := prio_param,
res := res_param,
dp := dp_param,
pf := pf_param,
ps := ps_param,
sa := sa_param},
can_pdu := {networkMessage := t_networkMessage}
}
template ECU2VT t_GetMemoryReqX( INT3 p_memoryRequired) := {