update 20161117
diff --git a/demo/Isobus.ttcn b/demo/Isobus.ttcn
new file mode 100644
index 0000000..0f7cc29
--- /dev/null
+++ b/demo/Isobus.ttcn
@@ -0,0 +1,326 @@
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: Isobus.ttcn
+// Description: Encoder / Decoder for Isobus message frames
+//
+// Revision R1A
+
+module Isobus {
+import from General_Types all
+import from Can all
+import from IsobusMessageTypes all
+import from IsobusCMMessageTypes all
+import from IsobusNMMessageTypes all
+import from IsobusVTMessageTypes 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
+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)" }
+
+
+
+
+
+
+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 BIT3 Priority
+
+type bitstring Priority length(6)
+with {
+ variant "ALIGN(left)";
+ 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)" }
+
+
+
+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 union AnyIsoBusPdu {
+ TopLevelMessage_VT2ECU_PDU vt2ecu, // Message Virtual Terminal (VT) to ECU
+ TopLevelMessage_ECU2VT_PDU ecu2vt, // Message ECU to Virtual Terminal (VT)
+ RequestForAddressClaimed requestForAddressClaimed,
+ TP_DT tp_dt,
+ TP_CM tp_cm,
+ 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!!!!!!
+}
+
+
+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
+ tp_dt, can_j1939.comp = 'EB0000'O;
+ tp_cm, 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!!!!!!
+}
+
+//---------------------------------------------------------------------------------------
+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 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(bit2int(p_priority), 32) << 26))
+ 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 {
+ var bitstring v_can_id_bitstring
+ var Priority v_priority
+ var BIT1 v_reserved // BIT1
+ var BIT1 v_datapage // BIT1
+ var OCT1 v_pduformat // OCT1
+ var OCT1 v_pduspecifc // OCT1
+ var OCT1 v_sourceaddress // OCT1
+ var PGN v_pgn
+ var J1939 v_j1939
+
+ v_can_id_bitstring := oct2bit(p_can_id)
+ v_priority := substr(v_can_id_bitstring, 3, 3)
+ v_reserved := v_can_id_bitstring[6]
+ v_datapage := v_can_id_bitstring[7]
+ v_pduformat := p_can_id[1] //(p_can_id and4b ISOBUS_PDUFORMAT_MASK) >> 2 // shift 16 bits = 2 octets
+ v_pduspecifc := p_can_id[2] // (p_can_id and4b ISOBUS_PDUSPECIFIC_MASK) >> 1 // shift 8 bits = 1 octet
+ v_sourceaddress := p_can_id[3] //(p_can_id and4b ISOBUS_SOURCEADDRESS_MASK)
+
+ if (oct2int(v_pduformat) < 240) {
+ v_pgn := bit2int(v_reserved)*2*256*256 + bit2int(v_datapage)*256 *256 + oct2int(v_pduformat)*256
+
+ } else {
+ v_pgn := bit2int(v_reserved)*2*256*256 + bit2int(v_datapage)*256 *256 + oct2int(v_pduformat)*256 + oct2int(v_pduspecifc)
+ }
+ v_j1939 := {/*pgn := v_pgn, */prio := v_priority, res := v_reserved, dp := v_datapage, pf := v_pduformat, ps := v_pduspecifc, sa := v_sourceaddress}
+ 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)))
+
+
+}
+//---------------------------------------------------------------------------
+function f_decode_CAN_frame_j1939(in octetstring data) return CAN_frame_j1939
+//---------------------------------------------------------------------------
+{
+
+ return f_map_mod2frame(decode_CAN_frame_j1939mod(f_insert_aux_hdr(data)))
+
+
+}
+
+
+} with { encode "RAW" }
diff --git a/demo/IsobusCMMessageTypes.ttcn b/demo/IsobusCMMessageTypes.ttcn
new file mode 100644
index 0000000..2deddd6
--- /dev/null
+++ b/demo/IsobusCMMessageTypes.ttcn
@@ -0,0 +1,73 @@
+module IsobusCMMessageTypes {
+import from General_Types all
+import from IsobusMessageTypes all
+
+type OCT1 Ctrl
+
+type record RequestToSend{
+ Ctrl ctrl ('10'O),
+ INT2 msgSizeInByte,
+ INT1 totalNumberOfPackets,
+ INT1 maxNoOfPacketsInResponseToCTS,
+ PGN pgnOfMultiPacketMessage
+} with { variant "" };
+
+type record ClearToSend{
+ Ctrl ctrl ('11'O),
+ INT1 totalNumberOfPackets,
+ INT1 nextPacketNumber,
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ PGN pgnOfMultiPacketMessage
+} with { variant "" };
+
+type record EndOfMessageAcknowledgement{
+ Ctrl ctrl ('13'O),
+ INT2 msgSizeInByte,
+ INT1 totalNumberOfPackets,
+ OCT1 reserved5 ('FF'O),
+ PGN pgnOfMultiPacketMessage
+} with { variant "" };
+
+type record ConnectionAbort{
+ Ctrl ctrl ('FF'O),
+ OCT1 connectionAbortReason,
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ PGN pgnOfMultiPacketMessage
+} with { variant "" };
+
+type record BroadcastAnnonce{
+ Ctrl ctrl ('20'O),
+ INT2 msgSizeInByte,
+ INT1 totalNumberOfPackets,
+ OCT1 reserved5 ('FF'O),
+ PGN pgnOfMultiPacketMessage
+} with { variant "" };
+
+type union TP_CM
+{
+ RequestToSend requestToSend,
+ ClearToSend clearToSend,
+ EndOfMessageAcknowledgement endOfMessageAcknowledgement,
+ BroadcastAnnonce broadcastAnnounce,
+ ConnectionAbort connectionAbort
+}
+with {variant "TAG (
+ // put all ECU2VT request messages here
+ requestToSend, ctrl = '10'O;
+ clearToSend, ctrl = '11'O;
+ endOfMessageAcknowledgement, ctrl = '13'O;
+ broadcastAnnounce, ctrl = '20'O;
+ connectionAbort, ctrl = 'FF'O;
+ ) "
+}
+
+
+type record TP_DT{
+ INT1 seq_no,
+ OCT7 data
+} with { variant "" }
+
+} with { encode "RAW" }
diff --git a/demo/IsobusMessageTypes.ttcn b/demo/IsobusMessageTypes.ttcn
new file mode 100644
index 0000000..4742290
--- /dev/null
+++ b/demo/IsobusMessageTypes.ttcn
@@ -0,0 +1,20 @@
+/*
+* Contributors:
+* Michael Josenhans
+*/
+
+module IsobusMessageTypes {
+
+
+type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(24), COMP(nosign), BYTEORDER(last)" };
+type INT24nb PGN
+
+
+
+type integer INT2 (0..65535)
+with { variant "FIELDLENGTH(16)" };
+
+type integer INT3 (0..16777215)
+with { variant "FIELDLENGTH(24)" };
+}
+with { encode "RAW" }
diff --git a/demo/IsobusNMMessageTypes.ttcn b/demo/IsobusNMMessageTypes.ttcn
new file mode 100644
index 0000000..aea1481
--- /dev/null
+++ b/demo/IsobusNMMessageTypes.ttcn
@@ -0,0 +1,38 @@
+/*
+* Contributors:
+* Michael Josenhans
+*/
+
+module IsobusNMMessageTypes {
+
+import from General_Types all
+import from IsobusMessageTypes all
+
+type OCT1 DestinationAddress
+
+type OCT1 PDUFormat
+type OCT1 SourceAddress
+type OCT8 NAME
+
+type record CannotClaimSourceAddress
+{
+ NAME name
+} with { variant "" }
+
+type record AddressClaimed
+{
+ NAME name
+} with { variant "" }
+
+type record RequestForAddressClaimed {
+ PGN pgn
+} with { variant "" }
+
+
+
+type record CommandedAddress {
+ NAME name,
+ SourceAddress newSourceAddress
+} with { variant "" }
+
+}with { encode "RAW" }
diff --git a/demo/IsobusVTMessageTypes.ttcn b/demo/IsobusVTMessageTypes.ttcn
new file mode 100644
index 0000000..aab197d
--- /dev/null
+++ b/demo/IsobusVTMessageTypes.ttcn
@@ -0,0 +1,380 @@
+module IsobusVTMessageTypes {
+
+import from General_Types all
+import from IsobusMessageTypes all
+
+type INT1 VTfunction
+
+type record GetMemoryReq
+{
+ VTfunction vtfunction (194),
+ OCT1 reserved2 ('FF'O),
+ INT3 memoryRequired,
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type enumerated e_GetMemoryResVersionNumber {
+ compliantWithHannoverAgritechnica_2001_limitedfeatureSet (0),
+ compliantWithFDISVersionISO11783_6_2002_E_Final_Draft (1),
+ compliantWithISVersionISO11783_6_2004_E_First_Edition (2),
+ compliantWithISVersionISO11783_6_2010_E_Second_Edition_version_3 (3),
+ compliantWithISVersionISO11783_6_2010_E_Second_Edition_version_4 (4),
+ compliantWithISVersionISO11783_6_2014_E_Third_Edition (5)}
+with {variant "PADDING(octet)" };
+
+type enumerated e_GetMemoryResStatus {
+ thereCanBeEnoughMemory (0),
+ thereIsNotEnoughMemoryAvailable (1)}
+with {variant "PADDING(octet)" }
+
+type record GetMemoryRes
+{
+ VTfunction vtfunction (194),
+ e_GetMemoryResVersionNumber versionNumber,
+ e_GetMemoryResStatus status,
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record GetNumberOfSoftKeysReq
+{
+ VTfunction vtfunction (192),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record GetNumberOfSoftKeysRes
+{
+ VTfunction vtfunction (192),
+ OCT1 navigationSoftKeys_,
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 x_dots,
+ OCT1 y_dots,
+ OCT1 numberOfVirtualSoftKeys_,
+ OCT1 numberOfPhysicalSoftKeys_
+} with { variant "" };
+
+type record GetTextFontDataReq
+{
+ VTfunction vtfunction (195),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+
+type enumerated e_TextFontDataRes_small_font_sizes {
+ font_6x8 (0),
+ font_8x8 (1),
+ font_8x12 (2),
+ font_12x16 (4),
+ font_16x16 (8),
+ font_16x24 (16),
+ font_24x32 (32),
+ font_32x32 (64),
+ reserved (128)
+ }
+with {variant "PADDING(octet)" };
+
+type enumerated e_TextFontDataRes_large_font_sizes {
+ font_32x48 (1),
+ font_48x64 (2),
+ font_64x64 (4),
+ font_64x96 (8),
+ font_96x128 (16),
+ font_128x128 (32),
+ font_128x192 (64),
+ reserved (128)
+ }
+with {variant "PADDING(octet)" }
+
+type enumerated e_TextFontDataRes_type_attribute {
+ normal_text (0),
+ bold_text (1),
+ crossed_out_text (2),
+ underlined_text (4),
+ italics_text (8),
+ inverted_text (16),
+ flash_inverted (32),
+ flash_background_and_foreground (64),
+ proportional_font_rendering_ (128)
+ }
+with {variant "PADDING(octet)"}
+
+type record GetTextFontDataRes
+{
+ VTfunction vtfunction (195),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ e_TextFontDataRes_small_font_sizes small_font_sizes,
+ e_TextFontDataRes_large_font_sizes large_font_sizes,
+ e_TextFontDataRes_type_attribute type_attribute
+} with { variant "" };
+
+type record GetHardwareReq
+{
+ VTfunction vtfunction (199),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+
+type enumerated e_GetHardwareResGraphicType {
+ monochrome (0),
+ colors16 (1),
+ colors256 (2)
+ }
+with {variant "PADDING(octet)"}
+
+type record e_GetHardwareResHardware {
+ boolean touchScreenandPointingEvent,
+ boolean pointingDeviceAndPointingEvent,
+ boolean multipleFrequencyAudioOutput,
+ boolean adjustableVolumeAudioOutput,
+ boolean simultaneousActivationsOfPhysicalSoftKeys,
+ boolean simultaneousActivationsOfButtons,
+ boolean dragOperationViaPointingEvent,
+ boolean intermediateCoordinatesDuringDragOperation
+} with { variant "" };
+
+type record GetHardwareRes
+{
+ VTfunction vtfunction (199),
+ e_GetHardwareResGraphicType graphicType,
+ e_GetHardwareResHardware hardware,
+ INT2 xPixels,
+ INT2 yPixels
+} with { variant "" };
+
+type enumerated e_Codeplane {
+ codeplane0 (0),
+ codeplane1 (1),
+ codeplane2 (2),
+ codeplane3 (3),
+ codeplane4 (4),
+ codeplane5 (5),
+ codeplane6 (6),
+ codeplane7 (7),
+ codeplane8 (8),
+ codeplane9 (9),
+ codeplane10 (10),
+ codeplane11 (11),
+ codeplane12 (12),
+ codeplane13 (13),
+ codeplane14 (14),
+ codeplane15 (15),
+ codeplane16 (16)}
+with {variant "PADDING(octet)"}
+
+
+type record GetSupportedWidecharsReq
+{
+ VTfunction vtfunction (193),
+ e_Codeplane codeplane,
+ OCT2 firstWideCharInInquiryRange,
+ OCT2 lastWideCharInInquiryRange,
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record WideCharRange
+{
+ OCT2 firstWideChar,
+ OCT2 lastWideChar
+} with { variant "" };
+
+type record of WideCharRange WideCharRangeArray
+
+type record GetSupportedWidecharsRes
+{
+ VTfunction vtfunction (193),
+ e_Codeplane codeplane,
+ OCT2 firstWideCharInInquiryRange,
+ OCT2 lastWideCharInInquiryRange,
+ INT1 numberOfRanges,
+ WideCharRangeArray wideCharRangeArray
+} with {
+ variant (numberOfRanges) "LENGTHTO(wideCharRangeArray)";
+ variant (numberOfRanges) "UNIT(elements)"}
+
+type record GetWindowMaskDataReq
+{
+ VTfunction vtfunction (196),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record GetWindowMaskDataRes
+{
+ VTfunction vtfunction (196),
+ OCT1 BackgroundColourVTUserLayoutDataMasks,
+ OCT1 BackgroundColourVTKeyCells,
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record GetSupportedObjectsReq
+{
+ VTfunction vtfunction (197),
+ OCT1 reserved2 ('FF'O),
+ OCT1 reserved3 ('FF'O),
+ OCT1 reserved4 ('FF'O),
+ OCT1 reserved5 ('FF'O),
+ OCT1 reserved6 ('FF'O),
+ OCT1 reserved7 ('FF'O),
+ OCT1 reserved8 ('FF'O)
+} with { variant "" };
+
+type record GetSupportedObjectsRes
+{
+ VTfunction vtfunction (197),
+ INT2 numberOfBytesToFollow,
+ OCT1 supportedObjectTypes
+} with {
+ variant (numberOfBytesToFollow) "LENGTHTO(supportedObjectTypes)";
+ variant (numberOfBytesToFollow) "UNIT(elements)"}
+
+
+type enumerated e_BusyCodes {
+ vtIsBusyUpdatingVisibleMask (0),
+ vtIsBusySavingDataToNonVolatileMemory (1),
+ vtIsBusyExecutingACommand (2),
+ vtIsBusyExecutingAMacro (3),
+ vtIsBusyParsingAnObjectPool (4),
+ reserved (5),
+ auxiliaryControlsLearnModeActive (6),
+ vtIsOutOfMemory (7)}
+with {variant "PADDING(octet)"}
+
+type record VTStatusReq
+{
+ VTfunction vtfunction (254),
+ OCT1 sourceAddressOfActiveWorkingSetMaster,
+ OCT2 objectIDOfTheVisibleDataAlarmMaskOfTheActiveWorkingSet,
+ OCT2 objectIDOfTheVisibleSoftKeyMaskOfTheActiveWorkingSet,
+ e_BusyCodes vtBusyCodes,
+ OCT1 vtFunctionCode
+} with { variant "" };
+
+type record WorkingSetMaintenanceBitMask {
+ boolean InitiatingWorkingSetMaintenance,
+ boolean reserved2 (false),
+ boolean reserved3 (false),
+ boolean reserved4 (false),
+ boolean reserved5 (false),
+ boolean reserved6 (false),
+ boolean reserved7 (false)
+} with { variant "" };
+
+type enumerated e_WorkingSetMaintenanceVersionNumber {
+ reserved0 (0),
+ reserved1 (1),
+ reserved2 (2),
+ compliantWithVTVersion3 (3),
+ compliantWithVTVersion4 (4),
+ compliantWithVTVersion5 (5),
+ compliantWithVTVersion2 (255)}
+with {variant "PADDING(octet)"}
+
+type record WorkingSetMaintenanceReq
+{
+ VTfunction vtfunction (255),
+ 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 { variant "" };
+
+type record DummyVTStatusRes
+{
+ VTfunction vtfunction (254)
+} with { variant "" };
+
+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, vtfunction = 254;
+// put all VT2ECU response messages here
+ getMemoryRes, vtfunction = 194;
+ getNumberOfSoftKeysRes, vtfunction = 192;
+ getTextFontDataRes, vtfunction = 195;
+ getHardwareRes, vtfunction = 199;
+ getSupportedWidecharsRes, vtfunction = 193;
+ getWindowMaskDataRes, vtfunction = 196;
+ getSupportedObjectsRes, vtfunction = 197;)"
+}
+
+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, vtfunction = 194;
+ getNumberOfSoftKeysReq, vtfunction = 192;
+ getTextFontDataReq, vtfunction = 195;
+ getHardwareReq, vtfunction = 199;
+ getSupportedWidecharsReq, vtfunction = 193;
+ getWindowMaskDataReq, vtfunction = 196;
+ getSupportedObjectsReq, vtfunction = 197;
+ workingSetMaintenanceReq, vtfunction = 255;
+// put all ECU2VT response messages here
+ //dummy_ECU2VT_Res, vtfunction = '00000000'B;
+ ) "
+ }
+
+} with { encode "RAW" }
diff --git a/demo/Isobus_Templates.ttcn b/demo/Isobus_Templates.ttcn
new file mode 100644
index 0000000..7b7d461
--- /dev/null
+++ b/demo/Isobus_Templates.ttcn
@@ -0,0 +1,64 @@
+module Isobus_Templates {
+
+import from IsobusMessageTypes all
+import from IsobusVTMessageTypes all
+import from Isobus all
+import from General_Types all
+
+
+template TopLevelMessage_ECU2VT_PDU t_GetMemoryReqX( INT3 p_memoryRequired) := {
+ getMemoryReq := {
+ vtfunction := 194,
+ reserved2 := 'FF'O,
+ memoryRequired := p_memoryRequired,
+ reserved7 := 'FF'O,
+ reserved8 := 'FF'O
+ }
+};
+
+template AnyIsoBusPdu t_ecu2vt(template TopLevelMessage_ECU2VT_PDU t_Message) := {
+ ecu2vt := t_Message
+};
+
+template AnyIsoBusPdu t_vt2ecu(template TopLevelMessage_VT2ECU_PDU t_Message) := {
+ vt2ecu := t_Message
+};
+
+template AnyIsoBusPdu t_GetMemoryReq_pdu(INT3 p_memoryRequired) := {
+ ecu2vt := {getMemoryReq := t_GetMemoryReq(p_memoryRequired)}
+}
+
+
+template GetMemoryReq t_GetMemoryReq(INT3 p_memoryRequired) := {
+ vtfunction := 194,
+ reserved2 := 'FF'O,
+ memoryRequired := p_memoryRequired,
+ reserved7 := 'FF'O,
+ reserved8 := 'FF'O
+}
+
+template GetMemoryRes t_GetMemoryRes(e_GetMemoryResVersionNumber p_versionNumber, e_GetMemoryResStatus p_status) := {
+ versionNumber := p_versionNumber,
+ status := p_status
+}
+
+template GetSupportedWidecharsReq t_GetSupportedWidecharsReq(e_Codeplane p_codeplane, OCT2 p_firstWideCharInInquiryRange, OCT2 p_lastWideCharInInquiryRange) := {
+ vtfunction := 193,
+ codeplane := p_codeplane,
+ firstWideCharInInquiryRange := p_firstWideCharInInquiryRange,
+ lastWideCharInInquiryRange := p_lastWideCharInInquiryRange,
+ reserved7 := 'FF'O,
+ reserved8 := 'FF'O
+}
+
+template GetSupportedWidecharsRes t_GetSupportedWidecharsRes(OCT2 p_firstWideCharInInquiryRange,
+ OCT2 p_lastWideCharInInquiryRange,
+ INT1 p_numberOfRanges,
+ WideCharRangeArray p_wideCharRangeArray) :=
+{
+ firstWideCharInInquiryRange := p_firstWideCharInInquiryRange,
+ lastWideCharInInquiryRange := p_lastWideCharInInquiryRange,
+ numberOfRanges := p_numberOfRanges,
+ wideCharRangeArray := p_wideCharRangeArray
+}
+}
diff --git a/demo/Isobustest.ttcn b/demo/Isobustest.ttcn
new file mode 100644
index 0000000..2db4c23
--- /dev/null
+++ b/demo/Isobustest.ttcn
@@ -0,0 +1,429 @@
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: Isobustest.ttcn
+// Description: Encoder / Decoder for Isobus message frames
+//
+// Revision R1A
+
+module Isobustest {
+
+import from General_Types all
+import from CanError all
+import from SocketCANtest all
+import from SocketCAN_Types all
+import from SocketCAN_PortType all
+import from SocketCAN_Templates all
+import from Can all
+import from Isobus all
+import from Isobus_Templates all
+
+
+
+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
+}
+
+type bitstring BIT29 length(29)
+type enumerated RTR { RTRNULL }
+
+type union Can_IDs {
+ BIT29 can_eff, // CAN extended format
+ BIT11 can_sff, // CAN basic format
+ RTR can_rtr, // Remote Transmission Request (RTR), seldom used
+ BIT29 can_err // CAN Error
+}
+with { variant "" }
+
+type record Can_IDwithType {
+ INT1 cantype, // can_id >> 29 bit
+ Can_IDs can_ids // can_id and4b '1FFFFFFF'O
+}
+with {
+ variant (can_ids) "CROSSTAG(
+ can_eff, cantype = 4;
+ can_rtr, cantype = 2;
+ can_err, cantype = 1;
+ can_sff, cantype = 0)"
+}
+
+//component declarations
+type component MTC_CT
+{
+}
+
+type component PTC_isobus_CT
+{
+ port SocketCAN_PT pt_socketCAN
+ port Isobus_PT pt_isobus
+ //variables
+ //timers
+ timer T0:= 0.2
+}
+
+type component PTC1_CT
+{
+ port Isobus_PT pt_isobus
+ //variables
+ //timers
+ timer T1:= 0.2
+
+}
+type component PTC2_CT
+{
+ //variables
+ //timers
+ timer T2:= 0.2
+}
+
+type port Isobus_PT message {
+ out CAN_frame_j1939
+ in CAN_frame_j1939
+} with { extension "internal" }
+
+type port SyncMasterPort message {
+ out PhaseStartReq
+ in PhaseEndInd
+} with { extension "internal" }
+
+type port SyncSlavePort message {
+ in PhaseStartReq
+ out PhaseEndInd
+} with { extension "internal" }
+
+type record of PTC PTCSet
+
+
+type component PTC {
+ port SyncSlavePort pt_sync
+ port SocketCAN_PT pt_socketCAN
+ var e_Phase v_phase := c_firstPhase
+}
+
+
+function f_open_socket2(in SocketCAN_open_socket_type v_socket_type)
+runs on PTC_isobus_CT
+return SocketCAN_socket_result {
+
+ var SocketCAN_socket_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ var SocketCAN_socket socket
+
+ if(v_socket_type==OPEN_CAN_RAW) {
+ socket := {domain:=PF_CAN, ptype := SOCK_RAW, protocol:= CAN_RAW};
+ } else if (v_socket_type == OPEN_CAN_BCM) {
+ socket := {domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_BCM};
+ }
+ pt_socketCAN.send(socket)
+
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(
+ a_SocketCAN_socket_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("SocketCan:Socket opened: ", v_result.id)}
+ [] pt_socketCAN.receive(a_SocketCAN_socket_result(a_result(SocketCAN_ERROR)))
+ {log("Received Opening Socket failed"); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+ t_guard.stop
+ return v_result
+}
+
+function f_open_raw2()
+runs on PTC_isobus_CT
+return SocketCAN_open_raw_result {
+ var SocketCAN_socketid v_socket_id
+ v_socket_id := f_open_socket2(OPEN_CAN_RAW).id
+ var SocketCAN_ifr v_ifr
+ v_ifr := f_ioctl_get_if_index2(v_socket_id).ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind2(v_socket_id, v_ifr.if_index)
+
+ var SocketCAN_open_raw_result v_result
+ v_result := {ifr := v_ifr, socket_id := v_socket_id}
+
+ return v_result
+}
+
+function f_ioctl_get_if_index2(in SocketCAN_socketid p_socket_id)
+runs on PTC_isobus_CT
+return SocketCAN_ioctl_result {
+ var SocketCAN_ioctl_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_ioctl:{id:= p_socket_id, ifu := omit});
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Retrieved interface index", v_result.ifr.if_index)}
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_ERROR)))
+ {log("Retrieving interface index failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_bind2(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_if_index p_if_index)
+runs on PTC_isobus_CT
+return SocketCAN_bind_result {
+ var SocketCAN_bind_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_bind:{id:= p_socket_id, bindu := {raw := {if_index:= p_if_index}}});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Binding socket", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_ERROR))) {}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_close_socket2 (in SocketCAN_socketid p_socket_id)
+runs on PTC_isobus_CT {
+ pt_socketCAN.send(SocketCAN_close:{id:= p_socket_id});
+}
+
+function f_behaviour_isobus(in PTC1_CT v_ptc1) runs on PTC_isobus_CT
+{
+
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ connect(v_ptc1:pt_isobus, self:pt_isobus)
+
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ var SocketCAN_open_raw_result res
+ res := f_open_raw2();
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+
+ log("socket open(): ", res)
+
+ var boolean condition3 := true
+ //periodic reception
+
+ while (condition3)
+ {
+ //var SocketCAN_socket_result v_result_socketcan
+ var SocketCAN_receive_CAN_or_CAN_FD_frame v_result_socketcan
+ var CAN_frame_j1939 v_result_can_frame_j1939
+ //T0.start;
+
+ alt
+ {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_CAN_frame(v_socket_id, t_CAN_EFF_FLAG, ?)) -> value v_result_socketcan
+ {log("SocketCan:Expected frame received", v_result_socketcan)
+ // it is assumed that no can fd frames are received here
+ if(ischosen(v_result_socketcan.frame.can_frame)){
+ var CAN_frame_j1939 v_CAN_frame_j1939 := can2j1939frame(v_result_socketcan.frame.can_frame)
+ pt_isobus.send(v_CAN_frame_j1939) to v_ptc1
+ } else {
+ setverdict(inconc, "reception of canfd frame not expected")
+ }
+ }
+ [] pt_socketCAN.receive(?) -> value v_result_socketcan
+ {log("SocketCan:Unexpected frame received!", v_result_socketcan)
+ setverdict(fail)
+ }
+ }//endalt
+ }
+ f_close_socket2(v_socket_id)
+ disconnect(self:pt_isobus, v_ptc1:pt_isobus)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+}//endfunction
+
+
+function f_behaviour1_sync() runs on PTC1_CT
+{
+
+ var boolean condition1 := true
+ var CAN_frame_j1939 v_can_frame_j1939
+ //periodic reception
+
+ while (condition1)
+ {
+ //T1.start;
+
+ alt
+ {
+
+ /* []syncport.receive("halt") {
+ condition1:=false } */
+
+ []pt_isobus.receive(CAN_frame_j1939:?) -> value v_can_frame_j1939 {
+ //T1.stop;
+ //log incoming message
+ //log ("received: ", v_can_frame_j1939);
+ }
+
+ //[]T1.timeout;
+
+ }//endalt
+ }
+}//endfunction var boolean condition1
+
+
+
+
+testcase tc_encdec() runs on MTC_CT
+
+{
+
+
+
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O }, can_pdu := { addressClaimed := { name := '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("--------------------------------------------")
+
+ template CAN_frame_j1939 t_CAN_frame_j1939_2 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { requestForAddressClaimed := {pgn := 123}} }
+ log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_2)))
+ log("--------------------------------------------")
+ log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_2))))
+ log("--------------------------------------------")
+
+ template CAN_frame_j1939 t_CAN_frame_j1939_3 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := { name := '1122334455667788'O }}}
+ log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_3)))
+ log("--------------------------------------------")
+ log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_3))))
+ log("--------------------------------------------")
+
+ template CAN_frame_j1939 t_CAN_frame_j1939_6 := { can_j1939 := { prio := '000110'B, res := '0'B, dp := '1'B, pf := 'E6'O , ps := 'FD'O, sa := '00'O }, can_pdu := { commandedAddress := {
+ name:='1122334455667788'O,
+ newSourceAddress:='AA'O
+ } } }
+ log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_6)))
+ log("--------------------------------------------")
+ log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939_6))))
+ log("--------------------------------------------")
+
+}
+
+testcase tc_encdec_vt2ecu_vtStatusReq() runs on MTC_CT
+{
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
+ {vt2ecu := {vtStatusReq :=
+ { vtfunction := 254,
+ sourceAddressOfActiveWorkingSetMaster := '11'O,
+ objectIDOfTheVisibleDataAlarmMaskOfTheActiveWorkingSet := '2233'O,
+ objectIDOfTheVisibleSoftKeyMaskOfTheActiveWorkingSet := '4455'O,
+ vtBusyCodes := vtIsBusyExecutingACommand,
+ vtFunctionCode := '66'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))))
+}
+
+testcase tc_encdec_ecu2vt_getMemoryReq() runs on MTC_CT
+{
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
+ {ecu2vt := {getMemoryReq :=
+ { vtfunction := 194,
+ reserved2 := 'FF'O,
+ memoryRequired := 1234567,
+ reserved7 := 'FF'O,
+ reserved8 := 'FF'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))))
+}
+
+testcase tc_encdec_ecu2vt_getMemoryReq_with_templateI() runs on MTC_CT // using a template
+{
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
+ {ecu2vt := {getMemoryReq := t_GetMemoryReq(1234567)}}}
+ 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))))
+}
+
+testcase tc_encdec_ecu2vt_getMemoryReq_with_template_II() runs on MTC_CT // using a template
+{
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000000'B, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
+ t_GetMemoryReq_pdu(1234567)}
+ 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))))
+}
+
+testcase tc_dec_requestForAddressClaimed() runs on MTC_CT
+{
+
+ var octetstring j1939_pdu
+ j1939_pdu := '98EAFFFE00EE00'O
+
+ log(j1939_pdu)
+ log("--------------------------------------------")
+ log(f_decode_CAN_frame_j1939(j1939_pdu))
+ log("--------------------------------------------")
+}
+
+//test case declarations
+testcase tc_Example001() runs on MTC_CT
+{
+
+ var PTC_isobus_CT v_PTC_isobus
+ var PTC1_CT v_PTC1
+
+ //create components
+ v_PTC_isobus:=PTC_isobus_CT.create;
+ v_PTC1:=PTC1_CT.create;
+
+ //connnect ports
+ //map ports
+
+ //start components
+
+ v_PTC1.start(f_behaviour1_sync());
+ v_PTC_isobus.start(f_behaviour_isobus(v_PTC1));
+
+ //wait for termination
+ all component.done
+
+
+ //unmap ports
+ //disconnect ports
+ //terminate all parallel test componenets
+ all component.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
+
+} with { encode "RAW" }
diff --git a/demo/Isotp.ttcn b/demo/Isotp.ttcn
new file mode 100644
index 0000000..2db472a
--- /dev/null
+++ b/demo/Isotp.ttcn
@@ -0,0 +1,46 @@
+
+
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: Isotp.ttcn
+// Description: Isotp base
+//
+// Revision R1A
+
+module Isotp {
+
+import from Bcm all
+import from Can all
+import from Raw all
+import from SocketCAN_Types all
+import from General_Types all
+
+template SocketCAN_write_isotp_result a_SocketCAN_write_isotp_result(
+ template SocketCAN_Result p_result) := {
+ // send ISOTP pdu
+ result := p_result
+}
+
+template SocketCAN_receive_isotp_pdu a_SocketCAN_receive_isotp_pdu(
+ template SocketCAN_socketid p_id,
+ template CAN_id p_can_id,
+ template SocketCAN_Isotp_PDU p_isotp_pdu) := {
+ // recieved CAN frame
+ id := p_id,
+ ifr := ?,
+ pdu := p_isotp_pdu
+}
+
+}
+
+
+
+
diff --git a/demo/Isotptest.ttcn b/demo/Isotptest.ttcn
new file mode 100644
index 0000000..7708e7d
--- /dev/null
+++ b/demo/Isotptest.ttcn
@@ -0,0 +1,268 @@
+module Isotptest {
+
+import from General_Types all
+import from CanError all
+import from SocketCAN_Types all
+import from SocketCAN_PortType all
+import from SocketCAN_Templates all
+import from Can all
+import from Isotp all
+
+const float c_guard := 10.0
+
+type enumerated SocketCAN_open_socket_type
+{
+ OPEN_CAN_RAW,
+ OPEN_CAN_BCM,
+ OPEN_CAN_ISOTP
+}
+
+type record SocketCAN_open_isotp_result{
+ SocketCAN_ifr ifr,
+ SocketCAN_socketid socket_id}
+
+//component declarations
+type component MTC_CT
+{
+}
+
+type component PTC_isotp_CT
+{
+ port SocketCAN_PT pt_socketCAN
+ // port Isotp_PT pt_isobus
+ //variables
+ //timers
+ timer T0:= 0.2
+}
+
+//type component PTC1_CT
+//{
+// port Isotp_PT pt_isobus
+// //variables
+// //timers
+// timer T1:= 0.2
+//
+//}
+//type component PTC2_CT
+//{
+// //variables
+// //timers
+// timer T2:= 0.2
+//}
+
+//type port Isotp_PT message {
+// out SocketCAN_Isotp_PDU
+// in SocketCAN_Isotp_PDU
+//} with { extension "internal" }
+
+function f_open_socket(in SocketCAN_open_socket_type v_socket_type)
+runs on PTC_isotp_CT
+return SocketCAN_socket_result {
+
+ var SocketCAN_socket_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ var SocketCAN_socket socket
+
+ if(v_socket_type==OPEN_CAN_RAW) {
+ socket := {domain:=PF_CAN, ptype := SOCK_RAW, protocol:= CAN_RAW};
+ } else if (v_socket_type == OPEN_CAN_BCM) {
+ socket := {domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_BCM};
+ } else if (v_socket_type == OPEN_CAN_ISOTP) {
+ socket := {domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_ISOTP};
+ }
+
+ pt_socketCAN.send(socket)
+
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(
+ a_SocketCAN_socket_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("SocketCan:Socket opened: ", v_result.id)}
+ [] pt_socketCAN.receive(a_SocketCAN_socket_result(a_result(SocketCAN_ERROR)))
+ {log("Received Opening Socket failed"); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+ t_guard.stop
+ return v_result
+}
+
+function f_open_isotp(in CAN_id p_rx_can_id,
+ in CAN_id p_tx_can_id)
+runs on PTC_isotp_CT
+return SocketCAN_open_isotp_result {
+ var SocketCAN_socketid v_socket_id
+ v_socket_id := f_open_socket(OPEN_CAN_ISOTP).id
+ var SocketCAN_ifr v_ifr
+ v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id, v_ifr.if_index, p_rx_can_id, p_tx_can_id)
+
+ var SocketCAN_open_isotp_result v_result
+ v_result := {ifr := v_ifr, socket_id := v_socket_id}
+
+ return v_result
+}
+
+function f_ioctl_get_if_index(in SocketCAN_socketid p_socket_id)
+runs on PTC_isotp_CT
+return SocketCAN_ioctl_result {
+ var SocketCAN_ioctl_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_ioctl:{id:= p_socket_id, ifu := omit});
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Retrieved interface index", v_result.ifr.if_index)}
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_ERROR)))
+ {log("Retrieving interface index failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_bind(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_if_index p_if_index,
+ in CAN_id p_rx_can_id,
+ in CAN_id p_tx_can_id)
+runs on PTC_isotp_CT
+return SocketCAN_bind_result {
+ var SocketCAN_bind_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_bind:{id:= p_socket_id,
+ bindu := {isotp := {if_index:= p_if_index,
+ rx_can_id := p_rx_can_id, tx_can_id := p_tx_can_id}}});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Binding socket", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_ERROR))) {}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_close_socket(in SocketCAN_socketid p_socket_id)
+runs on PTC_isotp_CT {
+ pt_socketCAN.send(SocketCAN_close:{id:= p_socket_id});
+}
+
+function f_send_isotp_message(in SocketCAN_socketid p_socket_id,
+ in octetstring p_pdu)
+runs on PTC_isotp_CT{
+ pt_socketCAN.send(SocketCAN_write_isotp:{p_socket_id, p_pdu})
+ alt{
+ []pt_socketCAN.receive(a_SocketCAN_write_isotp_result(a_result(SocketCAN_SUCCESS))){
+ log("Sent ISOTP Message \n")
+ }
+ }
+}
+
+
+function f_behaviour_isotp(in boolean p_initiator,
+ in CAN_id p_rx_can_id,
+ in CAN_id p_tx_can_id) runs on PTC_isotp_CT
+{
+
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ var SocketCAN_open_isotp_result res
+ res := f_open_isotp(p_rx_can_id, p_tx_can_id);
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+
+ log("socket open(): ", res)
+
+ var boolean condition3 := true
+ //periodic reception
+
+ if (p_initiator == true) {
+ var SocketCAN_Isotp_PDU v_pdu := '00112233445566778899'O
+ f_send_isotp_message(v_socket_id, v_pdu)
+ }
+ while (condition3)
+ {
+ //var SocketCAN_socket_result v_result_socketcan
+ var SocketCAN_receive_CAN_or_CAN_FD_frame v_result_socketcan
+ var SocketCAN_receive_isotp_pdu v_result_isotp_pdu
+ //T0.start;
+
+ alt
+ {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_isotp_pdu(v_socket_id, ?, ?)) -> value v_result_isotp_pdu
+ {log("SocketCan:Isotp pdu received", v_result_isotp_pdu)
+ f_send_isotp_message(v_socket_id, v_result_isotp_pdu.pdu)
+ }
+ [] pt_socketCAN.receive(a_SocketCAN_receive_isotp_pdu(?, ?, ?)) -> value v_result_isotp_pdu
+ {log("SocketCan:Isotp pdu received from unexpected port", v_result_isotp_pdu)
+ setverdict(inconc)
+ }
+ }//endalt
+ }
+ f_close_socket(v_socket_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+}//endfunction
+
+
+//test case declarations
+testcase tc_Isotp_Example001() runs on MTC_CT
+{
+
+ var PTC_isotp_CT v_PTC_isotp1, v_PTC_isotp2
+
+ //create components
+ v_PTC_isotp1 :=PTC_isotp_CT.create;
+ v_PTC_isotp2 :=PTC_isotp_CT.create;
+
+ //connnect ports
+ //map ports
+
+ //start components
+
+ //v_PTC1.start(f_behaviour1_sync());
+ v_PTC_isotp1.start(f_behaviour_isotp(true, '00000032'O, '00000023'O));
+ v_PTC_isotp2.start(f_behaviour_isotp(true, '00000023'O, '00000032'O));
+
+ //wait for termination
+ all component.done
+
+
+ //unmap ports
+ //disconnect ports
+ //terminate all parallel test componenets
+ all component.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_Isotp_Example001())
+
+
+}//endcontrol
+
+} with { encode "RAW" }
diff --git a/demo/J1939.ttcn b/demo/J1939.ttcn
new file mode 100644
index 0000000..5d5f4ff
--- /dev/null
+++ b/demo/J1939.ttcn
@@ -0,0 +1,15 @@
+module J1939 {
+import from General_Types all;
+
+type record CAN_identifier {
+BIT3 priority,
+BIT1 reseved,
+BIT1 datapage,
+OCT1 pduformat,
+OCT1 destinationAddress,
+OCT1 sourceAddress
+}
+
+type OCT3 PGN
+
+}
diff --git a/demo/Makefile b/demo/Makefile
index 3f9c4ec..45b168c 100644
--- a/demo/Makefile
+++ b/demo/Makefile
@@ -1,19 +1,19 @@
-# This Makefile was generated by the Makefile Generator
-# of the TTCN-3 Test Executor version CRL 113 200/6 R1A
-# for Elemer Lelik (ethlel@esekilxxen1841) on Sat Oct 15 09:22:38 2016
+# This Makefile was generated by the TITAN Designer eclipse plug-in
+# of the TTCN-3 Test executor version CRL 113 200/5 R5A
+# for (michael@michael-desktop) on Sun Sep 18 22:14:13 CEST 2016
# Copyright (c) 2000-2016 Ericsson Telecom AB
# The following make commands are available:
# - make, make all Builds the executable test suite.
# - make archive Archives all source files.
-# - make check Checks the semantics of TTCN-3 and ASN.1modules.
-# - make port Generates port skeletons.
+# - make check Checks the semantics of TTCN-3 and ASN.1 modules.
# - make clean Removes all generated files.
+# - make port Generates port skeletons.
# - make compile Translates TTCN-3 and ASN.1 modules to C++.
# - make dep Creates/updates dependency list.
# - make executable Builds the executable test suite.
-# - make library Builds the library archive.
+# - make library Builds the library archive: 'SocketCAN.a'.
# - make objects Builds the object files without linking the executable.
# WARNING! This Makefile can be used with GNU make only.
# Other versions of make may report syntax errors in it.
@@ -21,7 +21,7 @@
#
# Do NOT touch this line...
#
-.PHONY: all shared_objects executable library objects check port clean dep archive
+.PHONY: all executable library objects check port clean dep archive
.SUFFIXES: .d
@@ -31,23 +31,23 @@
# The path of your TTCN-3 Test Executor installation:
# Uncomment this line to override the environment variable.
-# TTCN3_DIR =
+# TTCN3_DIR =
# Your platform: (SOLARIS, SOLARIS8, LINUX, FREEBSD or WIN32)
PLATFORM = LINUX
# Your C++ compiler:
# (if you change the platform, you may need to change the compiler)
-CXX = g++
-
-# Flags for the C++ preprocessor (and makedepend as well):
-CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)/include -I. -I../src
+CXX = g++
# Flags for dependency generation
-CXXDEPFLAGS = -MM
+CXXDEPFLAGS := -MM
+
+# Flags for the C++ preprocessor (and makedepend as well):
+CPPFLAGS = -D$(PLATFORM) -I. -I$(TTCN3_DIR)/include -I. -I../src
# Flags for the C++ compiler:
-CXXFLAGS = -Wall
+CXXFLAGS = -Wall -O2
# Flags for the linker:
LDFLAGS =
@@ -62,7 +62,7 @@
ARFLAGS =
# Flags for the TTCN-3 and ASN.1 compiler:
-COMPILER_FLAGS = -L
+COMPILER_FLAGS = -lL
# Execution mode: (either ttcn3 or ttcn3-parallel)
TTCN3_LIB = ttcn3-parallel
@@ -83,38 +83,46 @@
#
# TTCN-3 modules of this project:
-TTCN3_MODULES = ../src/Bcm.ttcn ../src/Can.ttcn ../src/CanError.ttcn ../src/General_Types.ttcn ../src/Raw.ttcn SocketCAN_BCM_test.ttcn ../src/SocketCAN_PortType.ttcn SocketCAN_RAW_test.ttcn SocketCAN_Templates.ttcn ../src/SocketCAN_Types.ttcn SocketCANtest.ttcn
+TTCN3_MODULES = ../src/Bcm.ttcn ../src/Can.ttcn ../src/CanError.ttcn ../src/General_Types.ttcn ../src/Raw.ttcn \
+SocketCAN_BCM_test.ttcn ../src/SocketCAN_PortType.ttcn SocketCAN_RAW_test.ttcn ../src/SocketCAN_Templates.ttcn \
+../src/SocketCAN_Types.ttcn SocketCANtest.ttcn Isobus.ttcn Isobustest.ttcn IsobusMessageTypes.ttcn \
+Isobus_Templates.ttcn IsobusNMMessageTypes.ttcn IsobusCMMessageTypes.ttcn IsobusVTMessageTypes.ttcn \
+Isotp.ttcn Isotptest.ttcn
# ASN.1 modules of this project:
ASN1_MODULES =
# C++ source & header files generated from the TTCN-3 & ASN.1 modules of
# this project:
-GENERATED_SOURCES = Bcm.cc Can.cc CanError.cc General_Types.cc Raw.cc SocketCAN_BCM_test.cc SocketCAN_PortType.cc SocketCAN_RAW_test.cc SocketCAN_Templates.cc SocketCAN_Types.cc SocketCANtest.cc $(ASN1_MODULES:.asn=.cc)
+GENERATED_SOURCES = Bcm.cc Can.cc CanError.cc General_Types.cc Raw.cc \
+SocketCAN_BCM_test.cc SocketCAN_PortType.cc SocketCAN_RAW_test.cc SocketCAN_Templates.cc \
+SocketCAN_Types.cc SocketCANtest.cc Isobus.cc Isobustest.cc IsobusMessageTypes.cc \
+Isobus_Templates.cc IsobusNMMessageTypes.cc IsobusCMMessageTypes.cc IsobusVTMessageTypes.cc \
+Isotp.cc Isotptest.cc
+
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
# C/C++ Source & header files of Test Ports, external functions and
# other modules:
-USER_SOURCES = ../src/SocketCAN_PT.cc
-USER_HEADERS = $(USER_SOURCES:.cc=.hh)
+USER_SOURCES = ../src/SocketCAN_PT.cc
+USER_HEADERS = ../src/SocketCAN_PT.hh
# Object files of this project that are needed for the executable test suite:
OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)
GENERATED_OBJECTS = $(GENERATED_SOURCES:.cc=.o)
-USER_OBJECTS = $(USER_SOURCES:.cc=.o)
+USER_OBJECTS = SocketCAN_PT.o
-DEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)
+# Dependency files of this project that are needed for the executable test suite:
+DEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)
# Other files of the project (Makefile, configuration files, etc.)
# that will be added to the archived source files:
-OTHER_FILES = ../src/Makefile Makefile ../demo/README.md SocketCAN.cfg SocketCAN_broken_tests.cfg initscript.sh merge.sh
+OTHER_FILES = Makefile ../README.md SocketCAN.cfg SocketCAN_broken_tests.cfg initscript.sh merge.sh
# The name of the executable test suite:
EXECUTABLE = SocketCAN
-
-
LIBRARY = SocketCAN.a
TARGET = $(EXECUTABLE)
@@ -123,11 +131,11 @@
# Do not modify these unless you know what you are doing...
# Platform specific additional libraries:
#
-SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv
-SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv
-LINUX_LIBS = -lxml2 -lpthread -lrt
-FREEBSD_LIBS = -lxml2
-WIN32_LIBS = -lxml2
+SOLARIS_LIBS = -lsocket -lnsl -lxml2 -lresolv
+SOLARIS8_LIBS = -lsocket -lnsl -lxml2 -lresolv
+LINUX_LIBS = -lxml2 -lpthread -lrt
+FREEBSD_LIBS = -lxml2
+WIN32_LIBS = -lxml2
#
# Rules for building the executable...
@@ -142,21 +150,27 @@
objects: $(OBJECTS) compile;
$(EXECUTABLE): $(OBJECTS)
- if $(CXX) $(LDFLAGS) -o $@ $^ \
- -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
- -L$(OPENSSL_DIR)/lib -lcrypto \
- -L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \
- then : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi
+ $(CXX) $(LDFLAGS) -o $@ $^ \
+ -L$(TTCN3_DIR)/lib -L$(OPENSSL_DIR)/lib -L$(XMLDIR)/lib \
+ -l$(TTCN3_LIB) -lcrypto \
+ $($(PLATFORM)_LIBS) \
+ || if [ -f $(TTCN3_DIR)/bin/titanver ]; then $(TTCN3_DIR)/bin/titanver $^; else : ; fi
$(LIBRARY): $(OBJECTS)
$(AR) -r $(ARFLAGS) $(LIBRARY) $(OBJECTS)
-%.o: %.c $(GENERATED_HEADERS)
+SocketCAN_PT.o : ../src/SocketCAN_PT.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
-%.o: %.cc $(GENERATED_HEADERS)
+.cc.o .c.o:
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+SocketCAN_PT.d : ../src/SocketCAN_PT.cc
+ @echo Creating dependency file for '$<'; set -e; \
+ $(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
+ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+ [ -s $@ ] || rm -f $@
+
.cc.d .c.d:
@echo Creating dependency file for '$<'; set -e; \
$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
@@ -169,25 +183,28 @@
check: $(TTCN3_MODULES) $(ASN1_MODULES)
$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) $^
-port: $(TTCN3_MODULES)
+port: $(TTCN3_MODULES)
$(TTCN3_DIR)/bin/compiler -t $(COMPILER_FLAGS) $^
-compile: $(TTCN3_MODULES) $(ASN1_MODULES)
+compile: $(TTCN3_MODULES) $(ASN1_MODULES)
$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) $^ - $?
touch $@
+browserdata.dat: $(TTCN3_MODULES) $(ASN1_MODULES)
+ $(TTCN3_DIR)/bin/compiler -B -s $(COMPILER_FLAGS) $^
+
clean:
- -$(RM) $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \
- $(GENERATED_SOURCES) compile $(DEPFILES) \
- tags *.log
+ -$(RM) $(EXECUTABLE) $(OBJECTS) $(LIBRARY) $(GENERATED_HEADERS) $(DEPFILES) \
+ $(GENERATED_SOURCES) compile \
+ browserdata.dat tags *.log $(DEPFILES)
-dep: $(GENERATED_SOURCES) $(USER_SOURCES) ;
+dep: $(GENERATED_SOURCES) $(USER_SOURCES) $(DEPFILES) ;
-ifeq ($(findstring n,$(MAKEFLAGS)),)
-ifeq ($(filter clean check port compile archive diag,$(MAKECMDGOALS)),)
+ifeq ($(filter clean check port compile archive,$(MAKECMDGOALS)),)
-include $(DEPFILES)
endif
-endif
+
+
archive:
mkdir -p $(ARCHIVE_DIR)
diff --git a/demo/SocketCAN.cfg b/demo/SocketCAN.cfg
index ba45eb3..fc6c6cc 100644
--- a/demo/SocketCAN.cfg
+++ b/demo/SocketCAN.cfg
@@ -1,41 +1,41 @@
- ##############################################################################
- # Copyright (c) 2010, 2016 Ericsson AB
- # All rights reserved. This program and the accompanying materials
- # are made available under the terms of the Eclipse Public License v1.0
- # which accompanies this distribution, and is available at
- # http://www.eclipse.org/legal/epl-v10.html
- #
- # Contributors:
- # Michael Josenhans
- ##############################################################################
-
-
-
-[LOGGING]
-FileMask := LOG_ALL
-ConsoleMask := LOG_ALL
-LogSourceInfo := Yes
-SourceInfoFormat:= Single // Single or Stack
-LogEntityName:= Yes
-LogEventTypes:= Yes
-
-[TESTPORT_PARAMETERS]
-// Syntax:
-// <component_name>.<port_name>.<parameter_name> := <parameter_value>
-*.pt_socketCAN.SocketCAN_can_interface_name := "vcan0"
-*.pt_socketCAN.SocketCAN_debugging := "YES"
-
-
-[EXECUTE]
-//CAN RAW tests
-SocketCAN_RAW_test.tc_can_raw_send_and_receive_frame
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FILTER
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_ERR_FILTER
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_LOOPBACK
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_RECV_OWN_MSGS
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FD_FRAMES
-SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_JOIN_FILTERS
-//CAN BCM tests
-SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE
-// broken CAN BCM tests:
-//SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken
+ ##############################################################################
+ # Copyright (c) 2010, 2016 Ericsson AB
+ # All rights reserved. This program and the accompanying materials
+ # are made available under the terms of the Eclipse Public License v1.0
+ # which accompanies this distribution, and is available at
+ # http://www.eclipse.org/legal/epl-v10.html
+ #
+ # Contributors:
+ # Michael Josenhans
+ ##############################################################################
+
+// Revision R1A
+
+[LOGGING]
+FileMask := LOG_ALL | DEBUG | MATCHING
+ConsoleMask := LOG_ALL | DEBUG | MATCHING
+LogSourceInfo := Yes
+SourceInfoFormat:= Single // Single or Stack
+LogEntityName:= Yes
+LogEventTypes:= Yes
+
+[TESTPORT_PARAMETERS]
+// Syntax:
+// <component_name>.<port_name>.<parameter_name> := <parameter_value>
+*.pt_socketCAN.SocketCAN_can_interface_name := "vcan0"
+*.pt_socketCAN.SocketCAN_debugging := "YES"
+
+
+[EXECUTE]
+//CAN RAW tests
+SocketCAN_RAW_test.tc_can_raw_send_and_receive_frame
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FILTER
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_ERR_FILTER
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_LOOPBACK
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_RECV_OWN_MSGS
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FD_FRAMES
+SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_JOIN_FILTERS
+//CAN BCM tests
+SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE
+// broken CAN BCM tests:
+//SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken
diff --git a/demo/SocketCAN_BCM_test.ttcn b/demo/SocketCAN_BCM_test.ttcn
index 51035b2..8843028 100644
--- a/demo/SocketCAN_BCM_test.ttcn
+++ b/demo/SocketCAN_BCM_test.ttcn
@@ -1,243 +1,243 @@
-/* Copyright (c) 2010, 2016 Ericsson AB
-* All rights reserved. This program and the accompanying materials
-* are made available under the terms of the Eclipse Public License v1.0
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v10.html
-*
-* Contributors:
-* Michael Josenhans
-******************************************************************************/
-//
-// File: SocketCAN_BCM_test.ttcn
-// Description: SocketCAN testcases for CAN_BCM frames
-//
-
-
-
-module SocketCAN_BCM_test {
-import from SocketCANtest all
-import from SocketCAN_Types all;
-import from Bcm all
-import from Can all
-
-template SocketCAN_CAN_or_CAN_FD_frame a_CAN_frame (template CAN_frame p_can_frame) := {can_frame := p_can_frame}
-
-testcase tc_can_bcm_TX_SETUP_TX_DELETE() runs on MTC {
- // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving
- // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66).
-
- var PTC v_ptc_bcmConfigurator := PTC.create("PTC1_ptc_bcmConfigurator") alive
- var PTC v_ptc_rawFrameReceiver1 := PTC.create("PTC2_ptc_rawFrameReceiver1") alive
- var PTC v_ptc_rawFrameReceiver2 := PTC.create("PTC2_ptc_rawFrameReceiver2") alive
-
- f_addSyncSlaveSet(v_ptc_bcmConfigurator, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawFrameReceiver1, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawFrameReceiver2, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
-
- var CAN_frame v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
-
- var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame
-
- v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O};
- v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};
- v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O};
- v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O};
- v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O};
-
- template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
- {can_frame := v_can_frame1},
- {can_frame := v_can_frame2},
- {can_frame := v_can_frame3},
- {can_frame := v_can_frame4},
- {can_frame := v_can_frame5},
- {can_frame := v_can_frame1},
- {can_frame := v_can_frame2},
- {can_frame := v_can_frame3},
- {can_frame := v_can_frame4},
- {can_frame := v_can_frame5}
- }
-
- v_bcm_activation_frame := {
- opcode := '00000001'O, // TX_SETUP
- flags := '00000000000000000000000000000011'B, // refers to SETTIMER | STARTTIMER
- count := 0,
- ival1 := {0, 0},
- ival2 := {0, 100000},
- can_id := '00000042'O, // should become octetstring in the future
- frames := {can_frame := {
- v_can_frame1,
- v_can_frame2,
- v_can_frame3,
- v_can_frame4,
- v_can_frame5}}
- }
-
- v_bcm_deactivation_frame := {
- opcode := '00000002'O, // TX_DELETE
- flags := '00000000000000000000000000000000'B,
- count := 0,
- ival1 := {0, 0},
- ival2 := {0, 0},
- can_id := '00000042'O,
- frames := {can_frame := {}}
- }
-
- var BCM_cmds v_cmds :=
- {
- {phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
- {phase := e_testbody5, bcm_frame := v_bcm_deactivation_frame}
- }
-
- v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendInitiator(v_cmds))
-
- var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1, v_frame_to_receive5
- v_frame_to_receive1 := {can_frame := v_can_frame1}
- v_frame_to_receive5 := {can_frame := v_can_frame5}
-
- // stop when receiving v_frame_to_receive
- v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_receive1))
-
- // stop when receiving v_frame_to_receive
- v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody4, a_expected_can_frames, e_testbody5, 2.0))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
-
- all component.kill;
-}
-
-
-testcase tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken() runs on MTC {
- // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving
- // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66).
-
- var PTC v_ptc_bcmConfigurator := PTC.create("PTC1_ptc_bcmConfigurator") alive
- var PTC v_ptc_rawFrameReceiver1 := PTC.create("PTC2_ptc_rawFrameReceiver1") alive
- var PTC v_ptc_rawFrameReceiver2 := PTC.create("PTC2_ptc_rawFrameReceiver2") alive
-
- f_addSyncSlaveSet(v_ptc_bcmConfigurator, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawFrameReceiver1, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawFrameReceiver2, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
-
- var CAN_frame v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
-
- var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame, v_bcm_read_status_frame
-
- v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O};
- v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};
- v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O};
- v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O};
- v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O};
-
- template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
- {can_frame := v_can_frame1},
- {can_frame := v_can_frame2},
- {can_frame := v_can_frame3},
- {can_frame := v_can_frame4},
- {can_frame := v_can_frame5},
- {can_frame := v_can_frame1},
- {can_frame := v_can_frame2},
- {can_frame := v_can_frame3},
- {can_frame := v_can_frame4},
- {can_frame := v_can_frame5}
- }
-
-v_bcm_activation_frame := {
- opcode := '00000001'O, // TX_SETUP
- flags := '00000000000000000000000000000011'B, // refers to SETTIMER | STARTTIMER
- count := 0,
- ival1 := {0, 0},
- ival2 := {0, 100000},
- can_id := '00000042'O, // should become octetstring in the future
- frames := {can_frame := {
- v_can_frame1,
- v_can_frame2,
- v_can_frame3,
- v_can_frame4,
- v_can_frame5}}
- }
-
- v_bcm_deactivation_frame := {
- opcode := '00000002'O, // TX_DELETE
- flags := '00000000000000000000000000000000'B,
- count := 0,
- ival1 := {0, 0},
- ival2 := {0, 0},
- can_id := '00000042'O,
- frames := {can_frame := {}}
- }
-
- v_bcm_read_status_frame := {
- opcode := '00000003'O, // TX_READ
- flags :=
- // workaround for titan constants instead of enums:
- ('00000000000000000000000000000001'B << 0) or4b // enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) instead of 0
- ('00000000000000000000000000000001'B << 1) or4b // enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) instead of 1
- ('00000000000000000000000000000001'B << 4), // enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX) instead of 4
- count := 0,
- ival1 := {0, 0},
- ival2 := {0, 0},
- can_id := '00000042'O,
- frames := {can_frame := {}}
- }
-
-
- var BCM_cmds v_cmds :=
- {
- //{phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
- {phase := e_testbody3, bcm_frame := v_bcm_read_status_frame},
- {phase := e_testbody4, bcm_frame := v_bcm_deactivation_frame},
- {phase := e_testbody6, bcm_frame := v_bcm_read_status_frame}
- }
-
- v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendReceiveInitiator(v_cmds))
-
- var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1, v_frame_to_receive5
- v_frame_to_receive1 := {can_frame := v_can_frame1}
- v_frame_to_receive5 := {can_frame := v_can_frame5}
-
- // stop when receiving v_frame_to_receive
- v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_receive1))
-
- // stop when receiving v_frame_to_receive
- v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody5, a_expected_can_frames, e_testbody6, 2.0))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
-
- all component.kill;
-}
-
-}
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: SocketCAN_BCM_test.ttcn
+// Description: SocketCAN testcases for CAN_BCM frames
+//
+// Revision R1A
+
+
+module SocketCAN_BCM_test {
+import from SocketCANtest all
+import from SocketCAN_Types all;
+import from Bcm all
+import from Can all
+
+template SocketCAN_CAN_or_CAN_FD_frame a_CAN_frame (template CAN_frame p_can_frame) := {can_frame := p_can_frame}
+
+testcase tc_can_bcm_TX_SETUP_TX_DELETE() runs on MTC {
+ // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving
+ // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66).
+
+ var PTC v_ptc_bcmConfigurator := PTC.create("PTC1_ptc_bcmConfigurator") alive
+ var PTC v_ptc_rawFrameReceiver1 := PTC.create("PTC2_ptc_rawFrameReceiver1") alive
+ var PTC v_ptc_rawFrameReceiver2 := PTC.create("PTC2_ptc_rawFrameReceiver2") alive
+
+ f_addSyncSlaveSet(v_ptc_bcmConfigurator, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawFrameReceiver1, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawFrameReceiver2, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
+
+ var CAN_frame v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
+
+ var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame
+
+ v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O};
+ v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};
+ v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O};
+ v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O};
+ v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O};
+
+ template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
+ {can_frame := v_can_frame1},
+ {can_frame := v_can_frame2},
+ {can_frame := v_can_frame3},
+ {can_frame := v_can_frame4},
+ {can_frame := v_can_frame5},
+ {can_frame := v_can_frame1},
+ {can_frame := v_can_frame2},
+ {can_frame := v_can_frame3},
+ {can_frame := v_can_frame4},
+ {can_frame := v_can_frame5}
+ }
+
+ v_bcm_activation_frame := {
+ opcode := '00000001'O, // TX_SETUP
+ flags := '00000000000000000000000000000011'B, // refers to SETTIMER | STARTTIMER
+ count := 0,
+ ival1 := {0, 0},
+ ival2 := {0, 100000},
+ can_id := '00000042'O, // should become octetstring in the future
+ frames := {can_frame := {
+ v_can_frame1,
+ v_can_frame2,
+ v_can_frame3,
+ v_can_frame4,
+ v_can_frame5}}
+ }
+
+ v_bcm_deactivation_frame := {
+ opcode := '00000002'O, // TX_DELETE
+ flags := '00000000000000000000000000000000'B,
+ count := 0,
+ ival1 := {0, 0},
+ ival2 := {0, 0},
+ can_id := '00000042'O,
+ frames := {can_frame := {}}
+ }
+
+ var BCM_cmds v_cmds :=
+ {
+ {phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
+ {phase := e_testbody5, bcm_frame := v_bcm_deactivation_frame}
+ }
+
+ v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendInitiator(v_cmds))
+
+ var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1, v_frame_to_receive5
+ v_frame_to_receive1 := {can_frame := v_can_frame1}
+ v_frame_to_receive5 := {can_frame := v_can_frame5}
+
+ // stop when receiving v_frame_to_receive
+ v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_receive1))
+
+ // stop when receiving v_frame_to_receive
+ v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody4, a_expected_can_frames, e_testbody5, 2.0))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
+
+ all component.kill;
+}
+
+
+testcase tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken() runs on MTC {
+ // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving
+ // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66).
+
+ var PTC v_ptc_bcmConfigurator := PTC.create("PTC1_ptc_bcmConfigurator") alive
+ var PTC v_ptc_rawFrameReceiver1 := PTC.create("PTC2_ptc_rawFrameReceiver1") alive
+ var PTC v_ptc_rawFrameReceiver2 := PTC.create("PTC2_ptc_rawFrameReceiver2") alive
+
+ f_addSyncSlaveSet(v_ptc_bcmConfigurator, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawFrameReceiver1, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawFrameReceiver2, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
+
+ var CAN_frame v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
+
+ var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame, v_bcm_read_status_frame
+
+ v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O};
+ v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};
+ v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O};
+ v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O};
+ v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O};
+
+ template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
+ {can_frame := v_can_frame1},
+ {can_frame := v_can_frame2},
+ {can_frame := v_can_frame3},
+ {can_frame := v_can_frame4},
+ {can_frame := v_can_frame5},
+ {can_frame := v_can_frame1},
+ {can_frame := v_can_frame2},
+ {can_frame := v_can_frame3},
+ {can_frame := v_can_frame4},
+ {can_frame := v_can_frame5}
+ }
+
+v_bcm_activation_frame := {
+ opcode := '00000001'O, // TX_SETUP
+ flags := '00000000000000000000000000000011'B, // refers to SETTIMER | STARTTIMER
+ count := 0,
+ ival1 := {0, 0},
+ ival2 := {0, 100000},
+ can_id := '00000042'O, // should become octetstring in the future
+ frames := {can_frame := {
+ v_can_frame1,
+ v_can_frame2,
+ v_can_frame3,
+ v_can_frame4,
+ v_can_frame5}}
+ }
+
+ v_bcm_deactivation_frame := {
+ opcode := '00000002'O, // TX_DELETE
+ flags := '00000000000000000000000000000000'B,
+ count := 0,
+ ival1 := {0, 0},
+ ival2 := {0, 0},
+ can_id := '00000042'O,
+ frames := {can_frame := {}}
+ }
+
+ v_bcm_read_status_frame := {
+ opcode := '00000003'O, // TX_READ
+ flags :=
+ // workaround for titan constants instead of enums:
+ ('00000000000000000000000000000001'B << 0) or4b // enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) instead of 0
+ ('00000000000000000000000000000001'B << 1) or4b // enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) instead of 1
+ ('00000000000000000000000000000001'B << 4), // enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX) instead of 4
+ count := 0,
+ ival1 := {0, 0},
+ ival2 := {0, 0},
+ can_id := '00000042'O,
+ frames := {can_frame := {}}
+ }
+
+
+ var BCM_cmds v_cmds :=
+ {
+ //{phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
+ {phase := e_testbody3, bcm_frame := v_bcm_read_status_frame},
+ {phase := e_testbody4, bcm_frame := v_bcm_deactivation_frame},
+ {phase := e_testbody6, bcm_frame := v_bcm_read_status_frame}
+ }
+
+ v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendReceiveInitiator(v_cmds))
+
+ var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1, v_frame_to_receive5
+ v_frame_to_receive1 := {can_frame := v_can_frame1}
+ v_frame_to_receive5 := {can_frame := v_can_frame5}
+
+ // stop when receiving v_frame_to_receive
+ v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_receive1))
+
+ // stop when receiving v_frame_to_receive
+ v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody5, a_expected_can_frames, e_testbody6, 2.0))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
+
+ all component.kill;
+}
+
+}
diff --git a/demo/SocketCAN_RAW_test.ttcn b/demo/SocketCAN_RAW_test.ttcn
index 3f1e811..e738f3c 100644
--- a/demo/SocketCAN_RAW_test.ttcn
+++ b/demo/SocketCAN_RAW_test.ttcn
@@ -1,293 +1,294 @@
-/* Copyright (c) 2010, 2016 Ericsson AB
-* All rights reserved. This program and the accompanying materials
-* are made available under the terms of the Eclipse Public License v1.0
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v10.html
-*
-* Contributors:
-* Michael Josenhans
-******************************************************************************/
-//
-// File: SocketCAN_RAW_test.ttcn
-// Description: SocketCAN testcases for CAN_RAW frames
-//
-
-
-module SocketCAN_RAW_test
-{
-import from SocketCANtest all
-import from SocketCAN_Types all;
-import from Can all
-import from Raw all
-import from CanError all
-
-testcase tc_can_raw_send_and_receive_frame() runs on MTC {
- var PTC v_ptc_rawSendInitiator := PTC.create("PTC1_ptc_rawSendInitiator") alive
- var PTC v_ptc_rawFrameReceiver := PTC.create("PTC2_ptc_rawFrameReceiver") alive
-
- f_addSyncSlaveSet(v_ptc_rawSendInitiator, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawFrameReceiver, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
-
- var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_send
- v_frame_to_send := {can_frame :=
- {can_id := '00000015'O,
- can_pdu := '0123456789ABCDEF'O}
- }
-
- v_ptc_rawSendInitiator.start(f_ptc_RawSendInitiator(e_testbody1, v_frame_to_send))
- v_ptc_rawFrameReceiver.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_send))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete;v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_FILTER() runs on MTC {
-
- var PTC v_ptc_rawSetFilters := PTC.create("PTC1_ptc_rawSetFilters") alive
- var PTC v_ptc_rawDeactivateFilters := PTC.create("PTC1_ptc_rawDeactivateFilters") alive
-
- f_addSyncSlaveSet(v_ptc_rawSetFilters, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateFilters, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawSetFilters:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateFilters:pt_sync)
-
- // activate filters
- const CAN_RAW_filter c_rfilter0 := {
- can_id := '00000123'O,
- can_mask := bit2oct(oct2bit(CAN_EFF_FLAG) or4b oct2bit(CAN_RTR_FLAG) or4b oct2bit(CAN_SFF_MASK))};
- const CAN_RAW_filter c_rfilter1 := {
- can_id := '00000200'O,
- can_mask := '00000700'O};
- const CAN_RAW_filter c_rfilter2 := {
- can_id := bit2oct(oct2bit('12345678'O) or4b oct2bit(CAN_EFF_FLAG)),
- can_mask := bit2oct(oct2bit(CAN_EFF_FLAG) or4b oct2bit(CAN_RTR_FLAG) or4b oct2bit(CAN_EFF_MASK))};
- const SocketCAN_setsockopt_commandu c_commandu_activate_filters := {rfilter:={c_rfilter0, c_rfilter1, c_rfilter2}}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_filters := {rfilter:={}}
-
- // activate filters command
- v_ptc_rawSetFilters.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_filters))
-
- // deactivate filters command
- v_ptc_rawDeactivateFilters.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_filters))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawSetFilters:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateFilters:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_ERR_FILTER() runs on MTC {
-
- var PTC v_ptc_rawActivateErrorMask := PTC.create("PTC1_ptc_rawActivateErrorMask") alive
- var PTC v_ptc_rawDeactivateErrorMask := PTC.create("PTC1_ptc_rawDeactivateErrorMask") alive
-
- f_addSyncSlaveSet(v_ptc_rawActivateErrorMask, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateErrorMask, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawActivateErrorMask:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateErrorMask:pt_sync)
-
- const SocketCAN_setsockopt_commandu c_commandu_activate_err_mask := {err_mask := oct2bit(CAN_ERR_TX_TIMEOUT) or4b oct2bit(CAN_ERR_BUSOFF)}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_err_mask := {err_mask := oct2bit('00000000'O)}
-
- // activate error mask command
- v_ptc_rawActivateErrorMask.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_err_mask))
-
- // deactivate error mask command
- v_ptc_rawDeactivateErrorMask.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_err_mask))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawActivateErrorMask:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateErrorMask:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_LOOPBACK() runs on MTC {
-
- var PTC v_ptc_rawActivateLoopback := PTC.create("PTC1_ptc_rawActivateLoopback") alive
- var PTC v_ptc_rawDeactivateLoopback := PTC.create("PTC1_ptc_rawDeactivateLoopback") alive
-
- f_addSyncSlaveSet(v_ptc_rawActivateLoopback, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateLoopback, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawActivateLoopback:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateLoopback:pt_sync)
-
- const SocketCAN_setsockopt_commandu c_commandu_activate_loopback := {loopback := Enable}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_loopback := {loopback := Disable}
-
- // activate error mask command
- v_ptc_rawActivateLoopback.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_loopback))
-
- // deactivate error mask command
- v_ptc_rawDeactivateLoopback.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_loopback))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawActivateLoopback:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateLoopback:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_RECV_OWN_MSGS() runs on MTC {
-
- var PTC v_ptc_rawActivateReceiveOwnMessages := PTC.create("PTC1_ptc_rawActivateReceiveOwnMessages") alive
- var PTC v_ptc_rawDeactivateReceiveOwnMessages := PTC.create("PTC1_ptc_rawDeactivateReceiveOwnMessages") alive
-
- f_addSyncSlaveSet(v_ptc_rawActivateReceiveOwnMessages, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateReceiveOwnMessages, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawActivateReceiveOwnMessages:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateReceiveOwnMessages:pt_sync)
-
- const SocketCAN_setsockopt_commandu c_commandu_activate_ReceiveOwnMessages := {recv_own_msgs := Enable}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_ReceiveOwnMessages := {recv_own_msgs := Disable}
-
- // activate error mask command
- v_ptc_rawActivateReceiveOwnMessages.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_ReceiveOwnMessages))
-
- // deactivate error mask command
- v_ptc_rawDeactivateReceiveOwnMessages.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_ReceiveOwnMessages))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawActivateReceiveOwnMessages:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateReceiveOwnMessages:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_FD_FRAMES() runs on MTC {
-
- var PTC v_ptc_rawActivateFD_Frames := PTC.create("PTC1_ptc_rawActivateFD_Frames") alive
- var PTC v_ptc_rawDeactivateFD_Frames := PTC.create("PTC1_ptc_rawDeactivateFD_Frames") alive
-
- f_addSyncSlaveSet(v_ptc_rawActivateFD_Frames, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateFD_Frames, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawActivateFD_Frames:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateFD_Frames:pt_sync)
-
- const SocketCAN_setsockopt_commandu c_commandu_activate_FD_Frames := {fd_frames := Enable}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_FD_Frames := {fd_frames := Disable}
-
- // activate error mask command
- v_ptc_rawActivateFD_Frames.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_FD_Frames))
-
- // deactivate error mask command
- v_ptc_rawDeactivateFD_Frames.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_FD_Frames))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawActivateFD_Frames:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateFD_Frames:pt_sync)
-
- all component.kill;
-}
-
-testcase tc_can_raw_setsockopt_CAN_RAW_JOIN_FILTERS() runs on MTC {
-
- var PTC v_ptc_rawActivateJoinFilters := PTC.create("PTC1_ptc_rawActivateJoinFilters") alive
- var PTC v_ptc_rawDeactivateJoinFilters := PTC.create("PTC1_ptc_rawDeactivateJoinFilters") alive
-
- f_addSyncSlaveSet(v_ptc_rawActivateJoinFilters, v_PTCSet)
- f_addSyncSlaveSet(v_ptc_rawDeactivateJoinFilters, v_PTCSet)
- connect(mtc:pt_sync, v_ptc_rawActivateJoinFilters:pt_sync)
- connect(mtc:pt_sync, v_ptc_rawDeactivateJoinFilters:pt_sync)
-
- const SocketCAN_setsockopt_commandu c_commandu_activate_JoinFilters := {join_filters := Enable}
- const SocketCAN_setsockopt_commandu c_commandu_deactivate_JoinFilters := {join_filters := Disable}
-
- // activate error mask command
- v_ptc_rawActivateJoinFilters.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_JoinFilters))
-
- // deactivate error mask command
- v_ptc_rawDeactivateJoinFilters.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_JoinFilters))
-
- var e_Phase v_phase
-
- for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
- f_startPhase(v_phase)
- log("MTC: ", v_phase)
- f_awaitEndPhase(v_phase)
- }
-
- all component.done;
- log("MTC done")
-
- disconnect(mtc:pt_sync, v_ptc_rawActivateJoinFilters:pt_sync)
- disconnect(mtc:pt_sync, v_ptc_rawDeactivateJoinFilters:pt_sync)
-
- all component.kill;
-}
-
-
-
-//=========================================================================
-// Control
-//=========================================================================
-
-// Insert control part here if applicable!
-
-} // end of module
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: SocketCAN_RAW_test.ttcn
+// Description: SocketCAN testcases for CAN_RAW frames
+//
+// Revision R1A
+
+
+module SocketCAN_RAW_test
+{
+import from SocketCANtest all
+import from SocketCAN_Types all;
+import from Can all
+import from Raw all
+import from CanError all
+
+testcase tc_can_raw_send_and_receive_frame() runs on MTC {
+ var PTC v_ptc_rawSendInitiator := PTC.create("PTC1_ptc_rawSendInitiator") alive
+ var PTC v_ptc_rawFrameReceiver := PTC.create("PTC2_ptc_rawFrameReceiver") alive
+
+ f_addSyncSlaveSet(v_ptc_rawSendInitiator, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawFrameReceiver, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
+
+ var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_send
+ v_frame_to_send := {can_frame :=
+ {can_id := '00000015'O,
+ can_pdu := '0123456789ABCDEF'O}
+ }
+
+ v_ptc_rawSendInitiator.start(f_ptc_RawSendInitiator(e_testbody1, v_frame_to_send))
+ v_ptc_rawFrameReceiver.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_send))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete;v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_FILTER() runs on MTC {
+
+ var PTC v_ptc_rawSetFilters := PTC.create("PTC1_ptc_rawSetFilters") alive
+ var PTC v_ptc_rawDeactivateFilters := PTC.create("PTC1_ptc_rawDeactivateFilters") alive
+
+ f_addSyncSlaveSet(v_ptc_rawSetFilters, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateFilters, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawSetFilters:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateFilters:pt_sync)
+
+ // activate filters
+ const CAN_RAW_filter c_rfilter0 := {
+ can_id := '00000123'O,
+ can_mask := bit2oct(oct2bit(CAN_EFF_FLAG) or4b oct2bit(CAN_RTR_FLAG) or4b oct2bit(CAN_SFF_MASK))};
+ const CAN_RAW_filter c_rfilter1 := {
+ can_id := '00000200'O,
+ can_mask := '00000700'O};
+ const CAN_RAW_filter c_rfilter2 := {
+ can_id := bit2oct(oct2bit('12345678'O) or4b oct2bit(CAN_EFF_FLAG)),
+ can_mask := bit2oct(oct2bit(CAN_EFF_FLAG) or4b oct2bit(CAN_RTR_FLAG) or4b oct2bit(CAN_EFF_MASK))};
+ const SocketCAN_setsockopt_commandu c_commandu_activate_filters := {rfilter:={c_rfilter0, c_rfilter1, c_rfilter2}}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_filters := {rfilter:={}}
+
+ // activate filters command
+ v_ptc_rawSetFilters.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_filters))
+
+ // deactivate filters command
+ v_ptc_rawDeactivateFilters.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_filters))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawSetFilters:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateFilters:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_ERR_FILTER() runs on MTC {
+
+ var PTC v_ptc_rawActivateErrorMask := PTC.create("PTC1_ptc_rawActivateErrorMask") alive
+ var PTC v_ptc_rawDeactivateErrorMask := PTC.create("PTC1_ptc_rawDeactivateErrorMask") alive
+
+ f_addSyncSlaveSet(v_ptc_rawActivateErrorMask, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateErrorMask, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawActivateErrorMask:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateErrorMask:pt_sync)
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_err_mask := {err_mask := oct2bit(CAN_ERR_TX_TIMEOUT) or4b oct2bit(CAN_ERR_BUSOFF)}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_err_mask := {err_mask := oct2bit('00000000'O)}
+
+ // activate error mask command
+ v_ptc_rawActivateErrorMask.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_err_mask))
+
+ // deactivate error mask command
+ v_ptc_rawDeactivateErrorMask.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_err_mask))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawActivateErrorMask:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateErrorMask:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_LOOPBACK() runs on MTC {
+
+ var PTC v_ptc_rawActivateLoopback := PTC.create("PTC1_ptc_rawActivateLoopback") alive
+ var PTC v_ptc_rawDeactivateLoopback := PTC.create("PTC1_ptc_rawDeactivateLoopback") alive
+
+ f_addSyncSlaveSet(v_ptc_rawActivateLoopback, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateLoopback, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawActivateLoopback:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateLoopback:pt_sync)
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_loopback := {loopback := Enable}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_loopback := {loopback := Disable}
+
+ // activate error mask command
+ v_ptc_rawActivateLoopback.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_loopback))
+
+ // deactivate error mask command
+ v_ptc_rawDeactivateLoopback.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_loopback))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawActivateLoopback:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateLoopback:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_RECV_OWN_MSGS() runs on MTC {
+
+ var PTC v_ptc_rawActivateReceiveOwnMessages := PTC.create("PTC1_ptc_rawActivateReceiveOwnMessages") alive
+ var PTC v_ptc_rawDeactivateReceiveOwnMessages := PTC.create("PTC1_ptc_rawDeactivateReceiveOwnMessages") alive
+
+ f_addSyncSlaveSet(v_ptc_rawActivateReceiveOwnMessages, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateReceiveOwnMessages, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawActivateReceiveOwnMessages:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateReceiveOwnMessages:pt_sync)
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_ReceiveOwnMessages := {recv_own_msgs := Enable}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_ReceiveOwnMessages := {recv_own_msgs := Disable}
+
+ // activate error mask command
+ v_ptc_rawActivateReceiveOwnMessages.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_ReceiveOwnMessages))
+
+ // deactivate error mask command
+ v_ptc_rawDeactivateReceiveOwnMessages.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_ReceiveOwnMessages))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawActivateReceiveOwnMessages:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateReceiveOwnMessages:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_FD_FRAMES() runs on MTC {
+
+ var PTC v_ptc_rawActivateFD_Frames := PTC.create("PTC1_ptc_rawActivateFD_Frames") alive
+ var PTC v_ptc_rawDeactivateFD_Frames := PTC.create("PTC1_ptc_rawDeactivateFD_Frames") alive
+
+ f_addSyncSlaveSet(v_ptc_rawActivateFD_Frames, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateFD_Frames, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawActivateFD_Frames:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateFD_Frames:pt_sync)
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_FD_Frames := {fd_frames := Enable}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_FD_Frames := {fd_frames := Disable}
+
+ // activate error mask command
+ v_ptc_rawActivateFD_Frames.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_FD_Frames))
+
+ // deactivate error mask command
+ v_ptc_rawDeactivateFD_Frames.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_FD_Frames))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawActivateFD_Frames:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateFD_Frames:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_raw_setsockopt_CAN_RAW_JOIN_FILTERS() runs on MTC {
+
+ var PTC v_ptc_rawActivateJoinFilters := PTC.create("PTC1_ptc_rawActivateJoinFilters") alive
+ var PTC v_ptc_rawDeactivateJoinFilters := PTC.create("PTC1_ptc_rawDeactivateJoinFilters") alive
+
+ f_addSyncSlaveSet(v_ptc_rawActivateJoinFilters, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_rawDeactivateJoinFilters, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_rawActivateJoinFilters:pt_sync)
+ connect(mtc:pt_sync, v_ptc_rawDeactivateJoinFilters:pt_sync)
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_JoinFilters := {join_filters := Enable}
+ const SocketCAN_setsockopt_commandu c_commandu_deactivate_JoinFilters := {join_filters := Disable}
+
+ // activate error mask command
+ v_ptc_rawActivateJoinFilters.start(f_raw_setsockopt(e_testbody1, c_commandu_activate_JoinFilters))
+
+ // deactivate error mask command
+ v_ptc_rawDeactivateJoinFilters.start(f_raw_setsockopt(e_testbody3, c_commandu_deactivate_JoinFilters))
+
+ var e_Phase v_phase
+
+ for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+ f_startPhase(v_phase)
+ log("MTC: ", v_phase)
+ f_awaitEndPhase(v_phase)
+ }
+
+ all component.done;
+ log("MTC done")
+
+ disconnect(mtc:pt_sync, v_ptc_rawActivateJoinFilters:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_rawDeactivateJoinFilters:pt_sync)
+
+ all component.kill;
+}
+
+
+
+//=========================================================================
+// Control
+//=========================================================================
+
+// Insert control part here if applicable!
+
+} // end of module
diff --git a/demo/SocketCAN_broken_tests.cfg b/demo/SocketCAN_broken_tests.cfg
index f5990d9..377b773 100644
--- a/demo/SocketCAN_broken_tests.cfg
+++ b/demo/SocketCAN_broken_tests.cfg
@@ -9,7 +9,7 @@
# Michael Josenhans
##############################################################################
-
+// Revision R1A
[LOGGING]
FileMask := LOG_ALL
diff --git a/demo/SocketCANtest.ttcn b/demo/SocketCANtest.ttcn
index e27fef7..b78727a 100644
--- a/demo/SocketCANtest.ttcn
+++ b/demo/SocketCANtest.ttcn
@@ -1,652 +1,652 @@
-/* Copyright (c) 2010, 2016 Ericsson AB
-* All rights reserved. This program and the accompanying materials
-* are made available under the terms of the Eclipse Public License v1.0
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v10.html
-*
-* Contributors:
-* Michael Josenhans
-******************************************************************************/
-//
-// File: SocketCANtest.ttcn
-// Description: SocketCAN port type test
-//
-
-
-module SocketCANtest {
-
-import from SocketCAN_Types all;
-import from SocketCAN_PortType all;
-import from SocketCAN_Templates all;
-import from Bcm all
-
-const float c_guard := 10.0
-
-type enumerated SocketCAN_open_socket_type
-{
- OPEN_CAN_RAW,
- OPEN_CAN_BCM
- //OPEN_CAN_ISOTP
-}
-
-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
-}
-
-type record SocketCAN_open_raw_result{
- SocketCAN_ifr ifr,
- SocketCAN_socketid socket_id}
-
-type record BCM_cmd {
- e_Phase phase,
- SocketCAN_bcm_frame bcm_frame
-}
-
-type record length (0 .. CAN_FRAME_MAX_NUMBER) of BCM_cmd BCM_cmds
-
-type record length (0 .. CAN_FRAME_MAX_NUMBER) of SocketCAN_CAN_or_CAN_FD_frame SocketCAN_CAN_or_CAN_FD_frames
-
-// workarounds as (x .. enum2int(e_testcase_complete)) fails but:
-// workarounds as (x .. enum2int(c_testcase_complete)) works
-const e_Phase c_firstPhase := e_open_socket
-const e_Phase c_testcase_complete := e_testcase_complete
-
-type record PhaseStartReq {
- e_Phase phase,
- integer phase_int
-}
-type record PhaseEndInd {
- e_Phase phase,
- integer phase_int
-}
-
-type port SyncMasterPort message {
- out PhaseStartReq
- in PhaseEndInd
-} with { extension "internal" }
-
-type port SyncSlavePort message {
- in PhaseStartReq
- out PhaseEndInd
-} with { extension "internal" }
-
-type record of PTC PTCSet
-
-
-type component PTC {
- port SyncSlavePort pt_sync
- port SocketCAN_PT pt_socketCAN
- var e_Phase v_phase := c_firstPhase
-}
-
-//component declarations
-type component MTC{
- timer t_guard
- port SyncMasterPort pt_sync
- var PTCSet v_PTCSet := {}
-}
-
-altstep alt_awaitPhaseStartReq(in e_Phase p_phase) runs on PTC {
- var PhaseStartReq v_PhaseStartReq;
- [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
- log("PTC name: ", self)
- log("Waits for start of phase: ", p_phase)
- }
- // between v_phase and p_phase
- [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int := (enum2int(c_firstPhase) .. enum2int(v_phase))}) -> value v_PhaseStartReq
- {
- //v_phase := f_incPhase(v_phase)
- log("PTC name: ", self)
- log("Waits for start of phase: ", p_phase)
- log("Received completion of phase: ", p_phase)
- f_sendPhaseEndInd()
- repeat
- }
- [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int :=?}) -> value v_PhaseStartReq
- {log("Received unexpected message:", v_PhaseStartReq);setverdict(inconc)}
-}
-
-function f_startPhase (in e_Phase p_phase) runs on MTC {
- var integer v_i
- var integer v_amount := sizeof(v_PTCSet)
- var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}
-
- for (v_i := 0; v_i < v_amount; v_i := v_i +1){
- log("MTC instance: ", self)
- pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i]
- }
-}
-
-function f_incPTCPhase(in e_Phase p_currentPhase) runs on PTC return e_Phase {
- var e_Phase v_nextPhase
- log("PTC: ", self)
- log("PTC instance: ", self)
- log("Current PTC phase: ", p_currentPhase)
- int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
- log("Next PTC phase:", v_nextPhase)
- return v_nextPhase
-}
-
-function f_sendPhaseEndInd() runs on PTC{
- // just to allow matching with integer ranges on the reception side, as it is not poosible to do so with enums
- var PhaseEndInd v_PhaseEndInd := {phase := v_phase, phase_int := enum2int(v_phase)}
- pt_sync.send(v_PhaseEndInd)
- log("PTC: PhaseEndInd to MTC with content: ", v_PhaseEndInd, self)
- v_phase := f_incPTCPhase(v_phase)
-}
-
-function f_addSyncSlaveSet (in PTC p_slave,
- inout PTCSet p_set) {
- p_set[sizeof(p_set)] := p_slave
- return
-}
-
-function f_incMTCPhase(in e_Phase p_currentPhase) runs on MTC return e_Phase {
- var e_Phase v_nextPhase
- log("MTC: ", self)
- log("Current phase: ", p_currentPhase)
- int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
- log("Next phase:", v_nextPhase)
- return v_nextPhase
-}
-
-function f_awaitEndPhase(in e_Phase p_phase) runs on MTC {
- var integer v_amount:= sizeof(v_PTCSet);
- var integer v_i
- t_guard.start(c_guard)
- var PhaseEndInd v_PhaseEndInd
-
- for(v_i := 0; v_i < v_amount; v_i := v_i +1) {
- alt {
- [] pt_sync.receive (PhaseEndInd: {phase :=p_phase, phase_int := ?}){}
- // value between p_phase +1 and e_testcase_complete:
- [] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int := (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}
- [] t_guard.timeout {
- log("Timeout in MTC phase:", p_phase)
- setverdict(inconc)
- }
- [] pt_sync.receive (?) -> value v_PhaseEndInd {
- log("Unexpected phase recieved: ", v_PhaseEndInd)
- log("Expected phase range: ", p_phase)
- log(" to ", c_testcase_complete)
- setverdict(inconc)
- }
- [] any port.receive{
- log("Expected phase:", p_phase)
- setverdict(inconc)
- }
- }
- }
- t_guard.stop
-}
-
-function f_open_socket(in SocketCAN_open_socket_type v_socket_type)
-runs on PTC
-return SocketCAN_socket_result {
-
- var SocketCAN_socket_result v_result
- timer t_guard
- t_guard.start(c_guard)
-
- var SocketCAN_socket socket
-
- if(v_socket_type==OPEN_CAN_RAW) {
- socket := {domain:=PF_CAN, ptype := SOCK_RAW, protocol:= CAN_RAW};
- } else if (v_socket_type == OPEN_CAN_BCM) {
- socket := {domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_BCM};
- }
- pt_socketCAN.send(socket)
-
- // receive response
- alt {
- [] pt_socketCAN.receive(
- a_SocketCAN_socket_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("SocketCan:Socket opened: ", v_result.id)}
- [] pt_socketCAN.receive(a_SocketCAN_socket_result(a_result(SocketCAN_ERROR)))
- {log("Received Opening Socket failed"); setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- }
- t_guard.stop
- return v_result
-}
-
-function f_ioctl_get_if_index(in SocketCAN_socketid p_socket_id)
-runs on PTC
-return SocketCAN_ioctl_result {
- var SocketCAN_ioctl_result v_result
- timer t_guard
- t_guard.start(c_guard)
-
- pt_socketCAN.send(SocketCAN_ioctl:{id:= p_socket_id, ifu := omit});
- // receive response
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Retrieved interface index", v_result.ifr.if_index)}
- [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_ERROR)))
- {log("Retrieving interface index failed", p_socket_id); setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)
- }
- }
- return v_result
-}
-
-function f_connect(in SocketCAN_socketid p_socket_id,
- in SocketCAN_if_index p_if_index)
-runs on PTC
-return SocketCAN_connect_result {
- var SocketCAN_connect_result v_result
- timer t_guard
- t_guard.start(c_guard)
-
- pt_socketCAN.send(SocketCAN_connect:{id:= p_socket_id, if_index:= p_if_index});
- // SocketCAN_connect receive response
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_connect_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Connecting socket", p_socket_id)}
- [] pt_socketCAN.receive(a_SocketCAN_connect_result(a_result(SocketCAN_ERROR)))
- {log("Connecting socket failed.", p_socket_id); setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- }
- return v_result
-}
-
-function f_bind(in SocketCAN_socketid p_socket_id,
- in SocketCAN_if_index p_if_index)
-runs on PTC
-return SocketCAN_bind_result {
- var SocketCAN_bind_result v_result
- timer t_guard
- t_guard.start(c_guard)
-
- pt_socketCAN.send(SocketCAN_bind:{id:= p_socket_id, if_index:= p_if_index});
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Binding socket", p_socket_id)}
- [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_ERROR))) {}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)
- }
- }
- return v_result
-}
-
-function f_send_data(in SocketCAN_socketid p_socket_id,
- SocketCAN_send_data_ifu p_ifu,
- in SocketCAN_CAN_or_CAN_FD_frame p_CAN_or_CAN_FD_frame)
-runs on PTC
-return SocketCAN_send_data_result {
- var SocketCAN_send_data_result v_result
-
- timer t_guard
- t_guard.start(c_guard)
-
- // note: the optional parameter ifu has been left out.
- pt_socketCAN.send(SocketCAN_send_data:{id:= p_socket_id, ifu := p_ifu, frame := p_CAN_or_CAN_FD_frame});
-
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_send_data_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Sending data", p_socket_id)}
- [] pt_socketCAN.receive(a_SocketCAN_send_data_result(a_result(SocketCAN_ERROR)))
- {log("Sending data failed", p_socket_id); setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)
- }
- }
- return v_result
-}
-
-function f_receive_data(in 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(SocketCAN_receive_CAN_or_CAN_FD_frame:?) -> value v_result
- {log("SocketCan:Unexpected frame received!", v_result)
- setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- }
-}
-
-function f_receive_no_data_but_timeout(in SocketCAN_socketid p_socket_id, in float p_timeout_period)
-runs on PTC {
- var SocketCAN_receive_CAN_or_CAN_FD_frame v_result
-
- timer t_guard
- t_guard.start(p_timeout_period)
-
- // receive frame or timeout
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_receive_CAN_or_CAN_FD_frame(p_socket_id, ?)) -> value v_result {
- log("SocketCan:Unexpected frame received!", v_result)
- setverdict(fail)
- }
- [] t_guard.timeout {
- log("Expected timeout!")}
- }
-}
-
-function f_write_data(in SocketCAN_socketid p_socket_id,
- in SocketCAN_bcm_frame p_bcm_frame)
-runs on PTC {
-
- var SocketCAN_write_data_result v_result
-
- timer t_guard
- t_guard.start(c_guard)
- log("BCM frame: SocketCAN_write_data:{id}:", p_socket_id)
- log("BCM frame: SocketCAN_write_data:{bcm_tx_msg}:", p_bcm_frame)
-
- pt_socketCAN.send(SocketCAN_write_data:{id:= p_socket_id, bcm_tx_msg := p_bcm_frame});
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_write_data_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Writing data on BCM socket: ", p_socket_id)}
- [] pt_socketCAN.receive(a_SocketCAN_write_data_result(a_result(SocketCAN_ERROR)))
- {log("Writing data on BCM socket failed", p_socket_id);
- setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- }
-}
-
-function f_receive_BCM_message(template SocketCAN_socketid p_socket_id, template SocketCAN_bcm_frame p_BCM_message_expected)
-runs on PTC {
- var SocketCAN_receive_BCM_message v_result
-
- timer t_guard
- t_guard.start(c_guard)
-
- // receive frame or timeout
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_receive_BCM_message(p_socket_id, p_BCM_message_expected)) -> value v_result
- {log("SocketCan:Expected frame received", v_result)}
- [] pt_socketCAN.receive(SocketCAN_receive_BCM_message:?) -> value v_result
- {log("SocketCan:Unexpected frame received!", v_result)
- setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)}
- }
-}
-
-function f_setsockopt(in SocketCAN_socketid p_socket_id,
- in SocketCAN_setsockopt_commandu p_command)
-runs on PTC
-return SocketCAN_setsockopt_result{
- var SocketCAN_setsockopt_result v_result
-
- timer t_guard
- t_guard.start(c_guard)
-
- pt_socketCAN.send(SocketCAN_setsockopt:{id:= p_socket_id, command := p_command});
- alt {
- [] pt_socketCAN.receive(a_SocketCAN_setsockopt_result(a_result(SocketCAN_SUCCESS))) -> value v_result
- {log("Writing data", p_socket_id)}
- [] pt_socketCAN.receive(a_SocketCAN_setsockopt_result(a_result(SocketCAN_ERROR)))
- {log("Writing data failed", p_socket_id); setverdict(fail)}
- [] t_guard.timeout {
- log("timeout!")
- setverdict(fail)
- }
- }
- return v_result
-}
-
-function f_close_socket (in SocketCAN_socketid p_socket_id)
-runs on PTC {
- pt_socketCAN.send(SocketCAN_close:{id:= p_socket_id});
-}
-
-function f_open_raw()
-runs on PTC
-return SocketCAN_open_raw_result {
- var SocketCAN_socketid v_socket_id
- v_socket_id := f_open_socket(OPEN_CAN_RAW).id
- var SocketCAN_ifr v_ifr
- v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
- var SocketCAN_bind_result v_bind_result
- v_bind_result := f_bind(v_socket_id, v_ifr.if_index)
-
- var SocketCAN_open_raw_result v_result
- v_result := {ifr := v_ifr, socket_id := v_socket_id}
-
- return v_result
-}
-
-function f_open_bcm()
-runs on PTC
-return SocketCAN_socketid {
- var SocketCAN_socketid v_socket_id
- v_socket_id := f_open_socket(OPEN_CAN_BCM).id
- log("Opening BCM socket_id", v_socket_id)
- var SocketCAN_ifr v_ifr
- v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
- var SocketCAN_connect_result v_connect_result
- v_connect_result := f_connect(v_socket_id, v_ifr.if_index)
-
- return v_socket_id
-}
-
-function f_ptc_RawSendInitiator(in e_Phase p_phase,
- in SocketCAN_CAN_or_CAN_FD_frame v_frame_send) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_id
- var SocketCAN_ifr v_ifr
- var SocketCAN_send_data_ifu v_ifu
-
- alt_awaitPhaseStartReq(e_open_socket)
- var SocketCAN_open_raw_result res
- res := f_open_raw();
- v_socket_id := res.socket_id
- v_ifr := res.ifr
- v_ifu.if_name := v_ifr.if_name
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_phase)
- var SocketCAN_send_data_result send_data_result
- send_data_result := f_send_data(v_socket_id,
- v_ifu,
- v_frame_send)
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-function f_ptc_RawFrameReceiver(in e_Phase p_phase,
- template SocketCAN_CAN_or_CAN_FD_frame p_frame_expected) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_raw_id
- var SocketCAN_ifr v_ifr
- var SocketCAN_send_data_ifu v_ifu
-
- alt_awaitPhaseStartReq(e_open_socket)
- var SocketCAN_open_raw_result res
- res := f_open_raw();
- v_socket_raw_id := res.socket_id
- v_ifr := res.ifr
- v_ifu.if_name := v_ifr.if_name
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_phase)
- f_receive_data(v_socket_raw_id, p_frame_expected)
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_raw_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-function f_ptc_RawFrameSequenceReceiver(
- in e_Phase p_sequence_expected_phase,
- template SocketCAN_CAN_or_CAN_FD_frames p_frame_sequence_expected,
- in e_Phase p_no_further_frames_expected_phase,
- in float p_timeout_period) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_raw_id
- var SocketCAN_ifr v_ifr
- var SocketCAN_send_data_ifu v_ifu
-
- alt_awaitPhaseStartReq(e_open_socket)
- var SocketCAN_open_raw_result res
- res := f_open_raw();
- v_socket_raw_id := res.socket_id
- v_ifr := res.ifr
- v_ifu.if_name := v_ifr.if_name
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_sequence_expected_phase)
- var integer v_i
- for( v_i := 0; v_i < lengthof(p_frame_sequence_expected); v_i := v_i +1) {
- f_receive_data(v_socket_raw_id, p_frame_sequence_expected[v_i])
- }
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_no_further_frames_expected_phase)
- f_receive_no_data_but_timeout(v_socket_raw_id, p_timeout_period)
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_raw_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-function f_ptc_bcmComandSendInitiator(in BCM_cmds p_cmd_list) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_bcm_id
-
- alt_awaitPhaseStartReq(e_open_socket)
- v_socket_bcm_id := f_open_bcm()
- f_sendPhaseEndInd()
- var integer v_i
- for( v_i := 0; v_i < lengthof(p_cmd_list); v_i := v_i +1) {
- alt_awaitPhaseStartReq(p_cmd_list[v_i].phase)
- // write mesage to BCM using v_socket_bcm_id
- f_write_data(v_socket_bcm_id, p_cmd_list[v_i].bcm_frame)
- f_sendPhaseEndInd()
- }
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_bcm_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-// the following function is work in progress to receive messages from BCM
-function f_ptc_bcmComandSendReceiveInitiator(in BCM_cmds p_cmd_list) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_bcm_id
-
- alt_awaitPhaseStartReq(e_open_socket)
- v_socket_bcm_id := f_open_bcm()
- f_sendPhaseEndInd()
- var integer v_i
- for( v_i := 0; v_i < lengthof(p_cmd_list); v_i := v_i +1) {
- alt_awaitPhaseStartReq(p_cmd_list[v_i].phase)
- // write mesage to BCM using v_socket_bcm_id
- f_write_data(v_socket_bcm_id, p_cmd_list[v_i].bcm_frame)
- f_receive_BCM_message(v_socket_bcm_id, ?)
- f_sendPhaseEndInd()
- }
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_bcm_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-function f_ptc_bcmSendInitiator(in e_Phase p_phase,
- in SocketCAN_bcm_frame p_bcm_frame) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_bcm_id
-
- alt_awaitPhaseStartReq(e_open_socket)
- v_socket_bcm_id := f_open_bcm()
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_phase)
- // write mesage to BCM using v_socket_bcm_id
- f_write_data(v_socket_bcm_id, p_bcm_frame)
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_bcm_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-function f_raw_setsockopt(in e_Phase p_phase,
- in SocketCAN_setsockopt_commandu p_setsockopt_command) runs on PTC {
- map(self:pt_socketCAN, system:pt_socketCAN)
- var SocketCAN_socketid v_socket_id
- var SocketCAN_ifr v_ifr
- var SocketCAN_send_data_ifu v_ifu
-
- alt_awaitPhaseStartReq(e_open_socket)
- var SocketCAN_open_raw_result res
- res := f_open_raw();
- v_socket_id := res.socket_id
- v_ifr := res.ifr
- v_ifu.if_name := v_ifr.if_name
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(p_phase)
- // send command to setsockopt
- var SocketCAN_setsockopt_result v_setsockopt_result
-
- // configure filters:
- v_setsockopt_result := f_setsockopt(v_socket_id, p_setsockopt_command)
- f_sendPhaseEndInd()
-
- alt_awaitPhaseStartReq(e_close_socket)
- f_close_socket (v_socket_id)
- unmap(self:pt_socketCAN, system:pt_socketCAN)
- setverdict(pass)
- f_sendPhaseEndInd()
-}
-
-// control
-// {
-// execute(tc_can_raw0())
-// }
-}
+/* Copyright (c) 2010, 2016 Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: SocketCANtest.ttcn
+// Description: SocketCAN port type test
+//
+// Revision R1A
+
+module SocketCANtest {
+
+import from SocketCAN_Types all;
+import from SocketCAN_PortType all;
+import from SocketCAN_Templates all;
+import from Bcm all
+
+const float c_guard := 10.0
+
+type enumerated SocketCAN_open_socket_type
+{
+ OPEN_CAN_RAW,
+ OPEN_CAN_BCM,
+ OPEN_CAN_ISOTP
+}
+
+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
+}
+
+type record SocketCAN_open_raw_result{
+ SocketCAN_ifr ifr,
+ SocketCAN_socketid socket_id}
+
+type record BCM_cmd {
+ e_Phase phase,
+ SocketCAN_bcm_frame bcm_frame
+}
+
+type record length (0 .. CAN_FRAME_MAX_NUMBER) of BCM_cmd BCM_cmds
+
+type record length (0 .. CAN_FRAME_MAX_NUMBER) of SocketCAN_CAN_or_CAN_FD_frame SocketCAN_CAN_or_CAN_FD_frames
+
+// workarounds as (x .. enum2int(e_testcase_complete)) fails but:
+// workarounds as (x .. enum2int(c_testcase_complete)) works
+const e_Phase c_firstPhase := e_open_socket
+const e_Phase c_testcase_complete := e_testcase_complete
+
+type record PhaseStartReq {
+ e_Phase phase,
+ integer phase_int
+}
+type record PhaseEndInd {
+ e_Phase phase,
+ integer phase_int
+}
+
+type port SyncMasterPort message {
+ out PhaseStartReq
+ in PhaseEndInd
+} with { extension "internal" }
+
+type port SyncSlavePort message {
+ in PhaseStartReq
+ out PhaseEndInd
+} with { extension "internal" }
+
+type record of PTC PTCSet
+
+
+type component PTC {
+ port SyncSlavePort pt_sync
+ port SocketCAN_PT pt_socketCAN
+ var e_Phase v_phase := c_firstPhase
+}
+
+//component declarations
+type component MTC{
+ timer t_guard
+ port SyncMasterPort pt_sync
+ var PTCSet v_PTCSet := {}
+}
+
+altstep alt_awaitPhaseStartReq(in e_Phase p_phase) runs on PTC {
+ var PhaseStartReq v_PhaseStartReq;
+ [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
+ log("PTC name: ", self)
+ log("Waits for start of phase: ", p_phase)
+ }
+ // between v_phase and p_phase
+ [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int := (enum2int(c_firstPhase) .. enum2int(v_phase))}) -> value v_PhaseStartReq
+ {
+ //v_phase := f_incPhase(v_phase)
+ log("PTC name: ", self)
+ log("Waits for start of phase: ", p_phase)
+ log("Received completion of phase: ", p_phase)
+ f_sendPhaseEndInd()
+ repeat
+ }
+ [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int :=?}) -> value v_PhaseStartReq
+ {log("Received unexpected message:", v_PhaseStartReq);setverdict(inconc)}
+}
+
+function f_startPhase (in e_Phase p_phase) runs on MTC {
+ var integer v_i
+ var integer v_amount := sizeof(v_PTCSet)
+ var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}
+
+ for (v_i := 0; v_i < v_amount; v_i := v_i +1){
+ log("MTC instance: ", self)
+ pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i]
+ }
+}
+
+function f_incPTCPhase(in e_Phase p_currentPhase) runs on PTC return e_Phase {
+ var e_Phase v_nextPhase
+ log("PTC: ", self)
+ log("PTC instance: ", self)
+ log("Current PTC phase: ", p_currentPhase)
+ int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
+ log("Next PTC phase:", v_nextPhase)
+ return v_nextPhase
+}
+
+function f_sendPhaseEndInd() runs on PTC{
+ // just to allow matching with integer ranges on the reception side, as it is not poosible to do so with enums
+ var PhaseEndInd v_PhaseEndInd := {phase := v_phase, phase_int := enum2int(v_phase)}
+ pt_sync.send(v_PhaseEndInd)
+ log("PTC: PhaseEndInd to MTC with content: ", v_PhaseEndInd, self)
+ v_phase := f_incPTCPhase(v_phase)
+}
+
+function f_addSyncSlaveSet (in PTC p_slave,
+ inout PTCSet p_set) {
+ p_set[sizeof(p_set)] := p_slave
+ return
+}
+
+function f_incMTCPhase(in e_Phase p_currentPhase) runs on MTC return e_Phase {
+ var e_Phase v_nextPhase
+ log("MTC: ", self)
+ log("Current phase: ", p_currentPhase)
+ int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
+ log("Next phase:", v_nextPhase)
+ return v_nextPhase
+}
+
+function f_awaitEndPhase(in e_Phase p_phase) runs on MTC {
+ var integer v_amount:= sizeof(v_PTCSet);
+ var integer v_i
+ t_guard.start(c_guard)
+ var PhaseEndInd v_PhaseEndInd
+
+ for(v_i := 0; v_i < v_amount; v_i := v_i +1) {
+ alt {
+ [] pt_sync.receive (PhaseEndInd: {phase :=p_phase, phase_int := ?}){}
+ // value between p_phase +1 and e_testcase_complete:
+ [] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int := (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}
+ [] t_guard.timeout {
+ log("Timeout in MTC phase:", p_phase)
+ setverdict(inconc)
+ }
+ [] pt_sync.receive (?) -> value v_PhaseEndInd {
+ log("Unexpected phase recieved: ", v_PhaseEndInd)
+ log("Expected phase range: ", p_phase)
+ log(" to ", c_testcase_complete)
+ setverdict(inconc)
+ }
+ [] any port.receive{
+ log("Expected phase:", p_phase)
+ setverdict(inconc)
+ }
+ }
+ }
+ t_guard.stop
+}
+
+function f_open_socket(in SocketCAN_open_socket_type v_socket_type)
+runs on PTC
+return SocketCAN_socket_result {
+
+ var SocketCAN_socket_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ var SocketCAN_socket socket
+
+ if(v_socket_type==OPEN_CAN_RAW) {
+ socket := {domain:=PF_CAN, ptype := SOCK_RAW, protocol:= CAN_RAW};
+ } else if (v_socket_type == OPEN_CAN_BCM) {
+ socket := {domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_BCM};
+ }
+ pt_socketCAN.send(socket)
+
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(
+ a_SocketCAN_socket_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("SocketCan:Socket opened: ", v_result.id)}
+ [] pt_socketCAN.receive(a_SocketCAN_socket_result(a_result(SocketCAN_ERROR)))
+ {log("Received Opening Socket failed"); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+ t_guard.stop
+ return v_result
+}
+
+function f_ioctl_get_if_index(in SocketCAN_socketid p_socket_id)
+runs on PTC
+return SocketCAN_ioctl_result {
+ var SocketCAN_ioctl_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_ioctl:{id:= p_socket_id, ifu := omit});
+ // receive response
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Retrieved interface index", v_result.ifr.if_index)}
+ [] pt_socketCAN.receive(a_SocketCAN_ioctl_result(a_result(SocketCAN_ERROR)))
+ {log("Retrieving interface index failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_connect(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_if_index p_if_index)
+runs on PTC
+return SocketCAN_connect_result {
+ var SocketCAN_connect_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_connect:{id:= p_socket_id, connectu := {bcm := {if_index:= p_if_index}}});
+ // SocketCAN_connect receive response
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_connect_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Connecting socket", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_connect_result(a_result(SocketCAN_ERROR)))
+ {log("Connecting socket failed.", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+ return v_result
+}
+
+function f_bind(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_if_index p_if_index)
+runs on PTC
+return SocketCAN_bind_result {
+ var SocketCAN_bind_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+ pt_socketCAN.send(SocketCAN_bind:{id:= p_socket_id, bindu := {raw := {if_index:= p_if_index}}});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Binding socket", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_bind_result(a_result(SocketCAN_ERROR))) {}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_send_data(in SocketCAN_socketid p_socket_id,
+ SocketCAN_send_data_ifu p_ifu,
+ in SocketCAN_CAN_or_CAN_FD_frame p_CAN_or_CAN_FD_frame)
+runs on PTC
+return SocketCAN_send_data_result {
+ var SocketCAN_send_data_result v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ // note: the optional parameter ifu has been left out.
+ pt_socketCAN.send(SocketCAN_send_data:{id:= p_socket_id, ifu := p_ifu, frame := p_CAN_or_CAN_FD_frame});
+
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_send_data_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Sending data", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_send_data_result(a_result(SocketCAN_ERROR)))
+ {log("Sending data failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+
+function f_receive_data(in 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(SocketCAN_receive_CAN_or_CAN_FD_frame:?) -> value v_result
+ {log("SocketCan:Unexpected frame received!", v_result)
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+}
+
+function f_receive_no_data_but_timeout(in SocketCAN_socketid p_socket_id, in float p_timeout_period)
+runs on PTC {
+ var SocketCAN_receive_CAN_or_CAN_FD_frame v_result
+
+ timer t_guard
+ t_guard.start(p_timeout_period)
+
+ // receive frame or timeout
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_CAN_or_CAN_FD_frame(p_socket_id, ?)) -> value v_result {
+ log("SocketCan:Unexpected frame received!", v_result)
+ setverdict(fail)
+ }
+ [] t_guard.timeout {
+ log("Expected timeout!")}
+ }
+}
+
+function f_write_data(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_bcm_frame p_bcm_frame)
+runs on PTC {
+
+ var SocketCAN_write_data_result v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+ log("BCM frame: SocketCAN_write_data:{id}:", p_socket_id)
+ log("BCM frame: SocketCAN_write_data:{bcm_tx_msg}:", p_bcm_frame)
+
+ pt_socketCAN.send(SocketCAN_write_data:{id:= p_socket_id, bcm_tx_msg := p_bcm_frame});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_write_data_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Writing data on BCM socket: ", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_write_data_result(a_result(SocketCAN_ERROR)))
+ {log("Writing data on BCM socket failed", p_socket_id);
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+}
+
+function f_receive_BCM_message(template SocketCAN_socketid p_socket_id, template SocketCAN_bcm_frame p_BCM_message_expected)
+runs on PTC {
+ var SocketCAN_receive_BCM_message v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ // receive frame or timeout
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_BCM_message(p_socket_id, p_BCM_message_expected)) -> value v_result
+ {log("SocketCan:Expected frame received", v_result)}
+ [] pt_socketCAN.receive(SocketCAN_receive_BCM_message:?) -> value v_result
+ {log("SocketCan:Unexpected frame received!", v_result)
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+}
+
+function f_setsockopt(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_setsockopt_commandu p_command)
+runs on PTC
+return SocketCAN_setsockopt_result{
+ var SocketCAN_setsockopt_result v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_setsockopt:{id:= p_socket_id, command := p_command});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_setsockopt_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Writing data", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_setsockopt_result(a_result(SocketCAN_ERROR)))
+ {log("Writing data failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_close_socket (in SocketCAN_socketid p_socket_id)
+runs on PTC {
+ pt_socketCAN.send(SocketCAN_close:{id:= p_socket_id});
+}
+
+function f_open_raw()
+runs on PTC
+return SocketCAN_open_raw_result {
+ var SocketCAN_socketid v_socket_id
+ v_socket_id := f_open_socket(OPEN_CAN_RAW).id
+ var SocketCAN_ifr v_ifr
+ v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id, v_ifr.if_index)
+
+ var SocketCAN_open_raw_result v_result
+ v_result := {ifr := v_ifr, socket_id := v_socket_id}
+
+ return v_result
+}
+
+function f_open_bcm()
+runs on PTC
+return SocketCAN_socketid {
+ var SocketCAN_socketid v_socket_id
+ v_socket_id := f_open_socket(OPEN_CAN_BCM).id
+ log("Opening BCM socket_id", v_socket_id)
+ var SocketCAN_ifr v_ifr
+ v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
+ var SocketCAN_connect_result v_connect_result
+ v_connect_result := f_connect(v_socket_id, v_ifr.if_index)
+
+ return v_socket_id
+}
+
+function f_ptc_RawSendInitiator(in e_Phase p_phase,
+ in SocketCAN_CAN_or_CAN_FD_frame v_frame_send) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_raw_result res
+ res := f_open_raw();
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ var SocketCAN_send_data_result send_data_result
+ send_data_result := f_send_data(v_socket_id,
+ v_ifu,
+ v_frame_send)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+function f_ptc_RawFrameReceiver(in e_Phase p_phase,
+ template SocketCAN_CAN_or_CAN_FD_frame p_frame_expected) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_raw_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_raw_result res
+ res := f_open_raw();
+ v_socket_raw_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ f_receive_data(v_socket_raw_id, p_frame_expected)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_raw_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+function f_ptc_RawFrameSequenceReceiver(
+ in e_Phase p_sequence_expected_phase,
+ template SocketCAN_CAN_or_CAN_FD_frames p_frame_sequence_expected,
+ in e_Phase p_no_further_frames_expected_phase,
+ in float p_timeout_period) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_raw_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_raw_result res
+ res := f_open_raw();
+ v_socket_raw_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_sequence_expected_phase)
+ var integer v_i
+ for( v_i := 0; v_i < lengthof(p_frame_sequence_expected); v_i := v_i +1) {
+ f_receive_data(v_socket_raw_id, p_frame_sequence_expected[v_i])
+ }
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_no_further_frames_expected_phase)
+ f_receive_no_data_but_timeout(v_socket_raw_id, p_timeout_period)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_raw_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+function f_ptc_bcmComandSendInitiator(in BCM_cmds p_cmd_list) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_bcm_id
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ v_socket_bcm_id := f_open_bcm()
+ f_sendPhaseEndInd()
+ var integer v_i
+ for( v_i := 0; v_i < lengthof(p_cmd_list); v_i := v_i +1) {
+ alt_awaitPhaseStartReq(p_cmd_list[v_i].phase)
+ // write mesage to BCM using v_socket_bcm_id
+ f_write_data(v_socket_bcm_id, p_cmd_list[v_i].bcm_frame)
+ f_sendPhaseEndInd()
+ }
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_bcm_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+// the following function is work in progress to receive messages from BCM
+function f_ptc_bcmComandSendReceiveInitiator(in BCM_cmds p_cmd_list) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_bcm_id
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ v_socket_bcm_id := f_open_bcm()
+ f_sendPhaseEndInd()
+ var integer v_i
+ for( v_i := 0; v_i < lengthof(p_cmd_list); v_i := v_i +1) {
+ alt_awaitPhaseStartReq(p_cmd_list[v_i].phase)
+ // write mesage to BCM using v_socket_bcm_id
+ f_write_data(v_socket_bcm_id, p_cmd_list[v_i].bcm_frame)
+ f_receive_BCM_message(v_socket_bcm_id, ?)
+ f_sendPhaseEndInd()
+ }
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_bcm_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+function f_ptc_bcmSendInitiator(in e_Phase p_phase,
+ in SocketCAN_bcm_frame p_bcm_frame) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_bcm_id
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ v_socket_bcm_id := f_open_bcm()
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ // write mesage to BCM using v_socket_bcm_id
+ f_write_data(v_socket_bcm_id, p_bcm_frame)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_bcm_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+function f_raw_setsockopt(in e_Phase p_phase,
+ in SocketCAN_setsockopt_commandu p_setsockopt_command) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+ var SocketCAN_send_data_ifu v_ifu
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_raw_result res
+ res := f_open_raw();
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ v_ifu.if_name := v_ifr.if_name
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ // send command to setsockopt
+ var SocketCAN_setsockopt_result v_setsockopt_result
+
+ // configure filters:
+ v_setsockopt_result := f_setsockopt(v_socket_id, p_setsockopt_command)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(e_close_socket)
+ f_close_socket (v_socket_id)
+ unmap(self:pt_socketCAN, system:pt_socketCAN)
+ setverdict(pass)
+ f_sendPhaseEndInd()
+}
+
+// control
+// {
+// execute(tc_can_raw0())
+// }
+}
diff --git a/demo/initscript.sh b/demo/initscript.sh
index dcdd192..b9a0550 100755
--- a/demo/initscript.sh
+++ b/demo/initscript.sh
@@ -9,7 +9,7 @@
# Michael Josenhans
##############################################################################
-
+# Revision R1A
#!/bin/bash
diff --git a/doc/README.md b/doc/README.md
index 18bea74..3ad912b 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -88,6 +88,20 @@
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
+ are supported. Feel free to request needed options.
+
+ First install the isotp kernel module as descibed here:
+ https://github.com/hartkopp/can-isotp-modules
+
+ ./make_isotp.sh
+ sudo insmod ./can-isotp.ko
+
+
+ There is an endlessly running test case:
+ ttcn3_start SocketCAN SocketCAN.cfg Isotptest.tc_Isotp_Example001
+
-Merging of logfiles:
To merge the logfies from multiple Parallel Test Componets (PTCs) from a
single run in timely order into sigle file, run:
diff --git a/src/Bcm.ttcn b/src/Bcm.ttcn
index 7a1c20e..7a4c706 100644
--- a/src/Bcm.ttcn
+++ b/src/Bcm.ttcn
@@ -1,86 +1,86 @@
-/******************************************************************************
- * Copyright (c) 2010, 2016 Ericsson AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Michael Josenhans
- ******************************************************************************/
-
-
-
-module Bcm
-{
-import from Can all;
-import from General_Types all;
-
-const integer CAN_FRAME_MAX_NUMBER := 256;
-
-type enumerated BcmFlagsBitIndex_enum {
- e_CAN_BCM_SETTIMER_BITINDEX (0),
- e_CAN_BCM_STARTTIMER_BITINDEX (1),
- e_CAN_BCM_TX_COUNTEVT_BITINDEX (2),
- e_CAN_BCM_TX_ANNOUNCE_BITINDEX (3),
- e_CAN_BCM_TX_CP_CAN_ID_BITINDEX (4),
- e_CAN_BCM_RX_FILTER_ID_BITINDEX (5),
- e_CAN_BCM_RX_CHECK_DLC_BITINDEX (6),
- e_CAN_BCM_RX_NO_AUTOTIMER_BITINDEX (7),
- e_CAN_BCM_RX_ANNOUNCE_RESUME_BITINDEX (8),
- e_CAN_BCM_TX_RESET_MULTI_IDX_BITINDEX (9),
- e_CAN_BCM_RX_RTR_FRAME_BITINDEX (10)
-}
-
-type enumerated BcmFlags_enum {
- e_CAN_BCM_SETTIMER (1),
- e_CAN_BCM_STARTTIMER (2),
- e_CAN_BCM_TX_COUNTEVT (4),
- e_CAN_BCM_TX_ANNOUNCE (8),
- e_CAN_BCM_TX_CP_CAN_ID (16),
- e_CAN_BCM_RX_FILTER_ID (32),
- e_CAN_BCM_RX_CHECK_DLC (64),
- e_CAN_BCM_RX_NO_AUTOTIMER (128),
- e_CAN_BCM_RX_ANNOUNCE_RESUME (256),
- e_CAN_BCM_TX_RESET_MULTI_IDX (512),
- e_CAN_BCM_RX_RTR_FRAME (1024)
-}
-
-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)
-}
-
-type integer Bcm_long (-2147483648 .. +2147483647);
-
-type record Bcm_timeval {
- Bcm_long tv_sec,
- Bcm_long tv_usec
-}
-
-//type record length (0 .. CAN_FRAME_MAX_NUMBER) of CAN_frame Can_frame;
-
-type record SocketCAN_bcm_frame {
- OCT4 opcode,
- bitstring flags length (32),
- LIN4_BO_LAST count,
- Bcm_timeval ival1,
- Bcm_timeval ival2,
- CAN_id can_id,
- union {
- record length (0 .. CAN_FRAME_MAX_NUMBER) of CAN_frame can_frame,
- record length (0 .. CAN_FRAME_MAX_NUMBER) of CANFD_frame canfd_frame
- } frames // should become optional and the records have at least the length 1
-}
-
-}
+/******************************************************************************
+ * Copyright (c) 2010, 2016 Ericsson AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Michael Josenhans
+ ******************************************************************************/
+
+//Revision R1A
+
+module Bcm
+{
+import from Can all;
+import from General_Types all;
+
+const integer CAN_FRAME_MAX_NUMBER := 256;
+
+type enumerated BcmFlagsBitIndex_enum {
+ e_CAN_BCM_SETTIMER_BITINDEX (0),
+ e_CAN_BCM_STARTTIMER_BITINDEX (1),
+ e_CAN_BCM_TX_COUNTEVT_BITINDEX (2),
+ e_CAN_BCM_TX_ANNOUNCE_BITINDEX (3),
+ e_CAN_BCM_TX_CP_CAN_ID_BITINDEX (4),
+ e_CAN_BCM_RX_FILTER_ID_BITINDEX (5),
+ e_CAN_BCM_RX_CHECK_DLC_BITINDEX (6),
+ e_CAN_BCM_RX_NO_AUTOTIMER_BITINDEX (7),
+ e_CAN_BCM_RX_ANNOUNCE_RESUME_BITINDEX (8),
+ e_CAN_BCM_TX_RESET_MULTI_IDX_BITINDEX (9),
+ e_CAN_BCM_RX_RTR_FRAME_BITINDEX (10)
+}
+
+type enumerated BcmFlags_enum {
+ e_CAN_BCM_SETTIMER (1),
+ e_CAN_BCM_STARTTIMER (2),
+ e_CAN_BCM_TX_COUNTEVT (4),
+ e_CAN_BCM_TX_ANNOUNCE (8),
+ e_CAN_BCM_TX_CP_CAN_ID (16),
+ e_CAN_BCM_RX_FILTER_ID (32),
+ e_CAN_BCM_RX_CHECK_DLC (64),
+ e_CAN_BCM_RX_NO_AUTOTIMER (128),
+ e_CAN_BCM_RX_ANNOUNCE_RESUME (256),
+ e_CAN_BCM_TX_RESET_MULTI_IDX (512),
+ e_CAN_BCM_RX_RTR_FRAME (1024)
+}
+
+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)
+}
+
+type integer Bcm_long (-2147483648 .. +2147483647);
+
+type record Bcm_timeval {
+ Bcm_long tv_sec,
+ Bcm_long tv_usec
+}
+
+//type record length (0 .. CAN_FRAME_MAX_NUMBER) of CAN_frame Can_frame;
+
+type record SocketCAN_bcm_frame {
+ OCT4 opcode,
+ bitstring flags length (32),
+ LIN4_BO_LAST count,
+ Bcm_timeval ival1,
+ Bcm_timeval ival2,
+ CAN_id can_id,
+ union {
+ record length (0 .. CAN_FRAME_MAX_NUMBER) of CAN_frame can_frame,
+ record length (0 .. CAN_FRAME_MAX_NUMBER) of CANFD_frame canfd_frame
+ } frames // should become optional and the records have at least the length 1
+}
+
+}
diff --git a/src/Can.ttcn b/src/Can.ttcn
index a666490..1a137d7 100644
--- a/src/Can.ttcn
+++ b/src/Can.ttcn
@@ -1,155 +1,155 @@
-/******************************************************************************
- * Copyright (c) 2010, 2016 Ericsson AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Michael Josenhans
- ******************************************************************************/
-
-
-
-module Can
-{
-import from General_Types all;
-
-// special address description flags for the CAN_ID
-
-// should become an enum, definedable as hex
-const octetstring CAN_EFF_FLAG := '80000000'O; // EFF/SFF is set in the MSB
-const octetstring CAN_RTR_FLAG := '40000000'O; // remote transmission request
-const octetstring CAN_ERR_FLAG := '20000000'O; // error message frame
-
-// valid bits in CAN ID for frame formats
-const octetstring CAN_SFF_MASK := '000007FF'O // standard frame format (SFF)
-const octetstring CAN_EFF_MASK := '1FFFFFFF'O // extended frame format (EFF)
-const octetstring CAN_ERR_MASK := '1FFFFFFF'O // omit EFF, RTR, ERR flags
-
-template octetstring t_CAN_EFF_FLAG:=(
-'80???'O,'81???'O,'82???'O,'83???'O,'84???'O,'85???'O,'86???'O,'87???'O,
-'88???'O,'89???'O,'8A???'O,'8B???'O,'8C???'O,'8D???'O,'8E???'O,'8F???'O,
-'90???'O,'91???'O,'92???'O,'93???'O,'94???'O,'95???'O,'96???'O,'97???'O,
-'98???'O,'99???'O,'9A???'O,'9B???'O,'9C???'O,'9D???'O,'9E???'O,'9F???'O,
-'A0???'O,'A1???'O,'A2???'O,'A3???'O,'A4???'O,'A5???'O,'A6???'O,'A7???'O,
-'A8???'O,'A9???'O,'AA???'O,'AB???'O,'AC???'O,'AD???'O,'AE???'O,'AF???'O,
-'B0???'O,'B1???'O,'B2???'O,'B3???'O,'B4???'O,'B5???'O,'B6???'O,'B7???'O,
-'B8???'O,'B9???'O,'BA???'O,'BB???'O,'BC???'O,'BD???'O,'BE???'O,'BF???'O,
-'C0???'O,'C1???'O,'C2???'O,'C3???'O,'C4???'O,'C5???'O,'C6???'O,'C7???'O,
-'C8???'O,'C9???'O,'CA???'O,'CB???'O,'CC???'O,'CD???'O,'CE???'O,'CF???'O,
-'D0???'O,'D1???'O,'D2???'O,'D3???'O,'D4???'O,'D5???'O,'D6???'O,'D7???'O,
-'D8???'O,'D9???'O,'DA???'O,'DB???'O,'DC???'O,'DD???'O,'DE???'O,'DF???'O,
-'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
-'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
-'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
-'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
-
-template octetstring t_CAN_SFF_FLAG:=(
-'00???'O,'01???'O,'02???'O,'03???'O,'04???'O,'05???'O,'06???'O,'07???'O,
-'08???'O,'09???'O,'0A???'O,'0B???'O,'0C???'O,'0D???'O,'0E???'O,'0F???'O,
-'10???'O,'11???'O,'12???'O,'13???'O,'14???'O,'15???'O,'16???'O,'17???'O,
-'18???'O,'19???'O,'1A???'O,'1B???'O,'1C???'O,'1D???'O,'1E???'O,'1F???'O,
-'20???'O,'21???'O,'22???'O,'23???'O,'24???'O,'25???'O,'26???'O,'27???'O,
-'28???'O,'29???'O,'2A???'O,'2B???'O,'2C???'O,'2D???'O,'2E???'O,'2F???'O,
-'30???'O,'31???'O,'32???'O,'33???'O,'34???'O,'35???'O,'36???'O,'37???'O,
-'38???'O,'39???'O,'3A???'O,'3B???'O,'3C???'O,'3D???'O,'3E???'O,'3F???'O,
-'40???'O,'41???'O,'42???'O,'43???'O,'44???'O,'45???'O,'46???'O,'47???'O,
-'48???'O,'49???'O,'4A???'O,'4B???'O,'4C???'O,'4D???'O,'4E???'O,'4F???'O,
-'50???'O,'51???'O,'52???'O,'53???'O,'54???'O,'55???'O,'56???'O,'57???'O,
-'58???'O,'59???'O,'5A???'O,'5B???'O,'5C???'O,'5D???'O,'5E???'O,'5F???'O,
-'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
-'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
-'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
-'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O);
-
-template octetstring t_CAN_RTR_FLAG:=(
-'40???'O,'41???'O,'42???'O,'43???'O,'44???'O,'45???'O,'46???'O,'47???'O,
-'48???'O,'49???'O,'4A???'O,'4B???'O,'4C???'O,'4D???'O,'4E???'O,'4F???'O,
-'50???'O,'51???'O,'52???'O,'53???'O,'54???'O,'55???'O,'56???'O,'57???'O,
-'58???'O,'59???'O,'5A???'O,'5B???'O,'5C???'O,'5D???'O,'5E???'O,'5F???'O,
-'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
-'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
-'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
-'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O,
-'C0???'O,'C1???'O,'C2???'O,'C3???'O,'C4???'O,'C5???'O,'C6???'O,'C7???'O,
-'C8???'O,'C9???'O,'CA???'O,'CB???'O,'CC???'O,'CD???'O,'CE???'O,'CF???'O,
-'D0???'O,'D1???'O,'D2???'O,'D3???'O,'D4???'O,'D5???'O,'D6???'O,'D7???'O,
-'D8???'O,'D9???'O,'DA???'O,'DB???'O,'DC???'O,'DD???'O,'DE???'O,'DF???'O,
-'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
-'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
-'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
-'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
-
-template octetstring t_CAN_ERR_FLAG:=(
-'20???'O,'21???'O,'22???'O,'23???'O,'24???'O,'25???'O,'26???'O,'27???'O,
-'28???'O,'29???'O,'2A???'O,'2B???'O,'2C???'O,'2D???'O,'2E???'O,'2F???'O,
-'30???'O,'31???'O,'32???'O,'33???'O,'34???'O,'35???'O,'36???'O,'37???'O,
-'38???'O,'39???'O,'3A???'O,'3B???'O,'3C???'O,'3D???'O,'3E???'O,'3F???'O,
-'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
-'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
-'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
-'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O,
-'A0???'O,'A1???'O,'A2???'O,'A3???'O,'A4???'O,'A5???'O,'A6???'O,'A7???'O,
-'A8???'O,'A9???'O,'AA???'O,'AB???'O,'AC???'O,'AD???'O,'AE???'O,'AF???'O,
-'B0???'O,'B1???'O,'B2???'O,'B3???'O,'B4???'O,'B5???'O,'B6???'O,'B7???'O,
-'B8???'O,'B9???'O,'BA???'O,'BB???'O,'BC???'O,'BD???'O,'BE???'O,'BF???'O,
-'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
-'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
-'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
-'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
-
-type enumerated AdresseFamily_enum
-{
-// Supported address families
-PF_CAN (29) // Controller Area Network
-}
-// Supported address families
-
-const integer AF_CAN := 29; // See /include/linux/socket.h
-
-type enumerated ProtocolFamily_enum {
-//SOCK_STREAM (1),
-SOCK_DGRAM (2),
-SOCK_RAW (3)
-//SOCK_RDM (4),
-//SOCK_SEQPACKET (5),
-//SOCK_DCCP (6),
-//SOCK_PACKET (10)
-}
-
-// particular protocols of the protocol family PF_CAN
-type enumerated PF_CAN_protocols_enum {
-CAN_RAW (1), // RAW sockets
-CAN_BCM (2), // Broadcast Manager
-CAN_TP16 (3), // VAG Transport Protocol v1.6
-CAN_TP20 (4), // VAG Transport Protocol v2.0
-CAN_MCNET (5), // Bosch MCNet
-CAN_ISOTP (6), // ISO 15765-2 Transport Protocol
-CAN_NPROTO (7)
-}
-
-// CAN payload length and DLC definitions according to ISO 11898-1
-// See /usr/include/linux/can.h
-const integer CAN_MAX_DLEN := 8;
-
-// CAN FD payload length and DLC definitions according to ISO 11898-7
-// See /usr/include/linux/can.h
-const integer CANFD_MAX_DLEN := 64;
-
-// should be octetstring length (4);
-type octetstring CAN_id length (4);
-type bitstring CAN_flags length (8); // only used with CAN FD
-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)
-}
-}
+/******************************************************************************
+ * Copyright (c) 2010, 2016 Ericsson AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Michael Josenhans
+ ******************************************************************************/
+
+//Revision R1A
+
+module Can
+{
+import from General_Types all;
+
+// special address description flags for the CAN_ID
+
+// should become an enum, definedable as hex
+const octetstring CAN_EFF_FLAG := '80000000'O; // EFF/SFF is set in the MSB
+const octetstring CAN_RTR_FLAG := '40000000'O; // remote transmission request
+const octetstring CAN_ERR_FLAG := '20000000'O; // error message frame
+
+// valid bits in CAN ID for frame formats
+const octetstring CAN_SFF_MASK := '000007FF'O // standard frame format (SFF)
+const octetstring CAN_EFF_MASK := '1FFFFFFF'O // extended frame format (EFF)
+const octetstring CAN_ERR_MASK := '1FFFFFFF'O // omit EFF, RTR, ERR flags
+
+template octetstring t_CAN_EFF_FLAG:=(
+'80???'O,'81???'O,'82???'O,'83???'O,'84???'O,'85???'O,'86???'O,'87???'O,
+'88???'O,'89???'O,'8A???'O,'8B???'O,'8C???'O,'8D???'O,'8E???'O,'8F???'O,
+'90???'O,'91???'O,'92???'O,'93???'O,'94???'O,'95???'O,'96???'O,'97???'O,
+'98???'O,'99???'O,'9A???'O,'9B???'O,'9C???'O,'9D???'O,'9E???'O,'9F???'O,
+'A0???'O,'A1???'O,'A2???'O,'A3???'O,'A4???'O,'A5???'O,'A6???'O,'A7???'O,
+'A8???'O,'A9???'O,'AA???'O,'AB???'O,'AC???'O,'AD???'O,'AE???'O,'AF???'O,
+'B0???'O,'B1???'O,'B2???'O,'B3???'O,'B4???'O,'B5???'O,'B6???'O,'B7???'O,
+'B8???'O,'B9???'O,'BA???'O,'BB???'O,'BC???'O,'BD???'O,'BE???'O,'BF???'O,
+'C0???'O,'C1???'O,'C2???'O,'C3???'O,'C4???'O,'C5???'O,'C6???'O,'C7???'O,
+'C8???'O,'C9???'O,'CA???'O,'CB???'O,'CC???'O,'CD???'O,'CE???'O,'CF???'O,
+'D0???'O,'D1???'O,'D2???'O,'D3???'O,'D4???'O,'D5???'O,'D6???'O,'D7???'O,
+'D8???'O,'D9???'O,'DA???'O,'DB???'O,'DC???'O,'DD???'O,'DE???'O,'DF???'O,
+'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
+'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
+'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
+'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
+
+template octetstring t_CAN_SFF_FLAG:=(
+'00???'O,'01???'O,'02???'O,'03???'O,'04???'O,'05???'O,'06???'O,'07???'O,
+'08???'O,'09???'O,'0A???'O,'0B???'O,'0C???'O,'0D???'O,'0E???'O,'0F???'O,
+'10???'O,'11???'O,'12???'O,'13???'O,'14???'O,'15???'O,'16???'O,'17???'O,
+'18???'O,'19???'O,'1A???'O,'1B???'O,'1C???'O,'1D???'O,'1E???'O,'1F???'O,
+'20???'O,'21???'O,'22???'O,'23???'O,'24???'O,'25???'O,'26???'O,'27???'O,
+'28???'O,'29???'O,'2A???'O,'2B???'O,'2C???'O,'2D???'O,'2E???'O,'2F???'O,
+'30???'O,'31???'O,'32???'O,'33???'O,'34???'O,'35???'O,'36???'O,'37???'O,
+'38???'O,'39???'O,'3A???'O,'3B???'O,'3C???'O,'3D???'O,'3E???'O,'3F???'O,
+'40???'O,'41???'O,'42???'O,'43???'O,'44???'O,'45???'O,'46???'O,'47???'O,
+'48???'O,'49???'O,'4A???'O,'4B???'O,'4C???'O,'4D???'O,'4E???'O,'4F???'O,
+'50???'O,'51???'O,'52???'O,'53???'O,'54???'O,'55???'O,'56???'O,'57???'O,
+'58???'O,'59???'O,'5A???'O,'5B???'O,'5C???'O,'5D???'O,'5E???'O,'5F???'O,
+'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
+'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
+'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
+'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O);
+
+template octetstring t_CAN_RTR_FLAG:=(
+'40???'O,'41???'O,'42???'O,'43???'O,'44???'O,'45???'O,'46???'O,'47???'O,
+'48???'O,'49???'O,'4A???'O,'4B???'O,'4C???'O,'4D???'O,'4E???'O,'4F???'O,
+'50???'O,'51???'O,'52???'O,'53???'O,'54???'O,'55???'O,'56???'O,'57???'O,
+'58???'O,'59???'O,'5A???'O,'5B???'O,'5C???'O,'5D???'O,'5E???'O,'5F???'O,
+'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
+'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
+'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
+'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O,
+'C0???'O,'C1???'O,'C2???'O,'C3???'O,'C4???'O,'C5???'O,'C6???'O,'C7???'O,
+'C8???'O,'C9???'O,'CA???'O,'CB???'O,'CC???'O,'CD???'O,'CE???'O,'CF???'O,
+'D0???'O,'D1???'O,'D2???'O,'D3???'O,'D4???'O,'D5???'O,'D6???'O,'D7???'O,
+'D8???'O,'D9???'O,'DA???'O,'DB???'O,'DC???'O,'DD???'O,'DE???'O,'DF???'O,
+'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
+'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
+'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
+'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
+
+template octetstring t_CAN_ERR_FLAG:=(
+'20???'O,'21???'O,'22???'O,'23???'O,'24???'O,'25???'O,'26???'O,'27???'O,
+'28???'O,'29???'O,'2A???'O,'2B???'O,'2C???'O,'2D???'O,'2E???'O,'2F???'O,
+'30???'O,'31???'O,'32???'O,'33???'O,'34???'O,'35???'O,'36???'O,'37???'O,
+'38???'O,'39???'O,'3A???'O,'3B???'O,'3C???'O,'3D???'O,'3E???'O,'3F???'O,
+'60???'O,'61???'O,'62???'O,'63???'O,'64???'O,'65???'O,'66???'O,'67???'O,
+'68???'O,'69???'O,'6A???'O,'6B???'O,'6C???'O,'6D???'O,'6E???'O,'6F???'O,
+'70???'O,'71???'O,'72???'O,'73???'O,'74???'O,'75???'O,'76???'O,'77???'O,
+'78???'O,'79???'O,'7A???'O,'7B???'O,'7C???'O,'7D???'O,'7E???'O,'7F???'O,
+'A0???'O,'A1???'O,'A2???'O,'A3???'O,'A4???'O,'A5???'O,'A6???'O,'A7???'O,
+'A8???'O,'A9???'O,'AA???'O,'AB???'O,'AC???'O,'AD???'O,'AE???'O,'AF???'O,
+'B0???'O,'B1???'O,'B2???'O,'B3???'O,'B4???'O,'B5???'O,'B6???'O,'B7???'O,
+'B8???'O,'B9???'O,'BA???'O,'BB???'O,'BC???'O,'BD???'O,'BE???'O,'BF???'O,
+'E0???'O,'E1???'O,'E2???'O,'E3???'O,'E4???'O,'E5???'O,'E6???'O,'E7???'O,
+'E8???'O,'E9???'O,'EA???'O,'EB???'O,'EC???'O,'ED???'O,'EE???'O,'EF???'O,
+'F0???'O,'F1???'O,'F2???'O,'F3???'O,'F4???'O,'F5???'O,'F6???'O,'F7???'O,
+'F8???'O,'F9???'O,'FA???'O,'FB???'O,'FC???'O,'FD???'O,'FE???'O,'FF???'O);
+
+type enumerated AdresseFamily_enum
+{
+// Supported address families
+PF_CAN (29) // Controller Area Network
+}
+// Supported address families
+
+const integer AF_CAN := 29; // See /include/linux/socket.h
+
+type enumerated ProtocolFamily_enum {
+//SOCK_STREAM (1),
+SOCK_DGRAM (2),
+SOCK_RAW (3)
+//SOCK_RDM (4),
+//SOCK_SEQPACKET (5),
+//SOCK_DCCP (6),
+//SOCK_PACKET (10)
+}
+
+// particular protocols of the protocol family PF_CAN
+type enumerated PF_CAN_protocols_enum {
+CAN_RAW (1), // RAW sockets
+CAN_BCM (2), // Broadcast Manager
+CAN_TP16 (3), // VAG Transport Protocol v1.6
+CAN_TP20 (4), // VAG Transport Protocol v2.0
+CAN_MCNET (5), // Bosch MCNet
+CAN_ISOTP (6), // ISO 15765-2 Transport Protocol
+CAN_NPROTO (7)
+}
+
+// CAN payload length and DLC definitions according to ISO 11898-1
+// See /usr/include/linux/can.h
+const integer CAN_MAX_DLEN := 8;
+
+// CAN FD payload length and DLC definitions according to ISO 11898-7
+// See /usr/include/linux/can.h
+const integer CANFD_MAX_DLEN := 64;
+
+// should be octetstring length (4);
+type octetstring CAN_id length (4);
+type bitstring CAN_flags length (8); // only used with CAN FD
+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)
+}
+}
diff --git a/src/CanError.ttcn b/src/CanError.ttcn
index fa188d4..50416bc 100644
--- a/src/CanError.ttcn
+++ b/src/CanError.ttcn
@@ -9,7 +9,7 @@
* Michael Josenhans
******************************************************************************/
-
+//Revision R1A
module CanError
{
diff --git a/src/SocketCAN_PT.cc b/src/SocketCAN_PT.cc
index 1eb600e..1a5d68b 100644
--- a/src/SocketCAN_PT.cc
+++ b/src/SocketCAN_PT.cc
@@ -1,1605 +1,1727 @@
-/******************************************************************************
- * Copyright (c) 2010, 2016 Ericsson AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Michael Josenhans
- ******************************************************************************/
-//
-// File: SocketCAN_PT.cc
-// Description: SocketCAN_PT test port source
-//
-
-#include "SocketCAN_PT.hh"
-
-#include <Addfunc.hh>
-#include <Bitstring.hh>
-#include <Charstring.hh>
-#include <errno.h>
-#include <Error.hh>
-#include <Hexstring.hh>
-#include <Integer.hh>
-#include <linux/can/bcm.h>
-#include <linux/can/raw.h>
-#include <linux/if.h>
-#include <Logger.hh>
-#include <memory.h>
-#include <Octetstring.hh>
-#include <Optional.hh>
-#include <Port.hh>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <Template.hh>
-#include <unistd.h>
-#include <algorithm>
-#include <cerrno>
-#include <cstdarg>
-#include <cstddef>
-#include <cstring>
-#include <iostream>
-
-struct bcm_msg_head;
-struct can_frame;
-struct canfd_frame;
-
-#define DEFAULT_NUM_SOCK 10
-#define BCM_FRAME_BUFFER_SIZE 256
-#define BCM_FRAME_FLAGS_SIZE 32 // size of SocketCAN_bcm_frame in Bit
-
-// 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 */
-
-
-
-// workaround, as not yet defined in all versions of "linux/Can.h":
-#ifndef CAN_MAX_DLEN
-#define CAN_MAX_DLEN 8
-#endif
-
-// workaround, as not defined in some older kernel versions
-#ifndef CAN_MTU
-#define CAN_MTU (sizeof(struct can_frame))
-#endif //CANFD_MTU
-
-
-// workaround, as canfd not defined in some older kernel versions
-// and thus canfd frames can not be used for data transfer between
-// kernel module and userspace.
-#ifdef CANFD_MTU
-#define CANFD_FRAME_STRUCT_DEFINED true
-#define RAW_CANFD_SUPPORT true
-#endif //CANFD_MTU
-
-// has to be defined in later kernel versions in bcm.h as #define CAN_FD_FRAME 0x0800
-#ifdef CAN_FD_FRAME
-#define BCM_CANFD_SUPPORT true
-#endif
-
-namespace SocketCAN__PortType {
-
-SocketCAN__PT_PROVIDER::SocketCAN__PT_PROVIDER(const char *par_port_name) :
- PORT(par_port_name), num_of_sock(0), sock_list_length(0), target_fd(-1), can_interface_name(
- NULL), debugging(false), debugging_configured(false), config_finished(
- false) {
- sock_list = NULL;
- //&num_of_sock = 0;
- //sock_list_length = 0;
-}
-
-SocketCAN__PT_PROVIDER::~SocketCAN__PT_PROVIDER() {
- Free(sock_list);
- reset_configuration();
-}
-
-void SocketCAN__PT_PROVIDER::set_parameter(const char * parameter_name,
- const char * parameter_value) {
- log("entering SocketCAN__PT_PROVIDER::set_parameter(%s, %s)",
- parameter_name, parameter_value);
-
- if (config_finished) {
- reset_configuration();
- config_finished = false;
- }
-
- if (strcmp(parameter_name, "SocketCAN_can_interface_name") == 0) {
- InitStrPar(can_interface_name, parameter_name, parameter_value);
- } else if (strcmp(parameter_name, "SocketCAN_debugging") == 0) {
- if (strcmp(parameter_value, "YES") == 0) {
- debugging = true;
- debugging_configured = true;
- log("Reading testport parameter debugging: ", debugging);
- } else if (strcmp(parameter_value, "NO") == 0) {
- debugging = false;
- debugging_configured = true;
- log("Reading testport parameter debugging: ", debugging);
- }
- } else {
- TTCN_error(
- "SocketCAN parameter configuration error: Configuration file does not correctly configure parameter 'SocketCAN_debugging' however parameter name '%s' as parameter value: '%s'!!\nExpecting: \n*.*.SocketCAN_debugging := \"YES\"\n or \n*.*.SocketCAN_debugging := \"NO\"",
- parameter_name, parameter_value);
- }
-
- log("leaving SocketCAN__PT_PROVIDER::set_parameter(%s, %s)", parameter_name,
- parameter_value);
-}
-
-/*void SocketCAN__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
- boolean is_writable, boolean is_error) {}*/
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Error(int /*fd*/) {
-
-}
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/) {
-
-}
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int sock) {
- log("entering SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
- int res;
-
- for (int a = 0; a < sock_list_length; a++) {
- if ((sock == sock_list[a].fd)
- and (sock_list[a].status != SOCKET_NOT_ALLOCATED)) {
- switch (sock_list[a].protocol_family) {
- case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW: {
- SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame parameters;
-
- struct sockaddr_can addr;
- socklen_t addr_len = sizeof(addr);
- //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
- // struct sockaddr *src_addr, socklen_t *addrlen);
-#ifdef CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
- struct canfd_frame frame; // always asume a CANFD_Frame shall be received
- ssize_t nbytes = recvfrom(sock, &frame, CANFD_MTU, 0,
- (struct sockaddr*) &addr, &addr_len);
-#else //CANFD_FRAME_STRUCT_DEFINED
- struct can_frame frame; // CANFD_Frame is not supported by this kernel version
- ssize_t nbytes = recvfrom(sock, &frame, CAN_MTU, 0,
- (struct sockaddr*) &addr, &addr_len);
-#endif //CANFD_FRAME_STRUCT_DEFINED
-
- if (nbytes <= 0) {
- //there is an empty message, or error in receive
- //remove the socket
- TTCN_error(
- "Closing socket %d with interface index %d due to an empty message or error in reception\n",
- sock, addr.can_ifindex);
- std::cout << "close_fd" << sock << std::endl;
- sock_list[a].status = SOCKET_NOT_ALLOCATED;
- sock_list[a].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
- num_of_sock--;
- Handler_Remove_Fd_Read(sock);
- close(sock);
- } else
-
- if ((nbytes == CAN_MTU)
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- or (nbytes == CANFD_MTU)
-#endif //CANFD_FRAME_STRUCT_DEFINED
- ){
- // A CAN Frame has been received. However use the struct canfd_frame to access it.
- // As it is a CAN frame, the flags field contains invalid data and the can_dlc field
- // is here called len as in CAN FD.
- struct ifreq ifr;
- ifr.ifr_ifindex = addr.can_ifindex;
- /* get interface name of the received CAN frame */
- res = ioctl(sock, SIOCGIFNAME, &ifr);
- if (res != 0) {
- TTCN_error(
- "SocketCAN frame reception: Ioctl failed while retrieving the interface name from the socket: %d with interface index %d\n",
- sock, ifr.ifr_ifindex);
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- log("SocketCAN: Received a CAN frame from interface %s",
- ifr.ifr_name, nbytes, frame.len);
-#else //CANFD_FRAME_STRUCT_DEFINED
- log("SocketCAN: Received a CAN frame from interface %s",
- ifr.ifr_name, nbytes, frame.can_dlc);
-#endif //CANFD_FRAME_STRUCT_DEFINED
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() =
- "SocketCAN : device name unknown, ioctl failed";
- } else {
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() =
- "SocketCAN : device name unknown, ioctl failed";
- parameters.ifr().if__name() = ifr.ifr_name;
- }
-
- struct timeval tv;
- res = ioctl(sock, SIOCGSTAMP, &tv);
- if (res != 0) {
- TTCN_error(
- "SocketCAN frame reception: Ioctl failed while retrieving the timestamp from the socket: %d with interface name %s\n",
- sock, ifr.ifr_name);
-
- } else {
- parameters.timestamp().tv__sec() = tv.tv_sec;
- parameters.timestamp().tv__usec() = tv.tv_usec;
- }
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() = ifr.ifr_name;
- parameters.id() = a;
-
- INTEGER can_id;
- can_id.set_long_long_val(frame.can_id);
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- const INTEGER len = frame.len;
-#else //CANFD_FRAME_STRUCT_DEFINED
- const INTEGER len = frame.can_dlc;
-#endif //CANFD_FRAME_STRUCT_DEFINED
- // frame type specific part:
- if (nbytes == CAN_MTU) {
- // CAN frame received:
- Can::CAN__frame& frameref =
- parameters.frame().can__frame();
- log(
- "Received a CAN frame from interface %s of %d bytes and with payload length %d",
- ifr.ifr_name, nbytes, (int)len);
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() = ifr.ifr_name;
- parameters.id() = a;
- frameref.can__id() = int2oct(can_id, 4);
- frameref.can__pdu() = OCTETSTRING(len, frame.data);
- } else {
- // CAN FD frame received:
- Can::CANFD__frame& frameref =
- parameters.frame().canfd__frame();
- log(
- "Received a CAN FD frame from interface %s of %d bytes and with payload length %d",
- ifr.ifr_name, nbytes, (int)len);
- frameref.can__id() = int2oct(can_id, 4);
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- frameref.can__flags() = BITSTRING(
- int2bit(frame.flags,
- frameref.can__flags().lengthof()));
-#endif //CANFD_FRAME_STRUCT_DEFINED
- frameref.can__pdu() = OCTETSTRING(len, frame.data);
- }
- incoming_message(parameters);
- }
- }
- break;
- case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM: {
- SocketCAN__Types::SocketCAN__receive__BCM__message parameters;
- struct sockaddr_can addr;
- struct {
- struct bcm_msg_head msg_head;
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
-#else //CANFD_FRAME_STRUCT_DEFINED
- struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
-#endif //CANFD_FRAME_STRUCT_DEFINED
- } bcm_msg;
- struct ifreq ifr;
-
- socklen_t addr_len = sizeof(addr);
- ssize_t nbytes = recvfrom(sock, &bcm_msg,
- sizeof(struct can_frame), 0, (struct sockaddr*) &addr,
- &addr_len);
- if (nbytes < 0) {
- //there is an empty message, or error in receive
- //remove the socket
- TTCN_error(
- "Closing socket %d with interface index %d due to an empty BCM message or error in reception\n",
- sock, addr.can_ifindex);
- std::cout << "close_fd" << sock << std::endl;
- sock_list[a].status = SOCKET_NOT_ALLOCATED;
- sock_list[a].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
- num_of_sock--;
- Handler_Remove_Fd_Read(sock);
- close(sock);
- } else {
- ifr.ifr_ifindex = addr.can_ifindex;
- // get interface name of the received CAN frame
-
- // currently handling of can_ifindex == 0 (= any interface) is unclear.
-// res = ioctl(sock, SIOCGIFNAME, &ifr);
-// if (res == -1) {
-// TTCN_error(
-// "Ioctl failed while receiving a BCM message frame on socket: %d with interface index %d with errno: %d\n",
-// sock, ifr.ifr_ifindex, errno);
-// }
- const INTEGER msg_head_flags = bcm_msg.msg_head.flags;
- log(
- "Received a BCM message from interface index %d of bytes %d",
- ifr.ifr_ifindex, nbytes);
- parameters.id() = bcm_msg.msg_head.can_id;
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() = ifr.ifr_name;
-
- uint32_t nframes = bcm_msg.msg_head.nframes;
- INTEGER opcode;
- opcode.set_long_long_val(bcm_msg.msg_head.opcode);
- parameters.frame().opcode() = int2oct(opcode, 4);
- parameters.frame().flags() = BITSTRING(
- int2bit(INTEGER(msg_head_flags),
- BCM_FRAME_FLAGS_SIZE));
- parameters.frame().count() = bcm_msg.msg_head.count;
- parameters.frame().ival1().tv__sec() =
- bcm_msg.msg_head.ival1.tv_sec;
- parameters.frame().ival1().tv__usec() =
- bcm_msg.msg_head.ival1.tv_usec;
- parameters.frame().ival2().tv__sec() =
- bcm_msg.msg_head.ival2.tv_sec;
- parameters.frame().ival2().tv__usec() =
- bcm_msg.msg_head.ival2.tv_usec;
- INTEGER bcm_head_can_id;
- bcm_head_can_id.set_long_long_val(bcm_msg.msg_head.can_id);
- parameters.frame().can__id() = int2oct(bcm_head_can_id, 4);
-#ifdef BCM_CANFD_SUPPORT
- long flags = bcm_msg.msg_head.flags;
- if ((flags & CAN_FD_FRAME ) == CAN_FD_FRAME ) {
- // Handle CAN FD frames
-
- parameters.frame().frames().can__frame().set_size(nframes);
- for (uint32_t i = 0; i < nframes; i++) {
- INTEGER len;
- len = bcm_msg.frame[i].len;
- if (len > CANFD_MAX_DLEN) {
- TTCN_error("Writing data: CAN FD pdu size too large\n");
- };
- INTEGER can_id;
- can_id.set_long_long_val(bcm_msg.frame[i].can_id);
- parameters.frame().frames().canfd__frame()[i].can__id() = int2oct(can_id, 4);
- //Here the bitstring shall be stored into a
- parameters.frame().frames().canfd__frame()[i].can__flags() =
- BITSTRING(32,
- (const unsigned char*) &(bcm_msg.frame[i].flags));
- parameters.frame().frames().canfd__frame()[i].can__pdu() =
- OCTETSTRING(len,
- (const unsigned char*) &(bcm_msg.frame[i].data));
- }
- incoming_message(parameters);
- }
- else
-#endif //BCM_CANFD_SUPPORT
- {
- parameters.frame().frames().can__frame().set_size(
- nframes);
- for (uint32_t i = 0; i < nframes; i++) {
- INTEGER len;
-#ifdef CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
- len = bcm_msg.frame[i].len;
-#else //CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
- len = bcm_msg.frame[i].can_dlc;
-#endif //CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
- // Handle legacy CAN frames
- if (len > CAN_MAX_DLEN) {
- TTCN_error("Writing data: CAN pdu size too large\n");
- len = CAN_MAX_DLEN;
- };
- INTEGER can_id;
- can_id.set_long_long_val(bcm_msg.frame[i].can_id);
- parameters.frame().frames().can__frame()[i].can__id() = int2oct(can_id, 4);
- parameters.frame().frames().can__frame()[i].can__pdu() =
- OCTETSTRING(len,
- (const unsigned char*) &(bcm_msg.frame[i].data));
-
- }
- incoming_message(parameters);
- }
- }
- }
- break;
- default: {
- TTCN_error(
- "SocketCAN Handle_Fd_Event_Readable (%d): unhandled protocol configured",
- sock);
- }
- break;
- }
- }
- }
- log("leaving SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
-}
-
-void SocketCAN__PT_PROVIDER::user_map(const char */*system_port */) {
- log("entering SocketCAN__PT_PROVIDER::user_map()");
-
- config_finished = true;
-
- if (debugging_configured == false) {
- // The debugging mode has not been defined in TTCN configuration file.
- TTCN_error(
- "Missing mandatory parameter: SocketCAN_debuhhing for can_interface_name %s \n",
- can_interface_name);
- }
-
- if (sock_list != NULL)
- TTCN_error("SocketCAN Test Port (%s): Internal error: "
- "sock_list is not NULL when mapping.", port_name);
- sock_list = (sock_data*) Malloc(DEFAULT_NUM_SOCK * sizeof(*sock_list));
- num_of_sock = 0;
- sock_list_length = DEFAULT_NUM_SOCK;
- for (int a = 0; a < sock_list_length; a++) {
- sock_list[a].status = SOCKET_NOT_ALLOCATED;
- sock_list[a].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
- }
-
- log("leaving SocketCAN__PT_PROVIDER::user_map()");
-}
-
-void SocketCAN__PT_PROVIDER::user_unmap(const char * /*system_port*/) {
- log("entering SocketCAN__PT_PROVIDER::user_unmap()");
-
- closeDownSocket();
-
- log("leaving SocketCAN__PT_PROVIDER::user_unmap()");
-}
-
-void SocketCAN__PT_PROVIDER::user_start() {
-
-}
-
-void SocketCAN__PT_PROVIDER::user_stop() {
-
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__socket& send_par) {
- log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
- int cn;
- SocketCAN__Types::SocketCAN__socket__result result;
-
- if (num_of_sock < sock_list_length) {
- cn = 0;
- while (sock_list[cn].status == SOCKET_OPEN) {
- cn++;
- }
- } else {
- sock_list = (sock_data*) Realloc(sock_list,
- 2 * sock_list_length * sizeof(*sock_list));
- for (int a = sock_list_length; a < sock_list_length * 2; a++) {
- sock_list[a].status = SOCKET_NOT_ALLOCATED;
- }
- cn = sock_list_length;
- sock_list_length *= 2;
- }
-
- //extern int socket (int __domain, int __type, int __protocol) __THROW;
- target_fd = socket(send_par.domain(), send_par.ptype(),
- send_par.protocol());
- if (target_fd <= 0) {
- TTCN_error("Cannot open socket \n");
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "Cannot open socket";
- } else {
- log("SocketCAN opened socket %d \n", target_fd);
- sock_list[cn].fd = target_fd;
- sock_list[cn].status = SOCKET_OPEN;
-
- num_of_sock++;
-
- //Handler_Add_Fd_Read(target_fd);
-
- result.id() = cn;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
-
- incoming_message(result);
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__ioctl& send_par) {
- log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__ioctl)");
-
- struct ifreq ifr;
-
- int sock;
- int cn = send_par.id();
- int res;
- SocketCAN__Types::SocketCAN__ioctl__result result;
-
- if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
- sock = sock_list[cn].fd;
- if (send_par.ifu().is_present()) {
- const OPTIONAL<SocketCAN__Types::SocketCAN__ioctl__ifu>& ifu =
- send_par.ifu();
- switch (ifu().get_selection()) {
- case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__name:
- strcpy(ifr.ifr_name, ifu().if__name());
- res = ioctl(sock, SIOCGIFINDEX, &ifr);
- if (res != 0) {
- TTCN_error(
- "Ioctl failed on socket: %d with interface name %s\n",
- sock, (const char *) ifu().if__name());
- result.ifr().if__name() = ifu().if__name();
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "Ioctl failed";
-
- } else {
- log("SocketCAN ioctl successful on socket %d \n", sock);
- result.ifr().if__name() = ifu().if__name();
- result.ifr().if__index() = ifr.ifr_ifindex;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
-
- break;
- case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__index:
- res = ioctl(sock, SIOCGIFNAME, &ifr);
- if (res != 0) {
- TTCN_error(
- "Ioctl failed on socket: %d with interface index %llu \n",
- sock, ifu().if__index().get_long_long_val());
- result.ifr().if__index() = ifr.ifr_ifindex;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "Ioctl failed";
- } else {
- log("SocketCAN ioctl successful on socket %d \n", sock);
- result.ifr().if__name() = ifr.ifr_name;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- break;
- default:
- TTCN_error("Ioctl failed due to unknown union selection");
- break;
- }
- } else {
- // optional ifu filed is not present, set take interface name from applicable TTCN configuration file
- if (can_interface_name == NULL) {
- TTCN_error(
- "Missing mandatory parameter: \"SocketCAN_can_interface_name\" has not been defined in function call to Send Data nor in test configuration file! ");
- } else {
- strcpy(ifr.ifr_name, can_interface_name);
- res = ioctl(sock, SIOCGIFINDEX, &ifr);
- if (res != 0) {
- TTCN_error(
- "Ioctl failed on socket: %d with interface name %s \n",
- sock, can_interface_name);
- result.ifr().if__index() = ifr.ifr_ifindex;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "Ioctl failed";
- } else {
- log("SocketCAN ioctl successful on socket %d \n", sock);
- result.ifr().if__name() = ifr.ifr_name;
- result.ifr().if__index() = ifr.ifr_ifindex;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- if (strlen(can_interface_name) <= IFNAMSIZ) {
- std::strcpy(ifr.ifr_name, can_interface_name);
-
- } else {
- TTCN_error(
- "Ioctl failed due to interface name too long.\n");
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "Ioctl failed due to interface name too long";
- }
- }
- }
- } else {
- TTCN_error("Ioctl failed due to unknown socket reference: %d \n", cn);
- result.ifr().if__name() = ifr.ifr_name;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "Ioctl failed due to unknown socket reference";
- }
- incoming_message(result);
- log("SocketCAN__PT::outgoing_send(SocketCAN__ioctl)");
-}
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__connect& send_par) {
-//Client connects to BCM
- log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
-
- int sock;
- struct sockaddr_can addr;
- int cn = send_par.id();
- int res;
- SocketCAN__Types::SocketCAN__connect__result result;
-
- if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
- if (sock_list[cn].protocol_family
- == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
- sock = sock_list[cn].fd;
-
- addr.can_family = AF_CAN;
- addr.can_ifindex = send_par.if__index();
-
- //extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
- res = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
- if (res != 0) {
- TTCN_error("Connecting to socket %d failed: \n", sock);
- log("Connecting to socket %d failed", sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "Connecting to socket failed";
- } else {
- log("Connecting socket %d was successful", sock);
- sock_list[cn].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- sock_list[cn].remote_Addr.can_family = AF_CAN;
- Handler_Add_Fd_Read(target_fd);
- }
- } else {
- TTCN_error("Socket reference already connected or bound: %d \n",
- cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "Socket reference already connected or bound";
- }
- } else {
- TTCN_error("Unknown socket reference: %d \n", cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = "Unknown socket reference";
- }
- incoming_message(result);
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__bind& send_par) {
-//Client binds
- log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
-
- int sock;
- struct sockaddr_can addr;
- int cn = send_par.id();
- int res;
- SocketCAN__Types::SocketCAN__bind__result result;
-
- if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
- if (sock_list[cn].protocol_family
- == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
- int if_index;
- sock = sock_list[cn].fd;
-
- addr.can_family = AF_CAN;
- if_index = send_par.if__index();
- addr.can_ifindex = if_index;
- log("Binding socket: %d with index: %d", sock, if_index);
- res = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
- if (res != 0) {
- log("Binding to socket %d failed", sock);
- TTCN_error("Binding to socket %d failed:\n", sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- } else {
- log("Binding socket %d was successful", sock);
- sock_list[cn].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- sock_list[cn].remote_Addr.can_family = AF_CAN;
- Handler_Add_Fd_Read(target_fd);
- }
- } else {
- TTCN_error("Socket reference already connected or bound: %d \n",
- cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "Socket reference already connected or bound";
- }
- } else {
- TTCN_error("Unknown socket reference: %d \n", cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = "Unknown socket reference";
- }
- incoming_message(result);
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__send__data& send_par) {
- log(
- "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
-
- SocketCAN__Types::SocketCAN__send__data__result result;
- int res = 0;
- int sock;
- int cn = send_par.id();
-
- if ((cn < sock_list_length)) {
- struct sockaddr_can addr;
- struct ifreq ifr;
- int nrOfBytesSent, nrOfBytestoSend;
- sock = sock_list[cn].fd;
-
- if (send_par.ifu().is_present()) {
- const OPTIONAL<SocketCAN__Types::SocketCAN__send__data__ifu>& ifu =
- send_par.ifu();
- switch (ifu().get_selection()) {
- case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
- addr.can_ifindex = ifu().if__index();
- addr.can_family = AF_CAN;
- break;
- case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__name:
- strcpy(ifr.ifr_name, ifu().if__name());
- res = ioctl(sock, SIOCGIFINDEX, &ifr);
- if (res != 0) {
- TTCN_error(
- "SocketCAN: 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::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN: Send CAN frame: Ioctl failed while retrieving the interface";
- }
- addr.can_ifindex = ifr.ifr_ifindex;
- addr.can_family = AF_CAN;
- break;
- case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__any:
- addr.can_ifindex = 0;
- addr.can_family = AF_CAN;
- break;
- default:
- TTCN_error(
- "SocketCAN: Send CAN frame: Unknown union selection");
- res = -1;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN: Send CAN frame: Unknown union selection";
- }
- } else {
- // optional ifu filed is not present, thus send to any interface:
- addr.can_ifindex = 0;
- addr.can_family = AF_CAN;
- }
-
- if (res == 0) { // check if previous interface inquiry step failed
- switch (send_par.frame().get_selection()) {
- case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame: {
- struct can_frame frame;
-
- log("SocketCAN: Sending CAN frame)");
- logOctet(" to can id: ",
- send_par.frame().can__frame().can__id());
- logOctet("containing data: ",
- send_par.frame().can__frame().can__pdu());
-
- size_t can_dlc =
- send_par.frame().can__frame().can__pdu().lengthof();
- frame.can_id = oct2int(send_par.frame().can__frame().can__id());
- memcpy(frame.data, send_par.frame().can__frame().can__pdu(),
- can_dlc);
- frame.can_dlc = can_dlc;
-
- nrOfBytestoSend = sizeof(frame);
- if (send_par.ifu().is_present()) {
- nrOfBytesSent = sendto(sock, &frame, nrOfBytestoSend, 0,
- (struct sockaddr*) &addr, sizeof(addr));
- if (nrOfBytesSent < 0) {
- log(
- "SocketCAN: Sent CAN frame with sendto of size %d failed",
- nrOfBytesSent);
- TTCN_error(
- "SocketCAN send with sendto() error while trying to send %d bytes",
- nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN send with sendto() error";
- } else {
- log(
- "SocketCAN send data with sendto() successful on socket %d \n",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- } else {
- nrOfBytesSent = send(sock, &frame, nrOfBytestoSend, 0);
- log("Sent CAN frame with send of size %d", nrOfBytesSent);
- if (nrOfBytesSent < 0) {
- log("Sent CAN frame with send of size %d failed",
- nrOfBytesSent);
- TTCN_error(
- "SocketCAN send with send() error while trying to send CAN frame of %d bytes",
- nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN send with send() error";
- } else {
- log(
- "SocketCAN send data with send() successful on socket %d \n",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- }
- break;
-#ifdef RAW_CANFD_SUPPORT
- case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
- struct canfd_frame fd_frame;
-
- log("SocketCAN: Sending CAN FD frame)");
- logOctet(" to can id: ",
- send_par.frame().canfd__frame().can__id());
- logBitstring("with flags: ",
- send_par.frame().canfd__frame().can__flags());
- logOctet("containing data: ",
- send_par.frame().canfd__frame().can__pdu());
-
- size_t len =
- send_par.frame().canfd__frame().can__pdu().lengthof();
- fd_frame.can_id = oct2int(send_par.frame().canfd__frame().can__id());
- memcpy(fd_frame.data,
- send_par.frame().canfd__frame().can__pdu(), len);
- fd_frame.len = len;
-
- nrOfBytestoSend = sizeof(fd_frame);
- if (send_par.ifu().is_present()) {
-
- nrOfBytesSent = sendto(sock, &fd_frame, nrOfBytestoSend, 0,
- (struct sockaddr*) &addr, sizeof(addr));
- if (nrOfBytesSent < 0) {
- TTCN_error(
- "SocketCAN FD send with sendto() error while trying to send %d bytes",
- nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN FD send with sendto() error";
- } else {
- log(
- "SocketCAN: Sent CAN FD frame with sendto() of size %d",
- nrOfBytesSent);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- } else {
- nrOfBytesSent = send(sock, &fd_frame, nrOfBytestoSend, 0);
- if (nrOfBytesSent < 0) {
- TTCN_error(
- "SocketCAN FD send with send() error while trying to send %d bytes",
- nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN FD send with send() error";
- } else {
- log(
- "SocketCAN: Sent CAN FD frame with send() of size %d",
- nrOfBytesSent);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- }
- break;
-#else // RAW_CANFD_SUPPORT
- case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
- TTCN_error(
- "SocketCAN: CAN FD is not supported by your current kernel error");
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN: CAN FD is not supported by your current kernel error";
- }
- break;
-#endif // RAW_CANFD_SUPPORT
-
- default:
- TTCN_error("SocketCAN send unknown frame type error");
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN send unknown frame type error";
- break;
- }
- log("SocketCAN: Nr of bytes sent = %d", nrOfBytesSent);
- if ((nrOfBytesSent > 0) and (nrOfBytesSent != nrOfBytestoSend)
- and (nrOfBytestoSend != 0)) {
- TTCN_error(
- "Send system call failed: %d bytes were sent instead of %d",
- nrOfBytesSent, nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN write failed as wrong number of bytes have been written";
- }
- }
- } else {
- TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = "Unknown socket reference";
- }
- incoming_message(result);
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__write__data& send_par) {
- log(
- "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
-
- SocketCAN__Types::SocketCAN__write__data__result result;
- int sock;
- int cn = send_par.id();
-
- if ((cn < sock_list_length)
- and (sock_list[cn].protocol_family
- == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM)
- and (sock_list[cn].status == SOCKET_OPEN)) {
- sock = sock_list[cn].fd;
-
- switch (send_par.bcm__tx__msg().frames().get_selection()) {
- case Bcm::SocketCAN__bcm__frame_frames::ALT_can__frame: {
- int nrOfBytesSent = 0;
- int nrOfBytestoSend = 0;
- struct {
- struct bcm_msg_head msg_head;
- struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
- } bcm_msg;
-
- const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
- send_par.bcm__tx__msg();
-
- int nframes = bcm__tx__msg.frames().can__frame().lengthof();
-
- if (nframes > BCM_FRAME_BUFFER_SIZE) {
- TTCN_error(
- "SocketCAN: Writing data: number of CAN frames too large: %d \n",
- nframes);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent";
- TTCN_error(
- "SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent");
- } else {
- const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
- send_par.bcm__tx__msg();
-
- bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
- bcm_msg.msg_head.flags = bit2int(
- send_par.bcm__tx__msg().flags());
- bcm_msg.msg_head.count = bcm__tx__msg.count();
- bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
- bcm_msg.msg_head.ival1.tv_usec =
- bcm__tx__msg.ival1().tv__usec();
- bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
- bcm_msg.msg_head.ival2.tv_usec =
- bcm__tx__msg.ival2().tv__usec();
- bcm_msg.msg_head.can_id = oct2int(bcm__tx__msg.can__id());
- bcm_msg.msg_head.nframes = nframes;
-
- log("SocketCAN: Sending BCM Message)");
- logOctet(" opcode: ", bcm__tx__msg.opcode());
- logBitstring(" flags: ", bcm__tx__msg.flags());
- logInteger(" count: ", bcm__tx__msg.count());
- logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
- logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
- logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
- logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
- logOctet(" can_id: ", bcm__tx__msg.can__id());
- logInteger(" nframes: ", nframes);
-
- for (int i = 0; i < nframes; i++) {
- const Bcm::SocketCAN__bcm__frame_frames_can__frame& frame =
- bcm__tx__msg.frames().can__frame();
-
- bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
- unsigned int can_dlc;
- can_dlc = frame[i].can__pdu().lengthof();
- if (can_dlc > CAN_MAX_DLEN) {
- TTCN_error(
- "SocketCAN writing data: CAN pdu size too large\n");
- can_dlc = CAN_MAX_DLEN;
- };
- log(" containing CAN frame:)");
- logOctet(" can id: ", frame[i].can__id());
- logInteger(" can dlc: ", can_dlc);
-
- bcm_msg.frame[i].can_dlc = can_dlc;
- for (unsigned int j = 0; j < can_dlc; j++) {
- bcm_msg.frame[i].data[j] = oct2int(
- frame[i].can__pdu()[j]);
- logOctet(" data: ", frame[i].can__pdu()[j]);
- }
- }
- // assuming that the struct within the structure are aligned cm_msg without passing
- // BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
- nrOfBytestoSend = sizeof(struct bcm_msg_head)
- + nframes * sizeof(struct can_frame);
-
- nrOfBytesSent = write(sock, &bcm_msg, (int) nrOfBytestoSend);
-
- if ((nrOfBytesSent) < 0) {
- int myerrno = errno;
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = myerrno;
- result.result().err__text() =
- "SocketCAN sending CAN data with write() failed";
- logInteger("bcm_msg.msg_head.can_id: ",
- (bcm_msg.msg_head.can_id));
- logInteger("bcm_msg.msg_head.count: ",
- bcm_msg.msg_head.count);
- logInteger("bcm_msg.msg_head.flags: ",
- bcm_msg.msg_head.flags);
- logInteger("bcm_msg.msg_head.ival1.tv_sec: ",
- bcm_msg.msg_head.ival1.tv_sec);
- logInteger("bcm_msg.msg_head.ival1.tv_usec: ",
- bcm_msg.msg_head.ival1.tv_usec);
- logInteger("bcm_msg.msg_head.ival2.tv_sec: ",
- bcm_msg.msg_head.ival2.tv_sec);
- logInteger("bcm_msg.msg_head.ival2.tv_usec: ",
- bcm_msg.msg_head.ival2.tv_usec);
- logInteger("bcm_msg.msg_head.nframes: ",
- bcm_msg.msg_head.nframes);
- logInteger("bcm_msg.msg_head.opcode: ",
- bcm_msg.msg_head.opcode);
-
- TTCN_error(
- //"SocketCAN sending CAN data with write() failed");
- "SocketCAN sending CAN data with write() failed. nrOfBytestoSend: %d, sizeof(struct bcm_msg_head): %d, nframes: %d, sizeof(struct can_frame): %d, nrOfBytesSent: %d, errno: %d\n",
- nrOfBytestoSend,
- ((int) sizeof(struct bcm_msg_head)),
- ((int) nframes), ((int) sizeof(struct can_frame)),
- (int) nrOfBytesSent, (int) myerrno);
- } else {
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = nrOfBytesSent;
- result.result().err__text() = OMIT_VALUE;
- }
- log("Nr of bytes sent = %d", nrOfBytesSent);
-
- if (nrOfBytesSent != nrOfBytestoSend) {
- TTCN_error(
- "SocketCAN frame write failed: %d bytes were sent instead of %d",
- nrOfBytesSent, nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN write failed as wrong number of bytes have been written";
- }
- }
- }
- break;
-#ifdef BCM_CANFD_SUPPORT
- case Bcm::SocketCAN__bcm__frame_frames::ALT_canfd__frame: {
- int nrOfBytesSent = 0;
- int nrOfBytestoSend = 0;
- struct {
- struct bcm_msg_head msg_head;
- struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
- } bcm_msg;
-
- const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
- send_par.bcm__tx__msg();
-
- unsigned int nframes =
- bcm__tx__msg.frames().canfd__frame().lengthof();
-
- if (nframes > BCM_FRAME_BUFFER_SIZE) {
- TTCN_error(
- "SocketCAN writing data: number of CAN FD frames too large: %d \n",
- nframes);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent";
- TTCN_error(
- "SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent");
- } else {
- const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
- send_par.bcm__tx__msg();
-
- bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
- bcm_msg.msg_head.flags = bit2int(
- send_par.bcm__tx__msg().flags());
- bcm_msg.msg_head.count = bcm__tx__msg.count();
- bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
- bcm_msg.msg_head.ival1.tv_usec =
- bcm__tx__msg.ival1().tv__usec();
- bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
- bcm_msg.msg_head.ival2.tv_usec =
- bcm__tx__msg.ival2().tv__usec();
- bcm_msg.msg_head.nframes = nframes;
-
- log("SocketCAN: Sending BCM Message)");
- logOctet(" opcode: ", bcm__tx__msg.opcode());
- logBitstring(" flags: ", bcm__tx__msg.flags());
- logInteger(" count: ", bcm__tx__msg.count());
- logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
- logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
- logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
- logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
- logOctet(" can_id: ", send_par.bcm__tx__msg().can__id());
- logInteger(" nframes: ", nframes);
-
- for (unsigned int i = 0; i < nframes; i++) {
- const Bcm::SocketCAN__bcm__frame_frames_canfd__frame& frame =
- bcm__tx__msg.frames().canfd__frame();
-
- bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
- bcm_msg.frame[i].flags = bit2int(frame[i].can__flags());
- unsigned int len = frame[i].can__pdu().lengthof();
- if (len > CANFD_MAX_DLEN) {
- TTCN_error("Writing data: CAN FD pdu size too large\n");
- len = CANFD_MAX_DLEN;
- };
- log(" containing CAN FD frame:)");
- logOctet(" can id: ", frame[i].can__id());
- logInteger(" can len: ", len);
-
- bcm_msg.frame[i].len = len;
- for (unsigned int j = 0; j < len; j++) {
- bcm_msg.frame[i].data[j] = oct2int(
- frame[i].can__pdu()[j]);
- logOctet(" data: ", frame[i].can__pdu()[j]);
- }
- }
- // assuming that the structs within the structure are aligned cm_msg without passing
- // BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
- nrOfBytestoSend = sizeof(struct bcm_msg_head)
- + nframes * sizeof(struct canfd_frame);
- nrOfBytesSent = write(sock, &bcm_msg, nrOfBytestoSend);
-
- if (nrOfBytesSent < 0) {
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN sending CAN FD data with write() failed";
- TTCN_error(
- "SocketCAN sending CAN FD data with write() failed");
- } else {
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
-
- log("Nr of bytes sent = %d", nrOfBytesSent);
-
- if (nrOfBytesSent != nrOfBytestoSend) {
- TTCN_error(
- "SocketCAN CAN fd frame write failed: %d bytes were sent instead of %d",
- nrOfBytesSent, nrOfBytestoSend);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN write failed as wrong number of bytes have been written";
- }
- }
- break;
-#endif //BCM_CANFD_SUPPORT
-
- default:
- TTCN_error("SocketCAN write unknown frame type error");
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN write unknown frame type error";
- break;
- }
- } else {
- TTCN_error(
- "SocketCAN write data failed due to unknown socket reference: %d \n",
- cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN write data failed due to unknown socket reference";
- }
- incoming_message(result);
- log(
- "leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__setsockopt& send_par) {
- log(
- "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
-
- int sock;
- int cn = send_par.id();
- int res;
- SocketCAN__Types::SocketCAN__setsockopt__result result;
-
- if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
- sock = sock_list[cn].fd;
-
- SocketCAN__Types::SocketCAN__setsockopt__commandu::union_selection_type command_selection =
- send_par.command().get_selection();
-
- switch (command_selection) {
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_rfilter: {
-
- std::size_t rfilter_size = (sizeof(send_par.command().rfilter())
- / sizeof(send_par.command().rfilter()[0]));
-
- struct can_filter rfilter[rfilter_size];
-
- if (rfilter_size == 0) {
- // deactivate filters
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
- } else {
- for (std::size_t i = 0; i < rfilter_size; i++) {
- rfilter[i].can_id =
- oct2int(send_par.command().rfilter()[i].can__id());
- rfilter[i].can_mask =
- oct2int(send_par.command().rfilter()[i].can__mask());
- };
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
- sizeof(rfilter));
- }
- if (res < 0) {
- TTCN_error(
- "SocketCAN setsockopt rfilter failed with error code %d:\n",
- errno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN setsockopt rfilter failed";
-
- } else {
- log("SocketCAN: setsockopt rfilter successful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- break;
-
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_err__mask: {
- can_err_mask_t err_mask = bit2int(send_par.command().err__mask());
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask,
- sizeof(err_mask));
- if (res < 0) {
- int myerrno = errno;
- TTCN_error(
- "SocketCAN setsockopt can__err__mask failed with error code %d:\n",
- myerrno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = myerrno;
- result.result().err__text() =
- "SocketCAN setsockopt can__err__mask failed";
- } else {
- log(
- "SocketCAN: setsockopt can__err__mask successful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- break;
-
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_loopback: {
-
- int loopback = send_par.command().loopback();
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback,
- sizeof(loopback));
- if (res < 0) {
- int myerrno = errno;
- TTCN_error(
- "SocketCAN setsockopt loopbackfailed with error code %d:\n",
- myerrno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = myerrno;
- result.result().err__text() =
- "SocketCAN setsockopt loopback failed";
- } else {
- log("SocketCAN: setsockopt loopback successful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- break;
-
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_recv__own__msgs: {
-
- int recv_own_msgs = send_par.command().recv__own__msgs();
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
- &recv_own_msgs, sizeof(recv_own_msgs));
- if (res < 0) {
- TTCN_error(
- "SocketCAN setsockopt recv__own__msg failed with error code %d:\n",
- errno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN setsockopt recv__own__msg failed";
- } else {
- log(
- "SocketCAN: setsockopt recv__own__msg successful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- break;
-
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_fd__frames: {
-
- int fd_frames = send_par.command().fd__frames();
-
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_frames,
- sizeof(fd_frames));
- if (res < 0) {
- TTCN_error(
- "SocketCAN setsockopt fd__frames failed with error code %d:\n",
- errno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN setsockopt fd__frames failed";
- } else {
- log("SocketCAN: setsockopt fd__frames successful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- break;
- case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_join__filters: {
- {
- int join_filters = send_par.command().join__filters();
-
- res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,
- &join_filters, sizeof(join_filters));
- if (res < 0) {
- TTCN_error(
- "SocketCAN setsockopt join__filters failed with error code %d:\n",
- errno);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() =
- "SocketCAN setsockopt join__filters failed";
- } else {
- log(
- "SocketCAN: setsockopt join__filterssuccessful on socket %d",
- sock);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() = OMIT_VALUE;
- }
- }
- }
- break;
- default: {
- TTCN_error(
- "SocketCAN: Unknown SocketCAN_setsockopt commandu union selection: %d \n",
- cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = OMIT_VALUE;
- result.result().err__text() =
- "SocketCAN: Unknown SocketCAN_setsockopt commandu union selection";
- break;
- }
- }
- } else {
- TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
- result.result().result__code() =
- SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
- result.result().err() = errno;
- result.result().err__text() = "SocketCAN: Unknown socket reference";
- }
- incoming_message(result);
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
- const SocketCAN__Types::SocketCAN__close& send_par) {
- log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
- int sock = sock_list[send_par.id()].fd;
-
- sock_list[send_par.id()].status = SOCKET_NOT_ALLOCATED;
- sock_list[send_par.id()].fd = 0;
- sock_list[send_par.id()].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
- num_of_sock--;
- Handler_Remove_Fd_Read(sock);
-
- close(sock);
-
- log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
-}
-
-void SocketCAN__PT_PROVIDER::reset_configuration() {
- free(can_interface_name);
- can_interface_name = NULL;
- debugging = false;
- debugging_configured = false;
-}
-
-void SocketCAN__PT_PROVIDER::InitStrPar(char *&par, const char* name,
- const char* val) {
- if (name)
- log("%s: Reading testport parameter: "
- "%s = %s", port_name, name, val);
-
- if (par)
- free(par);
- par = (char*) malloc(strlen(val) + 1);
- if (par == NULL)
- TTCN_error("Not enough memory.");
- strcpy(par, val);
-}
-
-void SocketCAN__PT_PROVIDER::log(const char *fmt, ...) {
- if (debugging == true) {
- TTCN_Logger::begin_event(TTCN_DEBUG);
- TTCN_Logger::log_event("SocketCAN test port (%s): ", get_name());
- va_list args;
- va_start(args, fmt);
- TTCN_Logger::log_event_va_list(fmt, args);
- va_end(args);
- TTCN_Logger::end_event();
- }
-}
-
-void SocketCAN__PT_PROVIDER::logOctet(const char *prompt,
- const OCTETSTRING& msg) {
- if (debugging == true) { //if debug
- TTCN_Logger::begin_event(TTCN_DEBUG);
- TTCN_Logger::log_event_str(prompt);
- TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
-
- for (int i = 0; i < msg.lengthof(); i++) {
- TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
- }
- TTCN_Logger::log_event("\n");
- TTCN_Logger::end_event();
- }
-}
-
-void SocketCAN__PT_PROVIDER::logHex(const char *prompt, const HEXSTRING& msg) {
- if (debugging == true) { //if debug
- TTCN_Logger::begin_event(TTCN_DEBUG);
- TTCN_Logger::log_event_str(prompt);
- TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
-
- for (int i = 0; i < msg.lengthof(); i++) {
- TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
- }
- TTCN_Logger::log_event("\n");
- TTCN_Logger::end_event();
- }
-}
-
-void SocketCAN__PT_PROVIDER::logInteger(const char *prompt, const int number) {
- if (debugging) { //if debug
- TTCN_Logger::begin_event(TTCN_DEBUG);
- TTCN_Logger::log_event_str(prompt);
- TTCN_Logger::log_event("Value: %d,\n: ", number);
- TTCN_Logger::log_event("\n");
- TTCN_Logger::end_event();
- }
-}
-
-void SocketCAN__PT_PROVIDER::logBitstring(const char *prompt,
- const BITSTRING& msg) {
- if (debugging == true) { //if debug
- TTCN_Logger::begin_event(TTCN_DEBUG);
- TTCN_Logger::log_event_str(prompt);
- int len = msg.lengthof();
- TTCN_Logger::log_event("Size: %d,\nMsg: 0b", len);
- for (int i = 0; i < msg.lengthof(); i++) {
- TTCN_Logger::log_event("%d", (int) bit2int(msg[i]));
- }
- TTCN_Logger::log_event("\n");
- TTCN_Logger::end_event();
- }
-}
-
-void SocketCAN__PT_PROVIDER::setUpSocket() {
- log("entering SocketCAN__PT_PROVIDER::setUpSocket()");
- log("leaving SocketCAN__PT_PROVIDER::setUpSocket()");
-}
-
-void SocketCAN__PT_PROVIDER::closeDownSocket() {
- log("entering SocketCAN__PT_PROVIDER::closeDownSocket()");
-
- for (int a = 0; a < sock_list_length; a++) {
- if (sock_list[a].status == SOCKET_OPEN) {
- sock_list[a].status = SOCKET_NOT_ALLOCATED;
- sock_list[a].protocol_family =
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
- close(sock_list[a].fd);
- Handler_Remove_Fd_Read(sock_list[a].fd);
- }
- }
-
- Free(sock_list);
- sock_list = NULL;
-
- log("leaving SocketCAN__PT_PROVIDER::closeDownSocket()");
-}
-
-}
-/* end of namespace */
-
+/******************************************************************************
+ * Copyright (c) 2010, 2016 Ericsson AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Michael Josenhans
+ ******************************************************************************/
+//
+// File: SocketCAN_PT.cc
+// Description: SocketCAN_PT test port source
+//
+// Revision R1A
+#include "SocketCAN_PT.hh"
+#include "SocketCAN_PortType.hh"
+
+#include <Addfunc.hh>
+#include <Bitstring.hh>
+#include <Charstring.hh>
+#include <errno.h>
+#include <Error.hh>
+#include <Hexstring.hh>
+#include <Integer.hh>
+#include <linux/can/bcm.h>
+#include <linux/can/raw.h>
+#include <linux/if.h>
+#include <Logger.hh>
+#include <memory.h>
+#include <Octetstring.hh>
+#include <Optional.hh>
+#include <Port.hh>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <Template.hh>
+#include <unistd.h>
+#include <algorithm>
+#include <cerrno>
+#include <cstdarg>
+#include <cstddef>
+#include <cstring>
+#include <iostream>
+
+struct bcm_msg_head;
+struct can_frame;
+struct canfd_frame;
+
+
+#define DEFAULT_NUM_SOCK 10
+#define BCM_FRAME_BUFFER_SIZE 256
+#define BCM_FRAME_FLAGS_SIZE 32 // size of SocketCAN_bcm_frame in Bit
+#define ISOTP_RECIEVE_BUFSIZE 5000
+
+
+// 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 */
+
+// workaround, as not yet defined in all versions of "linux/Can.h":
+#ifndef CAN_MAX_DLEN
+#define CAN_MAX_DLEN 8
+#endif
+
+// workaround, as not defined in some older kernel versions
+#ifndef CAN_MTU
+#define CAN_MTU (sizeof(struct can_frame))
+#endif //CANFD_MTU
+
+// workaround, as canfd not defined in some older kernel versions
+// and thus canfd frames can not be used for data transfer between
+// kernel module and userspace.
+#ifdef CANFD_MTU
+#define CANFD_FRAME_STRUCT_DEFINED true
+#define RAW_CANFD_SUPPORT true
+#endif //CANFD_MTU
+
+// has to be defined in later kernel versions in bcm.h as #define CAN_FD_FRAME 0x0800
+#ifdef CAN_FD_FRAME
+#define BCM_CANFD_SUPPORT true
+#endif
+
+namespace SocketCAN__PortType {
+
+SocketCAN__PT_PROVIDER::SocketCAN__PT_PROVIDER(const char *par_port_name) :
+ PORT(par_port_name), num_of_sock(0), sock_list_length(0), target_fd(-1), can_interface_name(
+ NULL), debugging(false), debugging_configured(false), config_finished(
+ false) {
+ sock_list = NULL;
+ //&num_of_sock = 0;
+ //sock_list_length = 0;
+}
+
+SocketCAN__PT_PROVIDER::~SocketCAN__PT_PROVIDER() {
+ Free(sock_list);
+ reset_configuration();
+}
+
+void SocketCAN__PT_PROVIDER::set_parameter(const char * parameter_name,
+ const char * parameter_value) {
+ log("entering SocketCAN__PT_PROVIDER::set_parameter(%s, %s)",
+ parameter_name, parameter_value);
+
+ if (config_finished) {
+ reset_configuration();
+ config_finished = false;
+ }
+
+ if (strcmp(parameter_name, "SocketCAN_can_interface_name") == 0) {
+ InitStrPar(can_interface_name, parameter_name, parameter_value);
+ } else if (strcmp(parameter_name, "SocketCAN_debugging") == 0) {
+ if (strcmp(parameter_value, "YES") == 0) {
+ debugging = true;
+ debugging_configured = true;
+ log("Reading testport parameter debugging: ", debugging);
+ } else if (strcmp(parameter_value, "NO") == 0) {
+ debugging = false;
+ debugging_configured = true;
+ log("Reading testport parameter debugging: ", debugging);
+ }
+ } else {
+ TTCN_error(
+ "SocketCAN parameter configuration error: Configuration file does not correctly configure parameter 'SocketCAN_debugging' however parameter name '%s' as parameter value: '%s'!!\nExpecting: \n*.*.SocketCAN_debugging := \"YES\"\n or \n*.*.SocketCAN_debugging := \"NO\"",
+ parameter_name, parameter_value);
+ }
+
+ log("leaving SocketCAN__PT_PROVIDER::set_parameter(%s, %s)", parameter_name,
+ parameter_value);
+}
+
+/*void SocketCAN__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
+ boolean is_writable, boolean is_error) {}*/
+
+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Error(int /*fd*/) {
+
+}
+
+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/) {
+
+}
+
+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int sock) {
+ log("entering SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
+ int res;
+
+ for (int a = 0; a < sock_list_length; a++) {
+ if ((sock == sock_list[a].fd)
+ and (sock_list[a].status != SOCKET_NOT_ALLOCATED)) {
+ switch (sock_list[a].protocol_family) {
+ case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP: {
+ SocketCAN__Types::SocketCAN__receive__isotp__pdu parameters;
+
+ unsigned char msg[ISOTP_RECIEVE_BUFSIZE];
+
+ int nbytes = 0;
+ struct sockaddr_can addr;
+ socklen_t addr_len = sizeof(addr);
+ //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
+ // struct sockaddr *src_addr, socklen_t *addrlen);
+ nbytes = recvfrom(sock, msg, ISOTP_RECIEVE_BUFSIZE, 0,
+ (struct sockaddr*) &addr, &addr_len);
+
+ //nbytes = read(sock, msg, ISOTP_RECIEVE_BUFSIZE);
+ if(nbytes > 0 && nbytes < ISOTP_RECIEVE_BUFSIZE) {
+ struct ifreq ifr;
+ ifr.ifr_ifindex = addr.can_ifindex;
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() = ifr.ifr_name;
+ parameters.id() = a;
+ parameters.pdu() = OCTETSTRING(nbytes, msg);
+ incoming_message(parameters);
+ }
+ }
+ break;
+ case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW: {
+ SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame parameters;
+
+ struct sockaddr_can addr;
+ socklen_t addr_len = sizeof(addr);
+ //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
+ // struct sockaddr *src_addr, socklen_t *addrlen);
+#ifdef CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
+ struct canfd_frame frame; // always asume a CANFD_Frame shall be received
+ ssize_t nbytes = recvfrom(sock, &frame, CANFD_MTU, 0,
+ (struct sockaddr*) &addr, &addr_len);
+#else //CANFD_FRAME_STRUCT_DEFINED
+ struct can_frame frame; // CANFD_Frame is not supported by this kernel version
+ ssize_t nbytes = recvfrom(sock, &frame, CAN_MTU, 0,
+ (struct sockaddr*) &addr, &addr_len);
+#endif //CANFD_FRAME_STRUCT_DEFINED
+
+ if (nbytes <= 0) {
+ //there is an empty message, or error in receive
+ //remove the socket
+ TTCN_error(
+ "Closing socket %d with interface index %d due to an empty message or error in reception\n",
+ sock, addr.can_ifindex);
+ std::cout << "close_fd" << sock << std::endl;
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ sock_list[a].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ num_of_sock--;
+ Handler_Remove_Fd_Read(sock);
+ close(sock);
+ } else
+
+ if ((nbytes == CAN_MTU)
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ or (nbytes == CANFD_MTU)
+#endif //CANFD_FRAME_STRUCT_DEFINED
+ ) {
+ // A CAN Frame has been received. However use the struct canfd_frame to access it.
+ // As it is a CAN frame, the flags field contains invalid data and the can_dlc field
+ // is here called len as in CAN FD.
+ struct ifreq ifr;
+ ifr.ifr_ifindex = addr.can_ifindex;
+ /* get interface name of the received CAN frame */
+ res = ioctl(sock, SIOCGIFNAME, &ifr);
+ if (res != 0) {
+ TTCN_error(
+ "SocketCAN frame reception: Ioctl failed while retrieving the interface name from the socket: %d with interface index %d\n",
+ sock, ifr.ifr_ifindex);
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ log("SocketCAN: Received a CAN frame from interface %s",
+ ifr.ifr_name, nbytes, frame.len);
+#else //CANFD_FRAME_STRUCT_DEFINED
+ log("SocketCAN: Received a CAN frame from interface %s",
+ ifr.ifr_name, nbytes, frame.can_dlc);
+#endif //CANFD_FRAME_STRUCT_DEFINED
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() =
+ "SocketCAN : device name unknown, ioctl failed";
+ } else {
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() =
+ "SocketCAN : device name unknown, ioctl failed";
+ parameters.ifr().if__name() = ifr.ifr_name;
+ }
+
+ struct timeval tv;
+ res = ioctl(sock, SIOCGSTAMP, &tv);
+ if (res != 0) {
+ TTCN_error(
+ "SocketCAN frame reception: Ioctl failed while retrieving the timestamp from the socket: %d with interface name %s\n",
+ sock, ifr.ifr_name);
+
+ } else {
+ parameters.timestamp().tv__sec() = tv.tv_sec;
+ parameters.timestamp().tv__usec() = tv.tv_usec;
+ }
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() = ifr.ifr_name;
+ parameters.id() = a;
+
+ INTEGER can_id;
+ can_id.set_long_long_val(frame.can_id);
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ const INTEGER len = frame.len;
+#else //CANFD_FRAME_STRUCT_DEFINED
+ const INTEGER len = frame.can_dlc;
+#endif //CANFD_FRAME_STRUCT_DEFINED
+ // frame type specific part:
+ if (nbytes == CAN_MTU) {
+ // CAN frame received:
+ Can::CAN__frame& frameref =
+ parameters.frame().can__frame();
+ log(
+ "Received a CAN frame from interface %s of %d bytes and with payload length %d",
+ ifr.ifr_name, nbytes, (int) len);
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() = ifr.ifr_name;
+ parameters.id() = a;
+ frameref.can__id() = int2oct(can_id, 4);
+ frameref.can__pdu() = OCTETSTRING(len, frame.data);
+ } else {
+ // CAN FD frame received:
+ Can::CANFD__frame& frameref =
+ parameters.frame().canfd__frame();
+ log(
+ "Received a CAN FD frame from interface %s of %d bytes and with payload length %d",
+ ifr.ifr_name, nbytes, (int) len);
+ frameref.can__id() = int2oct(can_id, 4);
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ frameref.can__flags() = BITSTRING(
+ int2bit(frame.flags,
+ frameref.can__flags().lengthof()));
+#endif //CANFD_FRAME_STRUCT_DEFINED
+ frameref.can__pdu() = OCTETSTRING(len, frame.data);
+ }
+ incoming_message(parameters);
+ }
+ }
+ break;
+ case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM: {
+ SocketCAN__Types::SocketCAN__receive__BCM__message parameters;
+ struct sockaddr_can addr;
+ struct {
+ struct bcm_msg_head msg_head;
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
+#else //CANFD_FRAME_STRUCT_DEFINED
+ struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
+#endif //CANFD_FRAME_STRUCT_DEFINED
+ } bcm_msg;
+ struct ifreq ifr;
+
+ socklen_t addr_len = sizeof(addr);
+ ssize_t nbytes = recvfrom(sock, &bcm_msg,
+ sizeof(struct can_frame), 0, (struct sockaddr*) &addr,
+ &addr_len);
+ if (nbytes < 0) {
+ //there is an empty message, or error in receive
+ //remove the socket
+ TTCN_error(
+ "Closing socket %d with interface index %d due to an empty BCM message or error in reception\n",
+ sock, addr.can_ifindex);
+ std::cout << "close_fd" << sock << std::endl;
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ sock_list[a].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ num_of_sock--;
+ Handler_Remove_Fd_Read(sock);
+ close(sock);
+ } else {
+ ifr.ifr_ifindex = addr.can_ifindex;
+ // get interface name of the received CAN frame
+
+ // currently handling of can_ifindex == 0 (= any interface) is unclear.
+// res = ioctl(sock, SIOCGIFNAME, &ifr);
+// if (res == -1) {
+// TTCN_error(
+// "Ioctl failed while receiving a BCM message frame on socket: %d with interface index %d with errno: %d\n",
+// sock, ifr.ifr_ifindex, errno);
+// }
+ const INTEGER msg_head_flags = bcm_msg.msg_head.flags;
+ log(
+ "Received a BCM message from interface index %d of bytes %d",
+ ifr.ifr_ifindex, nbytes);
+ parameters.id() = bcm_msg.msg_head.can_id;
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() = ifr.ifr_name;
+
+ uint32_t nframes = bcm_msg.msg_head.nframes;
+ INTEGER opcode;
+ opcode.set_long_long_val(bcm_msg.msg_head.opcode);
+ parameters.frame().opcode() = int2oct(opcode, 4);
+ parameters.frame().flags() = BITSTRING(
+ int2bit(INTEGER(msg_head_flags),
+ BCM_FRAME_FLAGS_SIZE));
+ parameters.frame().count() = bcm_msg.msg_head.count;
+ parameters.frame().ival1().tv__sec() =
+ bcm_msg.msg_head.ival1.tv_sec;
+ parameters.frame().ival1().tv__usec() =
+ bcm_msg.msg_head.ival1.tv_usec;
+ parameters.frame().ival2().tv__sec() =
+ bcm_msg.msg_head.ival2.tv_sec;
+ parameters.frame().ival2().tv__usec() =
+ bcm_msg.msg_head.ival2.tv_usec;
+ INTEGER bcm_head_can_id;
+ bcm_head_can_id.set_long_long_val(bcm_msg.msg_head.can_id);
+ parameters.frame().can__id() = int2oct(bcm_head_can_id, 4);
+#ifdef BCM_CANFD_SUPPORT
+ long flags = bcm_msg.msg_head.flags;
+ if ((flags & CAN_FD_FRAME ) == CAN_FD_FRAME ) {
+ // Handle CAN FD frames
+
+ parameters.frame().frames().can__frame().set_size(nframes);
+ for (uint32_t i = 0; i < nframes; i++) {
+ INTEGER len;
+ len = bcm_msg.frame[i].len;
+ if (len > CANFD_MAX_DLEN) {
+ TTCN_error("Writing data: CAN FD pdu size too large\n");
+ };
+ INTEGER can_id;
+ can_id.set_long_long_val(bcm_msg.frame[i].can_id);
+ parameters.frame().frames().canfd__frame()[i].can__id() = int2oct(can_id, 4);
+ //Here the bitstring shall be stored into a
+ parameters.frame().frames().canfd__frame()[i].can__flags() =
+ BITSTRING(32,
+ (const unsigned char*) &(bcm_msg.frame[i].flags));
+ parameters.frame().frames().canfd__frame()[i].can__pdu() =
+ OCTETSTRING(len,
+ (const unsigned char*) &(bcm_msg.frame[i].data));
+ }
+ incoming_message(parameters);
+ }
+ else
+#endif //BCM_CANFD_SUPPORT
+ {
+ parameters.frame().frames().can__frame().set_size(
+ nframes);
+ for (uint32_t i = 0; i < nframes; i++) {
+ INTEGER len;
+#ifdef CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
+ len = bcm_msg.frame[i].len;
+#else //CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
+ len = bcm_msg.frame[i].can_dlc;
+#endif //CANFD_FRAME_STRUCT_DEFINED // struct canfd_frame is supported
+ // Handle legacy CAN frames
+ if (len > CAN_MAX_DLEN) {
+ TTCN_error(
+ "Writing data: CAN pdu size too large\n");
+ len = CAN_MAX_DLEN;
+ };
+ INTEGER can_id;
+ can_id.set_long_long_val(bcm_msg.frame[i].can_id);
+ parameters.frame().frames().can__frame()[i].can__id() =
+ int2oct(can_id, 4);
+ parameters.frame().frames().can__frame()[i].can__pdu() =
+ OCTETSTRING(len,
+ (const unsigned char*) &(bcm_msg.frame[i].data));
+
+ }
+ incoming_message(parameters);
+ }
+ }
+ }
+ break;
+ default: {
+ TTCN_error(
+ "SocketCAN Handle_Fd_Event_Readable (%d): unhandled protocol configured",
+ sock);
+ }
+ break;
+ }
+ }
+ }
+ log("leaving SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
+}
+
+void SocketCAN__PT_PROVIDER::user_map(const char */*system_port */) {
+ log("entering SocketCAN__PT_PROVIDER::user_map()");
+
+ config_finished = true;
+
+ if (debugging_configured == false) {
+ // The debugging mode has not been defined in TTCN configuration file.
+ TTCN_error(
+ "Missing mandatory parameter: SocketCAN_debuhhing for can_interface_name %s \n",
+ can_interface_name);
+ }
+
+ if (sock_list != NULL)
+ TTCN_error("SocketCAN Test Port (%s): Internal error: "
+ "sock_list is not NULL when mapping.", port_name);
+ sock_list = (sock_data*) Malloc(DEFAULT_NUM_SOCK * sizeof(*sock_list));
+ num_of_sock = 0;
+ sock_list_length = DEFAULT_NUM_SOCK;
+ for (int a = 0; a < sock_list_length; a++) {
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ sock_list[a].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ }
+
+ log("leaving SocketCAN__PT_PROVIDER::user_map()");
+}
+
+void SocketCAN__PT_PROVIDER::user_unmap(const char * /*system_port*/) {
+ log("entering SocketCAN__PT_PROVIDER::user_unmap()");
+
+ closeDownSocket();
+
+ log("leaving SocketCAN__PT_PROVIDER::user_unmap()");
+}
+
+void SocketCAN__PT_PROVIDER::user_start() {
+
+}
+
+void SocketCAN__PT_PROVIDER::user_stop() {
+
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__socket& send_par) {
+ log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
+ int cn;
+ SocketCAN__Types::SocketCAN__socket__result result;
+
+ if (num_of_sock < sock_list_length) {
+ cn = 0;
+ while (sock_list[cn].status == SOCKET_OPEN) {
+ cn++;
+ }
+ } else {
+ sock_list = (sock_data*) Realloc(sock_list,
+ 2 * sock_list_length * sizeof(*sock_list));
+ for (int a = sock_list_length; a < sock_list_length * 2; a++) {
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ }
+ cn = sock_list_length;
+ sock_list_length *= 2;
+ }
+
+ //extern int socket (int __domain, int __type, int __protocol) __THROW;
+ target_fd = socket(send_par.domain(), send_par.ptype(),
+ send_par.protocol());
+ if (target_fd <= 0) {
+ TTCN_error("Cannot open socket \n");
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "Cannot open socket";
+ } else {
+ log("SocketCAN opened socket %d \n", target_fd);
+ sock_list[cn].fd = target_fd;
+ sock_list[cn].status = SOCKET_OPEN;
+
+ num_of_sock++;
+
+ //Handler_Add_Fd_Read(target_fd);
+
+ result.id() = cn;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+
+ incoming_message(result);
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__ioctl& send_par) {
+ log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__ioctl)");
+
+ struct ifreq ifr;
+
+ int sock;
+ int cn = send_par.id();
+ int res;
+ SocketCAN__Types::SocketCAN__ioctl__result result;
+
+ if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
+ sock = sock_list[cn].fd;
+ if (send_par.ifu().is_present()) {
+ const OPTIONAL<SocketCAN__Types::SocketCAN__ioctl__ifu>& ifu =
+ send_par.ifu();
+ switch (ifu().get_selection()) {
+ case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__name:
+ strcpy(ifr.ifr_name, ifu().if__name());
+ res = ioctl(sock, SIOCGIFINDEX, &ifr);
+ if (res != 0) {
+ TTCN_error(
+ "Ioctl failed on socket: %d with interface name %s\n",
+ sock, (const char *) ifu().if__name());
+ result.ifr().if__name() = ifu().if__name();
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "Ioctl failed";
+
+ } else {
+ log("SocketCAN ioctl successful on socket %d \n", sock);
+ result.ifr().if__name() = ifu().if__name();
+ result.ifr().if__index() = ifr.ifr_ifindex;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+
+ break;
+ case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__index:
+ res = ioctl(sock, SIOCGIFNAME, &ifr);
+ if (res != 0) {
+ TTCN_error(
+ "Ioctl failed on socket: %d with interface index %llu \n",
+ sock, ifu().if__index().get_long_long_val());
+ result.ifr().if__index() = ifr.ifr_ifindex;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "Ioctl failed";
+ } else {
+ log("SocketCAN ioctl successful on socket %d \n", sock);
+ result.ifr().if__name() = ifr.ifr_name;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ break;
+ default:
+ TTCN_error("Ioctl failed due to unknown union selection");
+ break;
+ }
+ } else {
+ // optional ifu filed is not present, set take interface name from applicable TTCN configuration file
+ if (can_interface_name == NULL) {
+ TTCN_error(
+ "Missing mandatory parameter: \"SocketCAN_can_interface_name\" has not been defined in function call to Send Data nor in test configuration file! ");
+ } else {
+ strcpy(ifr.ifr_name, can_interface_name);
+ res = ioctl(sock, SIOCGIFINDEX, &ifr);
+ if (res != 0) {
+ TTCN_error(
+ "Ioctl failed on socket: %d with interface name %s \n",
+ sock, can_interface_name);
+ result.ifr().if__index() = ifr.ifr_ifindex;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "Ioctl failed";
+ } else {
+ log("SocketCAN ioctl successful on socket %d \n", sock);
+ result.ifr().if__name() = ifr.ifr_name;
+ result.ifr().if__index() = ifr.ifr_ifindex;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ if (strlen(can_interface_name) <= IFNAMSIZ) {
+ std::strcpy(ifr.ifr_name, can_interface_name);
+
+ } else {
+ TTCN_error(
+ "Ioctl failed due to interface name too long.\n");
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "Ioctl failed due to interface name too long";
+ }
+ }
+ }
+ } else {
+ TTCN_error("Ioctl failed due to unknown socket reference: %d \n", cn);
+ result.ifr().if__name() = ifr.ifr_name;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "Ioctl failed due to unknown socket reference";
+ }
+ incoming_message(result);
+ log("SocketCAN__PT::outgoing_send(SocketCAN__ioctl)");
+}
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__connect& send_par) {
+//Client connects to BCM
+ log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
+
+ int sock;
+ struct sockaddr_can addr;
+ int cn = send_par.id();
+ int res;
+ SocketCAN__Types::SocketCAN__connect__result result;
+
+ if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
+ if (sock_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
+ sock = sock_list[cn].fd;
+
+ addr.can_family = AF_CAN;
+
+ SocketCAN__Types::SocketCAN__connectu connectu = send_par.connectu();
+ switch (connectu.get_selection()) {
+ case SocketCAN__Types::SocketCAN__connectu::ALT_bcm:
+ addr.can_ifindex = connectu.bcm().if__index();
+ sock_list[cn].protocol_family
+ = SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
+ break;
+ default:
+ TTCN_error(
+ "connectu union selection does not exist on socket %d: \n",
+ sock);
+ break;
+ }
+ log("Connecting socket: %d with index: %d", sock, addr.can_ifindex);
+ //extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
+ res = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
+ if (res != 0) {
+ TTCN_error("Connecting to socket %d failed: \n", sock);
+ log("Connecting to socket %d failed", sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "Connecting to socket failed";
+ } else {
+ log("Connecting socket %d was successful", sock);
+ sock_list[cn].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ sock_list[cn].remote_Addr.can_family = AF_CAN;
+ Handler_Add_Fd_Read(target_fd);
+ }
+ } else {
+ TTCN_error("Socket reference already connected or bound: %d \n",
+ cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "Socket reference already connected or bound";
+ }
+ } else {
+ TTCN_error("Unknown socket reference: %d \n", cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = "Unknown socket reference";
+ }
+ incoming_message(result);
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__bind& send_par) {
+//Client binds
+ log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
+
+ int sock;
+ struct sockaddr_can addr;
+ int cn = send_par.id();
+ int res;
+ SocketCAN__Types::SocketCAN__bind__result result;
+
+ if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
+ if (sock_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
+ int if_index;
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_protocol_family_enum protocol_family;
+ sock = sock_list[cn].fd;
+
+ addr.can_family = AF_CAN;
+
+ SocketCAN__Types::SocketCAN__bindu bindu = send_par.bindu();
+
+ switch (bindu.get_selection()) {
+ case SocketCAN__Types::SocketCAN__bindu::ALT_raw:
+ if_index = bindu.raw().if__index();
+ protocol_family
+ = SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW;
+ break;
+ case SocketCAN__Types::SocketCAN__bindu::ALT_isotp:
+ if_index = bindu.isotp().if__index();
+ addr.can_addr.tp.rx_id = oct2int(bindu.isotp().rx__can__id());
+ addr.can_addr.tp.tx_id = oct2int(bindu.isotp().tx__can__id());
+ protocol_family
+ = SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP;
+ break;
+ default:
+ TTCN_error(
+ "bindu union selection does not exist on socket %d: \n",
+ sock);
+ break;
+ }
+ addr.can_ifindex = if_index;
+ log("Binding socket: %d with index: %d", sock, if_index);
+ res = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
+ if (res != 0) {
+ log("Binding to socket %d failed", sock);
+ TTCN_error("Binding to socket %d failed:\n", sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ } else {
+ log("Binding socket %d was successful", sock);
+ sock_list[cn].protocol_family = protocol_family ;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ sock_list[cn].remote_Addr.can_family = AF_CAN;
+ Handler_Add_Fd_Read(target_fd);
+ }
+ } else {
+ TTCN_error("Socket reference already connected or bound: %d \n",
+ cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "Socket reference already connected or bound";
+ }
+ } else {
+ TTCN_error("Unknown socket reference: %d \n", cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = "Unknown socket reference";
+ }
+ incoming_message(result);
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__send__data& send_par) {
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
+
+ SocketCAN__Types::SocketCAN__send__data__result result;
+ int res = 0;
+ int sock;
+ int cn = send_par.id();
+
+ if ((cn < sock_list_length)) {
+ struct sockaddr_can addr;
+ struct ifreq ifr;
+ int nrOfBytesSent, nrOfBytestoSend;
+ sock = sock_list[cn].fd;
+
+ if (send_par.ifu().is_present()) {
+ const OPTIONAL<SocketCAN__Types::SocketCAN__send__data__ifu>& ifu =
+ send_par.ifu();
+ switch (ifu().get_selection()) {
+ case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
+ addr.can_ifindex = ifu().if__index();
+ addr.can_family = AF_CAN;
+ break;
+ case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__name:
+ strcpy(ifr.ifr_name, ifu().if__name());
+ res = ioctl(sock, SIOCGIFINDEX, &ifr);
+ if (res != 0) {
+ TTCN_error(
+ "SocketCAN: 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::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN: Send CAN frame: Ioctl failed while retrieving the interface";
+ }
+ addr.can_ifindex = ifr.ifr_ifindex;
+ addr.can_family = AF_CAN;
+ break;
+ case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__any:
+ addr.can_ifindex = 0;
+ addr.can_family = AF_CAN;
+ break;
+ default:
+ TTCN_error(
+ "SocketCAN: Send CAN frame: Unknown union selection");
+ res = -1;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN: Send CAN frame: Unknown union selection";
+ }
+ } else {
+ // optional ifu filed is not present, thus send to any interface:
+ addr.can_ifindex = 0;
+ addr.can_family = AF_CAN;
+ }
+
+ if (res == 0) { // check if previous interface inquiry step failed
+ switch (send_par.frame().get_selection()) {
+ case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame: {
+ struct can_frame frame;
+
+ log("SocketCAN: Sending CAN frame)");
+ logOctet(" to can id: ",
+ send_par.frame().can__frame().can__id());
+ logOctet("containing data: ",
+ send_par.frame().can__frame().can__pdu());
+
+ size_t can_dlc =
+ send_par.frame().can__frame().can__pdu().lengthof();
+ frame.can_id = oct2int(send_par.frame().can__frame().can__id());
+ memcpy(frame.data, send_par.frame().can__frame().can__pdu(),
+ can_dlc);
+ frame.can_dlc = can_dlc;
+
+ nrOfBytestoSend = sizeof(frame);
+ if (send_par.ifu().is_present()) {
+ nrOfBytesSent = sendto(sock, &frame, nrOfBytestoSend, 0,
+ (struct sockaddr*) &addr, sizeof(addr));
+ if (nrOfBytesSent < 0) {
+ log(
+ "SocketCAN: Sent CAN frame with sendto of size %d failed",
+ nrOfBytesSent);
+ TTCN_error(
+ "SocketCAN send with sendto() error while trying to send %d bytes",
+ nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN send with sendto() error";
+ } else {
+ log(
+ "SocketCAN send data with sendto() successful on socket %d \n",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ } else {
+ nrOfBytesSent = send(sock, &frame, nrOfBytestoSend, 0);
+ log("Sent CAN frame with send of size %d", nrOfBytesSent);
+ if (nrOfBytesSent < 0) {
+ log("Sent CAN frame with send of size %d failed",
+ nrOfBytesSent);
+ TTCN_error(
+ "SocketCAN send with send() error while trying to send CAN frame of %d bytes",
+ nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN send with send() error";
+ } else {
+ log(
+ "SocketCAN send data with send() successful on socket %d \n",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ }
+ break;
+#ifdef RAW_CANFD_SUPPORT
+ case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
+ struct canfd_frame fd_frame;
+
+ log("SocketCAN: Sending CAN FD frame)");
+ logOctet(" to can id: ",
+ send_par.frame().canfd__frame().can__id());
+ logBitstring("with flags: ",
+ send_par.frame().canfd__frame().can__flags());
+ logOctet("containing data: ",
+ send_par.frame().canfd__frame().can__pdu());
+
+ size_t len =
+ send_par.frame().canfd__frame().can__pdu().lengthof();
+ fd_frame.can_id = oct2int(
+ send_par.frame().canfd__frame().can__id());
+ memcpy(fd_frame.data,
+ send_par.frame().canfd__frame().can__pdu(), len);
+ fd_frame.len = len;
+
+ nrOfBytestoSend = sizeof(fd_frame);
+ if (send_par.ifu().is_present()) {
+
+ nrOfBytesSent = sendto(sock, &fd_frame, nrOfBytestoSend, 0,
+ (struct sockaddr*) &addr, sizeof(addr));
+ if (nrOfBytesSent < 0) {
+ TTCN_error(
+ "SocketCAN FD send with sendto() error while trying to send %d bytes",
+ nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN FD send with sendto() error";
+ } else {
+ log(
+ "SocketCAN: Sent CAN FD frame with sendto() of size %d",
+ nrOfBytesSent);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ } else {
+ nrOfBytesSent = send(sock, &fd_frame, nrOfBytestoSend, 0);
+ if (nrOfBytesSent < 0) {
+ TTCN_error(
+ "SocketCAN FD send with send() error while trying to send %d bytes",
+ nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN FD send with send() error";
+ } else {
+ log(
+ "SocketCAN: Sent CAN FD frame with send() of size %d",
+ nrOfBytesSent);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ }
+ break;
+#else // RAW_CANFD_SUPPORT
+ case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
+ TTCN_error(
+ "SocketCAN: CAN FD is not supported by your current kernel error");
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN: CAN FD is not supported by your current kernel error";
+ }
+ break;
+#endif // RAW_CANFD_SUPPORT
+
+ default:
+ TTCN_error("SocketCAN send unknown frame type error");
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN send unknown frame type error";
+ break;
+ }
+ log("SocketCAN: Nr of bytes sent = %d", nrOfBytesSent);
+ if ((nrOfBytesSent > 0) and (nrOfBytesSent != nrOfBytestoSend)
+ and (nrOfBytestoSend != 0)) {
+ TTCN_error(
+ "Send system call failed: %d bytes were sent instead of %d",
+ nrOfBytesSent, nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write failed as wrong number of bytes have been written";
+ }
+ }
+ } else {
+ TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = "Unknown socket reference";
+ }
+ incoming_message(result);
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__write__data& send_par) {
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
+
+ SocketCAN__Types::SocketCAN__write__data__result result;
+ int sock;
+ int cn = send_par.id();
+
+ if ((cn < sock_list_length)
+ and (sock_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM)
+ and (sock_list[cn].status == SOCKET_OPEN)) {
+ sock = sock_list[cn].fd;
+
+ switch (send_par.bcm__tx__msg().frames().get_selection()) {
+ case Bcm::SocketCAN__bcm__frame_frames::ALT_can__frame: {
+ int nrOfBytesSent = 0;
+ int nrOfBytestoSend = 0;
+ struct {
+ struct bcm_msg_head msg_head;
+ struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
+ } bcm_msg;
+
+ const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
+ send_par.bcm__tx__msg();
+
+ int nframes = bcm__tx__msg.frames().can__frame().lengthof();
+
+ if (nframes > BCM_FRAME_BUFFER_SIZE) {
+ TTCN_error(
+ "SocketCAN: Writing data: number of CAN frames too large: %d \n",
+ nframes);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent";
+ TTCN_error(
+ "SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent");
+ } else {
+ const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
+ send_par.bcm__tx__msg();
+
+ bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
+ bcm_msg.msg_head.flags = bit2int(
+ send_par.bcm__tx__msg().flags());
+ bcm_msg.msg_head.count = bcm__tx__msg.count();
+ bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
+ bcm_msg.msg_head.ival1.tv_usec =
+ bcm__tx__msg.ival1().tv__usec();
+ bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
+ bcm_msg.msg_head.ival2.tv_usec =
+ bcm__tx__msg.ival2().tv__usec();
+ bcm_msg.msg_head.can_id = oct2int(bcm__tx__msg.can__id());
+ bcm_msg.msg_head.nframes = nframes;
+
+ log("SocketCAN: Sending BCM Message)");
+ logOctet(" opcode: ", bcm__tx__msg.opcode());
+ logBitstring(" flags: ", bcm__tx__msg.flags());
+ logInteger(" count: ", bcm__tx__msg.count());
+ logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
+ logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
+ logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
+ logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
+ logOctet(" can_id: ", bcm__tx__msg.can__id());
+ logInteger(" nframes: ", nframes);
+
+ for (int i = 0; i < nframes; i++) {
+ const Bcm::SocketCAN__bcm__frame_frames_can__frame& frame =
+ bcm__tx__msg.frames().can__frame();
+
+ bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
+ unsigned int can_dlc;
+ can_dlc = frame[i].can__pdu().lengthof();
+ if (can_dlc > CAN_MAX_DLEN) {
+ TTCN_error(
+ "SocketCAN writing data: CAN pdu size too large\n");
+ can_dlc = CAN_MAX_DLEN;
+ };
+ log(" containing CAN frame:)");
+ logOctet(" can id: ", frame[i].can__id());
+ logInteger(" can dlc: ", can_dlc);
+
+ bcm_msg.frame[i].can_dlc = can_dlc;
+ for (unsigned int j = 0; j < can_dlc; j++) {
+ bcm_msg.frame[i].data[j] = oct2int(
+ frame[i].can__pdu()[j]);
+ logOctet(" data: ", frame[i].can__pdu()[j]);
+ }
+ }
+ // assuming that the struct within the structure are aligned cm_msg without passing
+ // BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
+ nrOfBytestoSend = sizeof(struct bcm_msg_head)
+ + nframes * sizeof(struct can_frame);
+
+ nrOfBytesSent = write(sock, &bcm_msg, (int) nrOfBytestoSend);
+
+ if ((nrOfBytesSent) < 0) {
+ int myerrno = errno;
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = myerrno;
+ result.result().err__text() =
+ "SocketCAN sending CAN data with write() failed";
+ logInteger("bcm_msg.msg_head.can_id: ",
+ (bcm_msg.msg_head.can_id));
+ logInteger("bcm_msg.msg_head.count: ",
+ bcm_msg.msg_head.count);
+ logInteger("bcm_msg.msg_head.flags: ",
+ bcm_msg.msg_head.flags);
+ logInteger("bcm_msg.msg_head.ival1.tv_sec: ",
+ bcm_msg.msg_head.ival1.tv_sec);
+ logInteger("bcm_msg.msg_head.ival1.tv_usec: ",
+ bcm_msg.msg_head.ival1.tv_usec);
+ logInteger("bcm_msg.msg_head.ival2.tv_sec: ",
+ bcm_msg.msg_head.ival2.tv_sec);
+ logInteger("bcm_msg.msg_head.ival2.tv_usec: ",
+ bcm_msg.msg_head.ival2.tv_usec);
+ logInteger("bcm_msg.msg_head.nframes: ",
+ bcm_msg.msg_head.nframes);
+ logInteger("bcm_msg.msg_head.opcode: ",
+ bcm_msg.msg_head.opcode);
+
+ TTCN_error(
+ //"SocketCAN sending CAN data with write() failed");
+ "SocketCAN sending CAN data with write() failed. nrOfBytestoSend: %d, sizeof(struct bcm_msg_head): %d, nframes: %d, sizeof(struct can_frame): %d, nrOfBytesSent: %d, errno: %d\n",
+ nrOfBytestoSend,
+ ((int) sizeof(struct bcm_msg_head)),
+ ((int) nframes), ((int) sizeof(struct can_frame)),
+ (int) nrOfBytesSent, (int) myerrno);
+ } else {
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = nrOfBytesSent;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ log("Nr of bytes sent = %d", nrOfBytesSent);
+
+ if (nrOfBytesSent != nrOfBytestoSend) {
+ TTCN_error(
+ "SocketCAN frame write failed: %d bytes were sent instead of %d",
+ nrOfBytesSent, nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write failed as wrong number of bytes have been written";
+ }
+ }
+ }
+ break;
+#ifdef BCM_CANFD_SUPPORT
+ case Bcm::SocketCAN__bcm__frame_frames::ALT_canfd__frame: {
+ int nrOfBytesSent = 0;
+ int nrOfBytestoSend = 0;
+ struct {
+ struct bcm_msg_head msg_head;
+ struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
+ }bcm_msg;
+
+ const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
+ send_par.bcm__tx__msg();
+
+ unsigned int nframes =
+ bcm__tx__msg.frames().canfd__frame().lengthof();
+
+ if (nframes > BCM_FRAME_BUFFER_SIZE) {
+ TTCN_error(
+ "SocketCAN writing data: number of CAN FD frames too large: %d \n",
+ nframes);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent";
+ TTCN_error(
+ "SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent");
+ } else {
+ const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
+ send_par.bcm__tx__msg();
+
+ bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
+ bcm_msg.msg_head.flags = bit2int(
+ send_par.bcm__tx__msg().flags());
+ bcm_msg.msg_head.count = bcm__tx__msg.count();
+ bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
+ bcm_msg.msg_head.ival1.tv_usec =
+ bcm__tx__msg.ival1().tv__usec();
+ bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
+ bcm_msg.msg_head.ival2.tv_usec =
+ bcm__tx__msg.ival2().tv__usec();
+ bcm_msg.msg_head.nframes = nframes;
+
+ log("SocketCAN: Sending BCM Message)");
+ logOctet(" opcode: ", bcm__tx__msg.opcode());
+ logBitstring(" flags: ", bcm__tx__msg.flags());
+ logInteger(" count: ", bcm__tx__msg.count());
+ logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
+ logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
+ logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
+ logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
+ logOctet(" can_id: ", send_par.bcm__tx__msg().can__id());
+ logInteger(" nframes: ", nframes);
+
+ for (unsigned int i = 0; i < nframes; i++) {
+ const Bcm::SocketCAN__bcm__frame_frames_canfd__frame& frame =
+ bcm__tx__msg.frames().canfd__frame();
+
+ bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
+ bcm_msg.frame[i].flags = bit2int(frame[i].can__flags());
+ unsigned int len = frame[i].can__pdu().lengthof();
+ if (len > CANFD_MAX_DLEN) {
+ TTCN_error("Writing data: CAN FD pdu size too large\n");
+ len = CANFD_MAX_DLEN;
+ };
+ log(" containing CAN FD frame:)");
+ logOctet(" can id: ", frame[i].can__id());
+ logInteger(" can len: ", len);
+
+ bcm_msg.frame[i].len = len;
+ for (unsigned int j = 0; j < len; j++) {
+ bcm_msg.frame[i].data[j] = oct2int(
+ frame[i].can__pdu()[j]);
+ logOctet(" data: ", frame[i].can__pdu()[j]);
+ }
+ }
+ // assuming that the structs within the structure are aligned cm_msg without passing
+ // BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
+ nrOfBytestoSend = sizeof(struct bcm_msg_head)
+ + nframes * sizeof(struct canfd_frame);
+ nrOfBytesSent = write(sock, &bcm_msg, nrOfBytestoSend);
+
+ if (nrOfBytesSent < 0) {
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN sending CAN FD data with write() failed";
+ TTCN_error(
+ "SocketCAN sending CAN FD data with write() failed");
+ } else {
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+
+ log("Nr of bytes sent = %d", nrOfBytesSent);
+
+ if (nrOfBytesSent != nrOfBytestoSend) {
+ TTCN_error(
+ "SocketCAN CAN fd frame write failed: %d bytes were sent instead of %d",
+ nrOfBytesSent, nrOfBytestoSend);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write failed as wrong number of bytes have been written";
+ }
+ }
+ break;
+#endif //BCM_CANFD_SUPPORT
+
+ default:
+ TTCN_error("SocketCAN write unknown frame type error");
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write unknown frame type error";
+ break;
+ }
+ } else {
+ TTCN_error(
+ "SocketCAN write data failed due to unknown socket reference: %d \n",
+ cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write data failed due to unknown socket reference";
+ }
+ incoming_message(result);
+ log(
+ "leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__write__isotp& send_par) {
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__isotp)");
+
+ SocketCAN__Types::SocketCAN__write__isotp__result result;
+ int sock;
+ int cn = send_par.id();
+
+ if ((cn < sock_list_length)
+ and (sock_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP)
+ and (sock_list[cn].status == SOCKET_OPEN)) {
+ sock = sock_list[cn].fd;
+
+ int nrOfBytesSent = 0;
+ int nrOfBytestoSend = send_par.pdu().lengthof();
+
+ logOctet("Writing ISOTP data on socket: ", send_par.pdu());
+ nrOfBytesSent = write(sock, send_par.pdu(), nrOfBytestoSend);
+ log(
+ "Written to ISOTP %d bytes data of the expected %d bytes on socket %d: ",
+ nrOfBytesSent, nrOfBytestoSend, sock);
+ if (nrOfBytesSent != nrOfBytestoSend) {
+ TTCN_warning(
+ "SocketCAN write isotp has written %d bytes, which are fewer than expected %d bytes to socket: %d \n",
+ nrOfBytesSent, nrOfBytestoSend, sock);
+ }
+ if (nrOfBytesSent < 0) {
+ TTCN_error("SocketCAN write isotp failed with error code %d:\n",
+ errno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "SocketCAN write isotp failed";
+ } else {
+ log(
+ "SocketCAN: write isotp successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ } else {
+ TTCN_error(
+ "SocketCAN write isotp failed due to unknown socket reference: %d with protocol family %d and status %d\n",
+ cn, sock_list[cn].protocol_family, sock_list[cn].status);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN write isotp failed due to unknown socket reference";
+ }
+ incoming_message(result);
+ log(
+ "leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__isotp)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__setsockopt& send_par) {
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
+
+ int sock;
+ int cn = send_par.id();
+ int res;
+ SocketCAN__Types::SocketCAN__setsockopt__result result;
+
+ if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
+ sock = sock_list[cn].fd;
+
+ SocketCAN__Types::SocketCAN__setsockopt__commandu::union_selection_type command_selection =
+ send_par.command().get_selection();
+
+ switch (command_selection) {
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_rfilter: {
+
+ std::size_t rfilter_size = (sizeof(send_par.command().rfilter())
+ / sizeof(send_par.command().rfilter()[0]));
+
+ struct can_filter rfilter[rfilter_size];
+
+ if (rfilter_size == 0) {
+ // deactivate filters
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
+ } else {
+ for (std::size_t i = 0; i < rfilter_size; i++) {
+ rfilter[i].can_id = oct2int(
+ send_par.command().rfilter()[i].can__id());
+ rfilter[i].can_mask = oct2int(
+ send_par.command().rfilter()[i].can__mask());
+ };
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
+ sizeof(rfilter));
+ }
+ if (res < 0) {
+ TTCN_error(
+ "SocketCAN setsockopt rfilter failed with error code %d:\n",
+ errno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN setsockopt rfilter failed";
+
+ } else {
+ log("SocketCAN: setsockopt rfilter successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_err__mask: {
+ can_err_mask_t err_mask = bit2int(send_par.command().err__mask());
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask,
+ sizeof(err_mask));
+ if (res < 0) {
+ int myerrno = errno;
+ TTCN_error(
+ "SocketCAN setsockopt can__err__mask failed with error code %d:\n",
+ myerrno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = myerrno;
+ result.result().err__text() =
+ "SocketCAN setsockopt can__err__mask failed";
+ } else {
+ log(
+ "SocketCAN: setsockopt can__err__mask successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_loopback: {
+
+ int loopback = send_par.command().loopback();
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback,
+ sizeof(loopback));
+ if (res < 0) {
+ int myerrno = errno;
+ TTCN_error(
+ "SocketCAN setsockopt loopbackfailed with error code %d:\n",
+ myerrno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = myerrno;
+ result.result().err__text() =
+ "SocketCAN setsockopt loopback failed";
+ } else {
+ log("SocketCAN: setsockopt loopback successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_recv__own__msgs: {
+
+ int recv_own_msgs = send_par.command().recv__own__msgs();
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &recv_own_msgs, sizeof(recv_own_msgs));
+ if (res < 0) {
+ TTCN_error(
+ "SocketCAN setsockopt recv__own__msg failed with error code %d:\n",
+ errno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN setsockopt recv__own__msg failed";
+ } else {
+ log(
+ "SocketCAN: setsockopt recv__own__msg successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_fd__frames: {
+
+ int fd_frames = send_par.command().fd__frames();
+
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_frames,
+ sizeof(fd_frames));
+ if (res < 0) {
+ TTCN_error(
+ "SocketCAN setsockopt fd__frames failed with error code %d:\n",
+ errno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN setsockopt fd__frames failed";
+ } else {
+ log("SocketCAN: setsockopt fd__frames successful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ break;
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_join__filters: {
+ {
+ int join_filters = send_par.command().join__filters();
+
+ res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,
+ &join_filters, sizeof(join_filters));
+ if (res < 0) {
+ TTCN_error(
+ "SocketCAN setsockopt join__filters failed with error code %d:\n",
+ errno);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() =
+ "SocketCAN setsockopt join__filters failed";
+ } else {
+ log(
+ "SocketCAN: setsockopt join__filterssuccessful on socket %d",
+ sock);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() = OMIT_VALUE;
+ }
+ }
+ }
+ break;
+ default: {
+ TTCN_error(
+ "SocketCAN: Unknown SocketCAN_setsockopt commandu union selection: %d \n",
+ cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = OMIT_VALUE;
+ result.result().err__text() =
+ "SocketCAN: Unknown SocketCAN_setsockopt commandu union selection";
+ break;
+ }
+ }
+ } else {
+ TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "SocketCAN: Unknown socket reference";
+ }
+ incoming_message(result);
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__close& send_par) {
+ log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
+ int sock = sock_list[send_par.id()].fd;
+
+ sock_list[send_par.id()].status = SOCKET_NOT_ALLOCATED;
+ sock_list[send_par.id()].fd = 0;
+ sock_list[send_par.id()].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ num_of_sock--;
+ Handler_Remove_Fd_Read(sock);
+
+ close(sock);
+
+ log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
+}
+
+void SocketCAN__PT_PROVIDER::reset_configuration() {
+ free(can_interface_name);
+ can_interface_name = NULL;
+ debugging = false;
+ debugging_configured = false;
+}
+
+void SocketCAN__PT_PROVIDER::InitStrPar(char *&par, const char* name,
+ const char* val) {
+ if (name)
+ log("%s: Reading testport parameter: "
+ "%s = %s", port_name, name, val);
+
+ if (par)
+ free(par);
+ par = (char*) malloc(strlen(val) + 1);
+ if (par == NULL)
+ TTCN_error("Not enough memory.");
+ strcpy(par, val);
+}
+
+void SocketCAN__PT_PROVIDER::log(const char *fmt, ...) {
+ if (debugging == true) {
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event("SocketCAN test port (%s): ", get_name());
+ va_list args;
+ va_start(args, fmt);
+ TTCN_Logger::log_event_va_list(fmt, args);
+ va_end(args);
+ TTCN_Logger::end_event();
+ }
+}
+
+void SocketCAN__PT_PROVIDER::logOctet(const char *prompt,
+ const OCTETSTRING& msg) {
+ if (debugging == true) { //if debug
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event_str(prompt);
+ TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
+
+ for (int i = 0; i < msg.lengthof(); i++) {
+ TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
+ }
+ TTCN_Logger::log_event("\n");
+ TTCN_Logger::end_event();
+ }
+}
+
+void SocketCAN__PT_PROVIDER::logHex(const char *prompt, const HEXSTRING& msg) {
+ if (debugging == true) { //if debug
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event_str(prompt);
+ TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
+
+ for (int i = 0; i < msg.lengthof(); i++) {
+ TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
+ }
+ TTCN_Logger::log_event("\n");
+ TTCN_Logger::end_event();
+ }
+}
+
+void SocketCAN__PT_PROVIDER::logInteger(const char *prompt, const int number) {
+ if (debugging) { //if debug
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event_str(prompt);
+ TTCN_Logger::log_event("Value: %d,\n: ", number);
+ TTCN_Logger::log_event("\n");
+ TTCN_Logger::end_event();
+ }
+}
+
+void SocketCAN__PT_PROVIDER::logBitstring(const char *prompt,
+ const BITSTRING& msg) {
+ if (debugging == true) { //if debug
+ TTCN_Logger::begin_event(TTCN_DEBUG);
+ TTCN_Logger::log_event_str(prompt);
+ int len = msg.lengthof();
+ TTCN_Logger::log_event("Size: %d,\nMsg: 0b", len);
+ for (int i = 0; i < msg.lengthof(); i++) {
+ TTCN_Logger::log_event("%d", (int) bit2int(msg[i]));
+ }
+ TTCN_Logger::log_event("\n");
+ TTCN_Logger::end_event();
+ }
+}
+
+void SocketCAN__PT_PROVIDER::setUpSocket() {
+ log("entering SocketCAN__PT_PROVIDER::setUpSocket()");
+ log("leaving SocketCAN__PT_PROVIDER::setUpSocket()");
+}
+
+void SocketCAN__PT_PROVIDER::closeDownSocket() {
+ log("entering SocketCAN__PT_PROVIDER::closeDownSocket()");
+
+ for (int a = 0; a < sock_list_length; a++) {
+ if (sock_list[a].status == SOCKET_OPEN) {
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ sock_list[a].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ close(sock_list[a].fd);
+ Handler_Remove_Fd_Read(sock_list[a].fd);
+ }
+ }
+
+ Free(sock_list);
+ sock_list = NULL;
+
+ log("leaving SocketCAN__PT_PROVIDER::closeDownSocket()");
+}
+
+}
+/* end of namespace */
+
diff --git a/src/SocketCAN_PT.hh b/src/SocketCAN_PT.hh
index 7df1aa2..383ffef 100644
--- a/src/SocketCAN_PT.hh
+++ b/src/SocketCAN_PT.hh
@@ -12,7 +12,7 @@
// File: SocketCAN_PT.hh
// Description: SocketCAN test port header
//
-
+// Revision R1A
#ifndef SocketCAN__PT_HH
#define SocketCAN__PT_HH
@@ -63,6 +63,7 @@
void outgoing_send(const SocketCAN__Types::SocketCAN__send__data& send_par);
void outgoing_send(
const SocketCAN__Types::SocketCAN__write__data& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__write__isotp& send_par);
void outgoing_send(const SocketCAN__Types::SocketCAN__setsockopt& send_par);
void outgoing_send(const SocketCAN__Types::SocketCAN__close& send_par);
virtual void incoming_message(
@@ -77,10 +78,14 @@
const SocketCAN__Types::SocketCAN__send__data__result& incoming_par) = 0;
virtual void incoming_message(
const SocketCAN__Types::SocketCAN__write__data__result& incoming_par) = 0;
+ virtual void incoming_message(
+ const SocketCAN__Types::SocketCAN__write__isotp__result& incoming_par) = 0;
virtual void incoming_message(
const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame& incoming_par) = 0;
virtual void incoming_message(
const SocketCAN__Types::SocketCAN__receive__BCM__message& incoming_par) = 0;
+ virtual void incoming_message(
+ const SocketCAN__Types::SocketCAN__receive__isotp__pdu& incoming_par) = 0;
virtual void incoming_message(
const SocketCAN__Types::SocketCAN__setsockopt__result& incoming_par) = 0;
void set_asp_params();
@@ -101,7 +106,8 @@
enum socket_protocol_family_enum {
SOCKET_NO_PROTOCOL = 0,
SOCKET_PROTOCOL_CAN_BCM = 1,
- SOCKET_PROTOCOL_CAN_RAW = 2
+ SOCKET_PROTOCOL_CAN_RAW = 2,
+ SOCKET_PROTOCOL_CAN_ISOTP = 6
};
struct sock_data {
diff --git a/src/SocketCAN_PortType.ttcn b/src/SocketCAN_PortType.ttcn
index b229111..7c52676 100644
--- a/src/SocketCAN_PortType.ttcn
+++ b/src/SocketCAN_PortType.ttcn
@@ -12,7 +12,7 @@
// File: SocketCAN_PortType.ttcn
// Description: SocketCAN testport port definition file
//
-
+// Revision R1A
module SocketCAN_PortType
{
@@ -32,8 +32,11 @@
in SocketCAN_send_data_result;
out SocketCAN_write_data;
in SocketCAN_write_data_result;
+ out SocketCAN_write_isotp;
+ in SocketCAN_write_isotp_result;
in SocketCAN_receive_CAN_or_CAN_FD_frame;
in SocketCAN_receive_BCM_message;
+ in SocketCAN_receive_isotp_pdu;
out SocketCAN_setsockopt;
in SocketCAN_setsockopt_result;
out SocketCAN_close;
diff --git a/src/SocketCAN_Templates.ttcn b/src/SocketCAN_Templates.ttcn
new file mode 100644
index 0000000..7ca8e96
--- /dev/null
+++ b/src/SocketCAN_Templates.ttcn
@@ -0,0 +1,92 @@
+module SocketCAN_Templates {
+
+import from SocketCAN_Types all;
+import from Bcm all
+import from Can all
+
+template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {
+ result_code := v_result_code,
+ err := *,
+ err_text := *
+}
+
+template SocketCAN_socket_result
+a_SocketCAN_socket_result(template SocketCAN_Result p_result) := {
+ id := ?,
+ result := p_result
+}
+
+template SocketCAN_ioctl_result
+a_SocketCAN_ioctl_result(template SocketCAN_Result p_result) := {
+ ifr := ?,
+ result := p_result
+}
+
+template SocketCAN_connect_result
+a_SocketCAN_connect_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+template SocketCAN_bind_result
+a_SocketCAN_bind_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+template SocketCAN_send_data_result
+a_SocketCAN_send_data_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+template SocketCAN_write_data_result
+a_SocketCAN_write_data_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_frame(
+ template SocketCAN_socketid p_id,
+ template CAN_id p_can_id,
+ template CAN_PDU p_can_pdu) := {
+ // recieved CAN frame
+ id := p_id,
+ ifr := ?,
+ frame := {can_frame := {can_id := p_can_id, can_pdu := p_can_pdu}},
+ timestamp := ?
+}
+
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_FD_frame(
+ template SocketCAN_socketid p_id,
+ template CAN_id p_can_id,
+ template CAN_PDU p_can_pdu) := {
+ // recieved CAN or CAN FD frame
+ id := p_id,
+ ifr := ?,
+ frame := {canfd_frame := {can_id := p_can_id, can_pdu := p_can_pdu}},
+ timestamp := ?
+}
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_or_CAN_FD_frame(
+ template SocketCAN_socketid p_id,
+ template SocketCAN_CAN_or_CAN_FD_frame p_frame) := {
+ // recieved CAN or CAN FD frame
+ id := p_id,
+ ifr := ?,
+ frame := p_frame,
+ timestamp := ?
+}
+
+template SocketCAN_receive_BCM_message a_SocketCAN_receive_BCM_message(
+ template SocketCAN_socketid p_id,
+ template SocketCAN_bcm_frame p_frame) := {
+ // recieved CAN or CAN FD frame
+ id := p_id,
+ ifr := ?,
+ frame := p_frame
+}
+
+template SocketCAN_setsockopt_result
+a_SocketCAN_setsockopt_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+}
diff --git a/src/SocketCAN_Types.ttcn b/src/SocketCAN_Types.ttcn
index 5455c9b..071b706 100644
--- a/src/SocketCAN_Types.ttcn
+++ b/src/SocketCAN_Types.ttcn
@@ -12,7 +12,7 @@
// File: SocketCAN_Types.ttcn
// Description: SocketCAN definition file
//
-
+// Revision R1A
module SocketCAN_Types
{
@@ -24,6 +24,8 @@
type charstring SocketCAN_if_name;
type integer SocketCAN_if_index (-32767 .. +32767);
+type octetstring SocketCAN_Isotp_PDU
+
type record SocketCAN_timeval
{
integer tv_sec, // Seconds
@@ -87,18 +89,41 @@
SocketCAN_Result result
}
+type union SocketCAN_connectu{
+ SocketCAN_connect_bcm bcm
+}
+
+type record SocketCAN_connect_bcm {
+ SocketCAN_if_index if_index
+}
+
type record SocketCAN_connect{
SocketCAN_socketid id,
- SocketCAN_if_index if_index
+ SocketCAN_connectu connectu
}
type record SocketCAN_connect_result{
SocketCAN_Result result
}
+type record SocketCAN_bind_raw {
+ SocketCAN_if_index if_index
+}
+
+type record SocketCAN_bind_isotp {
+ SocketCAN_if_index if_index,
+ CAN_id rx_can_id,
+ CAN_id tx_can_id
+}
+
+type union SocketCAN_bindu{
+ SocketCAN_bind_raw raw,
+ SocketCAN_bind_isotp isotp
+}
+
type record SocketCAN_bind{
SocketCAN_socketid id,
- SocketCAN_if_index if_index
+ SocketCAN_bindu bindu
}
type record SocketCAN_bind_result{
@@ -124,7 +149,15 @@
type record SocketCAN_write_data_result{
SocketCAN_Result result
- //SocketCAN_bcm_frame bcm_rx_msg
+}
+
+type record SocketCAN_write_isotp{
+ SocketCAN_socketid id,
+ SocketCAN_Isotp_PDU pdu
+}
+
+type record SocketCAN_write_isotp_result{
+ SocketCAN_Result result
}
type record SocketCAN_receive_CAN_or_CAN_FD_frame{ // recieved CAN or CAN FD frame
@@ -140,6 +173,12 @@
SocketCAN_bcm_frame frame
}
+type record SocketCAN_receive_isotp_pdu { // recieved Isotp PDU
+ SocketCAN_socketid id,
+ SocketCAN_ifr ifr,
+ SocketCAN_Isotp_PDU pdu
+}
+
type record length (0 .. 255) of CAN_RAW_filter CAN_RAW_filters
type union SocketCAN_setsockopt_commandu {
@@ -151,6 +190,23 @@
CAN_RAW_join_filters_enum join_filters
}
+//type record Setsockopt_isotp_opts{
+// CAM_id source_id,
+// CAM_id destination_id,
+//
+//}
+//
+//type record Setsockopt_isotp_llopts{
+//
+//}
+//
+//type union SocketCAN_setsockopt_commandu {
+// Setsockopt_rawu can_raw,
+// Setsockopt_isotp_opts can_isotp_opts,
+// Setsockopt_isotp_llopts can_isotp_llopts
+//}
+
+
type record SocketCAN_setsockopt{
SocketCAN_socketid id,
SocketCAN_setsockopt_commandu command