Added J1939 support by Michael Josenhans
Signed-off-by: Lenard Nagy <lenard.nagy@ericsson.com>
diff --git a/demo/Isobus.ttcn b/demo/Isobus.ttcn
index b5729af..6c525f6 100644
--- a/demo/Isobus.ttcn
+++ b/demo/Isobus.ttcn
@@ -19,6 +19,7 @@
import from IsobusCMMessageTypes all
import from IsobusNMMessageTypes all
import from IsobusVTMessageTypes all
+import from J1939 all
// Note:
// SocketCAN Error frames are not considered here
@@ -37,17 +38,9 @@
const octetstring ISOBUS_PDUSPECIFIC_MASK := '0000FF00'O;
const octetstring ISOBUS_SOURCEADDRESS_MASK := '000000FF'O;
-//type BIT3 Priority
+type J1939_Priority Priority
-type bitstring Priority length(6)
-with {
- variant "ALIGN(left)";
- variant "FIELDLENGTH(6)"
-}
-
-
-
-type record J1939 { // Error & RTR Frames are not considered here
+type record J1939_header { // Error & RTR Frames are not considered here
//PGN pgn optional,
//BIT3 ignore,
Priority prio,
@@ -90,7 +83,7 @@
with { variant "" }
type record CAN_frame_j1939 {
- J1939 can_j1939,
+ J1939_header can_j1939,
AnyIsoBusPdu can_pdu
}with { variant "" }
@@ -121,10 +114,10 @@
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{
+function pdu1_j1939id2canid(in J1939_header p_j1939, in Priority p_priority, in DestinationAddress p_da, in SourceAddress p_sa) return CAN_id{
var CAN_id v_can_id
v_can_id := bit2oct(oct2bit(p_sa) or4b (oct2bit(p_da) << 8) or4b (oct2bit(p_j1939.pf) << 16) or4b ((p_j1939.dp) << 24) or4b
- ((p_j1939.res) << 25) or4b (int2bit(bit2int(p_priority), 32) << 26))
+ ((p_j1939.res) << 25) or4b (int2bit(p_priority, 32) << 26))
return v_can_id
}
@@ -137,12 +130,12 @@
}
*/
-function j1939id2canid(in J1939 p_j1939) return CAN_id{
+function j1939id2canid(in J1939_header p_j1939) return CAN_id{
var CAN_id v_can_id
v_can_id := int2oct(
oct2int(p_j1939.sa) + oct2int(p_j1939.ps)*256 + oct2int(p_j1939.pf) * 256 * 256 +
bit2int(p_j1939.dp) * 256 * 256 * 256 + bit2int(p_j1939.res) * 256 * 256 * 256 * 2 +
- bit2int(p_j1939.prio) * 256 * 256 * 256 * 2 * 2,
+ p_j1939.prio * 256 * 256 * 256 * 2 * 2,
4 )
return v_can_id
}
@@ -161,13 +154,13 @@
return v_can_frame_j1939
}
-function canid2j1939(in CAN_id p_can_id) return J1939 {
+function canid2j1939(in CAN_id p_can_id) return J1939_header {
//---------------------------------------------------------------------------------------
var bitstring v_can_id_bitstring:= oct2bit(p_can_id)
- var J1939 v_j1939
+ var J1939_header v_j1939
- v_j1939.prio :=substr(v_can_id_bitstring, 0, 6); //3 ,3
+ v_j1939.prio :=bit2int(substr(v_can_id_bitstring, 0, 6)); //3 ,3
v_j1939.res :=v_can_id_bitstring[6];
v_j1939.dp :=v_can_id_bitstring[7];
v_j1939.pf :=p_can_id[1];//(p_can_id and4b ISOBUS_PDUFORMAT_MASK) >> 2 // shift 16 bits = 2 octets
diff --git a/demo/IsobusVTMessageTypes.ttcn b/demo/IsobusVTMessageTypes.ttcn
index e122cf2..ab0edba 100644
--- a/demo/IsobusVTMessageTypes.ttcn
+++ b/demo/IsobusVTMessageTypes.ttcn
@@ -3,6 +3,16 @@
import from General_Types all
import from IsobusMessageTypes all
+external function encode_VT2ECU(in VT2ECU pdu) return octetstring
+with { extension "prototype(convert) encode(RAW)" }
+external function decode_VT2ECU(in octetstring data) return VT2ECU
+with { extension "prototype(convert) decode(RAW)" }
+
+external function encode_ECU2VT(in ECU2VT pdu) return octetstring
+with { extension "prototype(convert) encode(RAW)" }
+external function decode_ECU2VT(in octetstring data) return ECU2VT
+with { extension "prototype(convert) decode(RAW)" }
+
type INT1 VTfunction
type integer AnyObjectID (0..65535) with { variant "FIELDLENGTH(16)" }; // includes also 65535 as no object
diff --git a/demo/Isobus_Templates.ttcn b/demo/Isobus_Templates.ttcn
index 623f884..48e6e26 100644
--- a/demo/Isobus_Templates.ttcn
+++ b/demo/Isobus_Templates.ttcn
@@ -7,6 +7,7 @@
import from Isobus all
import from General_Types all
+
template CAN_frame_j1939 t_message(Isobus.Priority prio_param, BIT1 res_param, BIT1 dp_param,
OCT1 pf_param, OCT1 ps_param, SourceAddress sa_param, template AnyIsoBusPdu t_can_pdu)
:= { can_j1939 := {
diff --git a/demo/Isobustest.ttcn b/demo/Isobustest.ttcn
index a1d0b0c..943a8ab 100644
--- a/demo/Isobustest.ttcn
+++ b/demo/Isobustest.ttcn
@@ -25,6 +25,7 @@
import from Isobus all
import from IsobusMessageTypes all
import from Isobus_Templates all
+import from J1939 all
import from IsobusNMMessageTypes all
@@ -552,26 +553,26 @@
{
- 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 },
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 6, res := '0'B, dp := '1'B, pf := 'E9'O, ps := 'FD'O, sa := 'E6'O },
can_pdu := { addressClaimed := { name := { selfConfigurableAddressValue := '0'B, industryGroupValue := '011'B, deviceClassInstanceValue := '0001'B, deviceClassValue := '0000001'B, reserveValued := '0'B, functionValue := '00000011'B, functionInstanceValue := '00101'B, ecuInstancceValue := '110'B, manufacturerCodeValue := '10000000000'B, identityNumberBits := '101000010000101000000'B } }}}
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}} }
+ template CAN_frame_j1939 t_CAN_frame_j1939_2 := { can_j1939 := { prio := 0, 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 := { selfConfigurableAddressValue := '0'B, industryGroupValue := '011'B, deviceClassInstanceValue := '0001'B, deviceClassValue := '0000001'B, reserveValued := '0'B, functionValue := '00000011'B, functionInstanceValue := '00101'B, ecuInstancceValue := '110'B, manufacturerCodeValue := '10000000000'B, identityNumberBits := '101000010000101000000'B } }}}
+ template CAN_frame_j1939 t_CAN_frame_j1939_3 := { can_j1939 := { prio := 0, res := '0'B, dp := '0'B, pf := '00'O, ps := 'FD'O, sa := 'C0'O }, can_pdu := { cannotClaimSourceAddress := { name := { selfConfigurableAddressValue := '0'B, industryGroupValue := '011'B, deviceClassInstanceValue := '0001'B, deviceClassValue := '0000001'B, reserveValued := '0'B, functionValue := '00000011'B, functionInstanceValue := '00101'B, ecuInstancceValue := '110'B, manufacturerCodeValue := '10000000000'B, identityNumberBits := '101000010000101000000'B } }}}
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 := {
+ template CAN_frame_j1939 t_CAN_frame_j1939_6 := { can_j1939 := { prio := 6, res := '0'B, dp := '1'B, pf := 'E6'O , ps := 'FD'O, sa := '00'O }, can_pdu := { commandedAddress := {
name := { selfConfigurableAddressValue := '0'B, industryGroupValue := '011'B, deviceClassInstanceValue := '0001'B, deviceClassValue := '0000001'B, reserveValued := '0'B, functionValue := '00000011'B, functionInstanceValue := '00101'B, ecuInstancceValue := '110'B, manufacturerCodeValue := '10000000000'B, identityNumberBits := '101000010000101000000'B },
newSourceAddress:='AA'O
} } }
@@ -583,7 +584,7 @@
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 :=
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
{vt2ecu := {vtStatusReq :=
{ vtfunction := 254,
sourceAddressOfActiveWorkingSetMaster := '11'O,
@@ -597,7 +598,7 @@
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 :=
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
{ecu2vt := {getMemoryReq :=
{ vtfunction := 194,
reserved2 := 'FF'O,
@@ -610,7 +611,7 @@
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 :=
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, 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))))
@@ -618,7 +619,7 @@
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 :=
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, 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))))
@@ -626,7 +627,7 @@
testcase tc_encdec_networkMessage_N_SP_Response_pdu_with_template() runs on MTC_CT // using a template
{
- template CAN_frame_j1939 t_CAN_frame_j1939 := t_message ( '000001'B, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
+ template CAN_frame_j1939 t_CAN_frame_j1939 := t_message ( 1, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
t_N_SP_Response_pdu(port_3, port_4, {'01'O,'02'O,'03'O,'04'O,'05'O,'06'O,'07'O}))
log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
@@ -634,7 +635,7 @@
testcase tc_encdec_networkMessage_N_SP_Response_with_template() runs on MTC_CT // using a template
{
- template CAN_frame_j1939 t_CAN_frame_j1939 := t_network_message ( '000001'B, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
+ template CAN_frame_j1939 t_CAN_frame_j1939 := t_network_message ( 1, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
{n_SP_Response := t_N_SP_Response(port_3, port_4, {'01'O,'02'O,'03'O,'04'O,'05'O,'06'O,'07'O})})
log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
@@ -642,7 +643,7 @@
testcase tc_encdec_N_SP_Response_with_template() runs on MTC_CT // using a template
{
- template CAN_frame_j1939 t_CAN_frame_j1939 := t_message ( '000001'B, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
+ template CAN_frame_j1939 t_CAN_frame_j1939 := t_message ( 1, '1'B, '0'B, '0A'O, '0B'O, '0C'O ,
{networkMessage := {n_SP_Response := t_N_SP_Response(port_3, port_4, {'01'O,'02'O,'03'O,'04'O,'05'O,'06'O,'07'O})}})
log(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939)))
log(f_decode_CAN_frame_j1939(f_encode_CAN_frame_j1939(valueof(t_CAN_frame_j1939))))
@@ -650,7 +651,7 @@
testcase tc_encdec_ecu2vt_workingSetMaintenanceReq() 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 :=
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, res := '0'B, dp := '0'B, pf := '00'O, ps := '00'O, sa := '00'O }, can_pdu :=
t_WorkingSetMaintenanceReq_pdu({
initiatingWorkingSetMaintenance := true,
reserved1 := false,
@@ -667,7 +668,7 @@
testcase tc_encdec_etp_dt () runs on MTC_CT // using a template
{
- template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := '000000'B, res := '1'B, dp := '1'B, pf := 'FE'O, ps := '00'O, sa := 'F8'O },
+ template CAN_frame_j1939 t_CAN_frame_j1939 := { can_j1939 := { prio := 0, res := '1'B, dp := '1'B, pf := 'FE'O, ps := '00'O, sa := 'F8'O },
can_pdu := { etp_dt := { seq_no := 105, data := '6C652073657276'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))))
@@ -687,7 +688,6 @@
}
-
testcase tc_dec_largemessage() runs on MTC_CT
{
@@ -720,6 +720,44 @@
log("--------------------------------------------")
}
+
+import from IsobusVTMessageTypes all
+
+testcase tc_decode_VT2ECU() runs on MTC_CT
+{
+
+ var octetstring j1939_vt_pdu
+ j1939_vt_pdu := 'c7ff02cde001e001'O
+ j1939_vt_pdu := 'c200ffff7d48400c'O
+ j1939_vt_pdu := 'c3ffffffff7f7fff'O
+ j1939_vt_pdu := 'c00400ffffffffff'O
+ j1939_vt_pdu := 'e00130303034333030'O
+ j1939_vt_pdu := 'd1ffffffff00ffff'O
+ j1939_vt_pdu := '09d00701ffff01ff'O
+ j1939_vt_pdu := 'b3ffffda5900ffff'O
+ j1939_vt_pdu := 'a82bd300bc0b0000'O
+ j1939_vt_pdu := 'a82cd300bb0b0000'O
+ j1939_vt_pdu := 'a82dd300bb0b0000'O
+ j1939_vt_pdu := 'b3ffff02d700ffff'O
+ j1939_vt_pdu := 'a875d600c4da0000'O
+ j1939_vt_pdu := 'a876d600c2da0000'O
+ j1939_vt_pdu := 'a877d600ffff0000'O
+ j1939_vt_pdu := 'a878d600ffff0000'O
+ j1939_vt_pdu := 'a879d600ffff0000'O
+ j1939_vt_pdu := 'a87ad600ffff0000'O
+ j1939_vt_pdu := 'a87bd600ffff0000'O
+ j1939_vt_pdu := 'a87cd600ffff0000'O
+ j1939_vt_pdu := 'a87dd600ffff0000'O
+ j1939_vt_pdu := 'a87ed600ffff0000'O
+ //j1939_vt_pdu := 'ade90300ffffffff'O
+ //j1939_vt_pdu := '09d00700ffff00ff'O
+
+ log(j1939_vt_pdu)
+ log("--------------------------------------------")
+ log(decode_VT2ECU(j1939_vt_pdu))
+ log("--------------------------------------------")
+}
+
//test case declarations
testcase tc_Example001() runs on MTC_CT
{
@@ -752,6 +790,7 @@
//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
+
//test case declarations
testcase tc_Example002() runs on MTC_CT
{
diff --git a/demo/Isotptest.ttcn b/demo/Isotptest.ttcn
index 33128b9..903b257 100644
--- a/demo/Isotptest.ttcn
+++ b/demo/Isotptest.ttcn
@@ -127,7 +127,7 @@
timer t_guard
t_guard.start(c_guard)
- pt_socketCAN.send(SocketCAN_ioctl:{id:= p_socket_id, ifu := omit});
+ pt_socketCAN.send(SocketCAN_Types.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
diff --git a/demo/J1939.cfg b/demo/J1939.cfg
new file mode 100644
index 0000000..4825fd6
--- /dev/null
+++ b/demo/J1939.cfg
@@ -0,0 +1,32 @@
+ ##############################################################################
+ # Copyright (c) 2000-2019 Ericsson Telecom AB 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 | 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 J1939 tests
+SocketCAN_J1939_test.tc_can_j1939_send_and_receive_can_frame
+SocketCAN_J1939_test.tc_can_j1939_send_and_receive_can_frame_parallel
diff --git a/demo/J1939test.ttcn b/demo/J1939test.ttcn
new file mode 100644
index 0000000..a0e4d19
--- /dev/null
+++ b/demo/J1939test.ttcn
@@ -0,0 +1,971 @@
+/* Copyright (c) 2000-2019 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: J1939test.ttcn
+// Description: J1939 port type test
+//
+
+
+module J1939test {
+
+import from SocketCAN_Types all;
+import from SocketCAN_PortType all;
+import from SocketCAN_Templates all;
+import from J1939 all;
+
+const float c_guard := 10.0
+
+type enumerated SocketCAN_open_socket_type
+{
+ OPEN_CAN_RAW,
+ OPEN_CAN_BCM,
+ OPEN_CAN_ISOTP,
+ OPEN_CAN_J1939
+}
+
+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_j1939_result{
+ SocketCAN_ifr ifr,
+ SocketCAN_socketid socket_id}
+
+type record J1939_message {
+ e_Phase phase,
+ SocketCAN_J1939_PDU j1939_pdu
+}
+
+const integer J1939_MAX_PDU_NUMBER := 256; // for testing purposes
+
+type record length (0 .. J1939_MAX_PDU_NUMBER) of SocketCAN_J1939_PDU SocketCAN_J1939_PDUs
+
+// 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_socket p_socket)
+runs on PTC
+return SocketCAN_socket_result {
+
+ var SocketCAN_socket_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(p_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,
+ in J1939_NAME p_j1939_name_destination,
+ in J1939_PGN p_j1939_pgn_destination,
+ in J1939_ADDR p_j1939_pgn_addr)
+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_Types.SocketCAN_connect:{id:= p_socket_id,
+ connectu := {j1939 := {if_index:= p_if_index,
+ j1939_destination:= {
+ name := p_j1939_name_destination /* or J1939_NO_NAME */,
+ pgn := p_j1939_pgn_destination /* or J1939_NO_PGN */,
+ addr := p_j1939_pgn_addr /* or J1939_NO_ADDR */}}}});
+ // 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,
+ in J1939_NAME p_j1939_name_source,
+ in J1939_PGN p_j1939_pgn_source,
+ in J1939_ADDR p_j1939_addr_source)
+runs on PTC
+return SocketCAN_bind_result {
+ var SocketCAN_bind_result v_result
+ timer t_guard
+ t_guard.start(c_guard)
+
+ log("p_socket_id", p_socket_id)
+ log("p_if_index", p_if_index)
+ log("p_j1939_name_source", p_j1939_name_source)
+ log("p_j1939_pgn_source", p_j1939_pgn_source)
+ log("p_j1939_addr_source", p_j1939_addr_source)
+
+
+ pt_socketCAN.send(SocketCAN_bind:{id:= p_socket_id,
+ bindu := {j1939 := {if_index:= p_if_index,
+ j1939_source:=
+ {name := p_j1939_name_source /* or J1939_NO_NAME */,
+ pgn := p_j1939_pgn_source /* or J1939_NO_PGN */,
+ addr := p_j1939_addr_source /* or J1939_NO_ADDR or J1939_IDLE_ADDR */ }}}});
+ 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_j1939_send_data_to(
+ in SocketCAN_socketid p_socket_id,
+ in SocketCAN_if_index p_if_index,
+ in J1939_hdr p_j1939_destination,
+ in SocketCAN_J1939_PDU p_pdu)
+runs on PTC
+return SocketCAN_j1939_send_data_to_result {
+ var SocketCAN_j1939_send_data_to_result v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ pt_socketCAN.send(SocketCAN_j1939_send_data_to:{
+ id := p_socket_id,
+ if_index := p_if_index,
+ j1939_destination := p_j1939_destination,
+ pdu := p_pdu});
+
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_to_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Sending j1939_send_data_to", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_to_result(a_result(SocketCAN_ERROR)))
+ {log("Sending j1939_send_data_to failed", p_socket_id); setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)
+ }
+ }
+ return v_result
+}
+
+function f_receive_j1939_message_data(
+ in SocketCAN_socketid p_socket_id,
+ template J1939_PGN p_pgn_expected,
+ template J1939_ADDR p_addr_expected,
+ template J1939_NAME p_name_expected,
+ template SocketCAN_J1939_PDU p_pdu_expected
+)
+runs on PTC {
+ var SocketCAN_receive_j1939_message v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ // receive frame or timeout
+ alt {
+
+ [] pt_socketCAN.receive(a_SocketCAN_receive_j1939_message(
+ p_socket_id,
+ ?,
+ p_pgn_expected,
+ p_addr_expected,
+ p_name_expected,
+ p_pdu_expected))-> value v_result
+ {log("SocketCan:Expected frame received", v_result)}
+ [] pt_socketCAN.receive(SocketCAN_receive_j1939_message:?) -> value v_result
+ {log("SocketCan:Unexpected j1939 message 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_j1939_message v_result
+
+ timer t_guard
+ t_guard.start(p_timeout_period)
+
+ // receive j1939 message or timeout
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_j1939_message(
+ p_socket_id,
+ ?,
+ ?,
+ ?,
+ ?,
+ ?)) -> value v_result {
+ log("SocketCan:Unexpected j1939 message received!", v_result)
+ setverdict(fail)
+ }
+ [] t_guard.timeout {
+ log("Expected timeout!")}
+ }
+}
+
+function f_j1939_send_data(in SocketCAN_socketid p_socket_id,
+ in SocketCAN_J1939_PDU p_pdu)
+runs on PTC
+return SocketCAN_j1939_send_data_result {
+
+ var SocketCAN_j1939_send_data_result v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+ log("SocketCAN_j1939_send_data_to:{id}:", p_socket_id)
+ log("SocketCAN_j1939_send_data_to:{pdu}:", p_pdu)
+
+ pt_socketCAN.send(SocketCAN_j1939_send_data:{
+ id:= p_socket_id,
+ pdu:=p_pdu});
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_result(a_result(SocketCAN_SUCCESS))) -> value v_result
+ {log("Writing data on J1939 socket: ", p_socket_id)}
+ [] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_result(a_result(SocketCAN_ERROR)))
+ {log("Writing data on J1939 socket failed", p_socket_id);
+ setverdict(fail)}
+ [] t_guard.timeout {
+ log("timeout!")
+ setverdict(fail)}
+ }
+ return v_result
+}
+
+function f_receive_j1939_data(
+ in SocketCAN_socketid p_socket_id,
+ template SocketCAN_ifr p_ifr,
+ template J1939_PGN p_peer_pgn,
+ template J1939_ADDR p_peer_addr,
+ template J1939_NAME p_peer_name,
+ template SocketCAN_J1939_PDU p_j1939_pdu__expected)
+runs on PTC {
+ var SocketCAN_receive_j1939_message v_result
+
+ timer t_guard
+ t_guard.start(c_guard)
+
+ // receive frame or timeout
+ alt {
+ [] pt_socketCAN.receive(a_SocketCAN_receive_j1939_message(
+ p_socket_id,
+ p_ifr,
+ p_peer_pgn,
+ p_peer_addr,
+ p_peer_name,
+ p_j1939_pdu__expected)) -> value v_result
+ {log("SocketCan:Expected frame received", v_result)}
+ [] pt_socketCAN.receive(SocketCAN_receive_j1939_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_Types.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_j1939()
+runs on PTC
+return SocketCAN_open_j1939_result {
+ var SocketCAN_socketid v_socket_id
+ v_socket_id := f_open_socket({domain:=PF_CAN, ptype := SOCK_DGRAM, protocol:= CAN_J1939}).id
+ var SocketCAN_ifr v_ifr
+ v_ifr := f_ioctl_get_if_index(v_socket_id).ifr
+
+ var SocketCAN_open_j1939_result v_result
+ v_result := {ifr := v_ifr, socket_id := v_socket_id}
+
+ return v_result
+}
+
+function f_ptc_J1939SendInitiator(
+ in e_Phase p_phase,
+ in J1939_Priority p_send_prio,
+ in J1939_ADDR p_j1939_addr_source,
+ in J1939_PGN p_j1939_pgn_destination,
+ in J1939_ADDR p_j1939_addr_destination,
+ in SocketCAN_J1939_PDU p_pdu_send) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ J1939_NO_NAME /* p_j1939_name_source */,
+ J1939_NO_PGN /* p_j1939_pgn_source */,
+ p_j1939_addr_source)
+ var SocketCAN_setsockopt_result v_setsockopt_result
+ v_setsockopt_result := f_setsockopt(v_socket_id, {j1939_prio:=p_send_prio})
+ v_setsockopt_result := f_setsockopt(v_socket_id, {j1939_prio:=p_send_prio})
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ var SocketCAN_j1939_send_data_to_result send_data_to_result
+ var J1939_hdr v_j1939_destination := {
+ //name := p_j1939_name_source,
+ pgn := p_j1939_pgn_destination,
+ addr:= p_j1939_addr_destination}
+
+ send_data_to_result := f_j1939_send_data_to(
+ v_socket_id,
+ v_ifr.if_index,
+ v_j1939_destination,
+ p_pdu_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_J1939SendInitiatorWithConnect(
+ in e_Phase p_phase,
+ in J1939_ADDR p_j1939_addr_source,
+ in J1939_PGN p_j1939_pgn_destination,
+ in J1939_ADDR p_j1939_addr_destination,
+ in SocketCAN_J1939_PDU p_pdu_send) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ J1939_NO_NAME /* p_j1939_name_source */,
+ J1939_NO_PGN /* p_j1939_pgn_source */,
+ p_j1939_addr_source)
+ var SocketCAN_connect_result v_connect_result
+ v_connect_result := f_connect(
+ v_socket_id,
+ v_ifr.if_index,
+ J1939_NO_NAME,
+ p_j1939_pgn_destination,
+ p_j1939_addr_destination)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ var SocketCAN_j1939_send_data_result send_data_result
+
+ send_data_result := f_j1939_send_data(
+ v_socket_id,
+ p_pdu_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_J1939FrameReceiver(
+ in e_Phase p_phase,
+ in J1939_ADDR p_j1939_addr_source,
+ template J1939_PGN p_peer_pgn,
+ template J1939_ADDR p_peer_addr,
+ template J1939_NAME p_peer_name,
+ template SocketCAN_J1939_PDU p_j1939_pdu_expected) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ J1939_NO_NAME,
+ J1939_NO_PGN,
+ p_j1939_addr_source)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ f_receive_j1939_data(
+ v_socket_id,
+ v_ifr,
+ p_peer_pgn,
+ p_peer_addr,
+ p_peer_name,
+ p_j1939_pdu_expected)
+ 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_J1939SendInitiatorDynamic(in e_Phase p_phase,
+ in J1939_NAME p_j1939_name_source,
+ in J1939_NAME p_j1939_name_destination,
+ in J1939_PGN p_j1939_pgn_destination,
+ in J1939_ADDR p_j1939_addr_destination,
+ in SocketCAN_J1939_PDU p_pdu_send) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ p_j1939_name_source,
+ J1939_NO_PGN /* p_j1939_pgn_source */,
+ J1939_IDLE_ADDR /* p_j1939_addr_source */)
+ // var SocketCAN_connect_result v_connect_result
+ // v_connect_result := f_connect(v_socket_id,
+ // v_ifr.if_index,
+ // p_j1939_name_destination,
+ // p_j1939_pgn_destination,
+ // p_j1939_pgn_addr)
+ var SocketCAN_setsockopt_result v_setsockopt_result
+ const SocketCAN_setsockopt_commandu c_commandu_activate_broadcast := {j1939_broadcast := Enable}
+
+ // configure filters:
+ v_setsockopt_result := f_setsockopt(v_socket_id, c_commandu_activate_broadcast)
+ // configure filters:
+ const J1939_filter c_j1939_filter0 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn :=J1939_PGN_ADDRESS_CLAIMED,
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter1 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_REQUEST, //J1939_PGN_ADDRESS_REQUEST
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter2 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_ADDRESS_COMMANDED,
+ pgn_mask := J1939_PGN_MAX}};
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_j1939_filters :=
+ {j1939_filter:={c_j1939_filter0, c_j1939_filter1, c_j1939_filter2}}
+
+ v_setsockopt_result := f_setsockopt(v_socket_id, c_commandu_activate_j1939_filters)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ var SocketCAN_j1939_send_data_to_result send_data_to_result
+ var J1939_hdr v_j1939_destination := {
+ name := omit,
+ pgn := J1939_PGN_ADDRESS_CLAIMED,
+ addr:= J1939_NO_ADDR}
+
+ send_data_to_result := f_j1939_send_data_to(
+ v_socket_id,
+ v_ifr.if_index,
+ v_j1939_destination,
+ p_j1939_name_source /*p_pdu_send*/)
+
+ // var SocketCAN_j1939_send_data_result send_data_result
+ // send_data_result := f_j1939_send_data(v_socket_id,
+ // p_pdu_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_J1939FrameReceiverDynamic(in e_Phase p_phase,
+ in J1939_NAME p_j1939_name_source,
+ in J1939_PGN p_j1939_pgn_source,
+ in J1939_ADDR p_j1939_addr_source,
+ template J1939_PGN p_peer_pgn,
+ template J1939_ADDR p_peer_addr,
+ template J1939_NAME p_peer_name,
+ template SocketCAN_J1939_PDU p_j1939_pdu_expected) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ p_j1939_name_source,
+ p_j1939_pgn_source,
+ p_j1939_addr_source)
+
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_phase)
+ f_receive_j1939_data(
+ v_socket_id,
+ v_ifr,
+ p_peer_pgn,
+ p_peer_addr,
+ p_peer_name,
+ p_j1939_pdu_expected)
+ 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_J1939FrameSequenceReceiver(
+ in e_Phase p_sequence_expected_phase,
+ in J1939_NAME p_j1939_name_source,
+ template J1939_PGN p_peer_pgn,
+ template J1939_ADDR p_peer_addr,
+ template J1939_NAME p_peer_name,
+ template SocketCAN_J1939_PDUs p_pdu_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_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ p_j1939_name_source,
+ J1939_NO_PGN /* p_j1939_pgn_source */,
+ J1939_NO_ADDR /*p_j1939_addr_source */)
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_sequence_expected_phase)
+ var integer v_i
+ for( v_i := 0; v_i < lengthof(p_pdu_sequence_expected); v_i := v_i +1) {
+ f_receive_j1939_data(
+ v_socket_id,
+ v_ifr,
+ p_peer_pgn,
+ p_peer_addr,
+ p_peer_name,
+ p_pdu_sequence_expected[v_i])
+ }
+ f_sendPhaseEndInd()
+
+ alt_awaitPhaseStartReq(p_no_further_frames_expected_phase)
+ f_receive_no_data_but_timeout(v_socket_id, p_timeout_period)
+ 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_j1939_address_claim(in e_Phase p_phase,
+ in J1939_NAME p_j1939_name_source) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ p_j1939_name_source,
+ J1939_NO_PGN,
+ '80'O)//J1939_IDLE_ADDR)
+ f_sendPhaseEndInd()
+
+ var SocketCAN_setsockopt_result v_setsockopt_result
+
+ v_setsockopt_result := f_setsockopt(v_socket_id, {j1939_broadcast:=Enable})
+
+ // configure filters:
+ const J1939_filter c_j1939_filter0 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn :=J1939_PGN_ADDRESS_CLAIMED,
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter1 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_REQUEST, //J1939_PGN_ADDRESS_REQUEST
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter2 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_ADDRESS_COMMANDED,
+ pgn_mask := J1939_PGN_MAX}};
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_j1939_filters :=
+ {j1939_filter:={c_j1939_filter0, c_j1939_filter1, c_j1939_filter2}}
+
+ v_setsockopt_result := f_setsockopt(v_socket_id, c_commandu_activate_j1939_filters)
+
+ alt_awaitPhaseStartReq(p_phase)
+
+ var SocketCAN_j1939_send_data_to_result send_data_to_result
+ var J1939_hdr v_j1939_destination := {
+ name := omit,
+ pgn := J1939_PGN_ADDRESS_CLAIMED,
+ addr:= J1939_NO_ADDR}
+
+ var J1939_NAME v_j1939_name_source_reverse :=
+ p_j1939_name_source[7]& p_j1939_name_source[6]& p_j1939_name_source[5]&
+ p_j1939_name_source[4]& p_j1939_name_source[3]& p_j1939_name_source[2]&
+ p_j1939_name_source[1]& p_j1939_name_source[0]
+
+ send_data_to_result := f_j1939_send_data_to(
+ v_socket_id,
+ v_ifr.if_index,
+ v_j1939_destination,
+ v_j1939_name_source_reverse /*p_pdu_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_j1939_address_claim2(in e_Phase p_phase,
+ in J1939_NAME p_j1939_name_source,
+ in SocketCAN_J1939_PDU p_pdu_send) runs on PTC {
+ map(self:pt_socketCAN, system:pt_socketCAN)
+ var SocketCAN_socketid v_socket_id
+ var SocketCAN_ifr v_ifr
+
+ alt_awaitPhaseStartReq(e_open_socket)
+ var SocketCAN_open_j1939_result res
+ res := f_open_j1939()
+ v_socket_id := res.socket_id
+ v_ifr := res.ifr
+ var SocketCAN_bind_result v_bind_result
+ v_bind_result := f_bind(v_socket_id,
+ v_ifr.if_index,
+ p_j1939_name_source,
+ J1939_NO_PGN,
+ J1939_IDLE_ADDR)
+ f_sendPhaseEndInd()
+
+ var SocketCAN_setsockopt_result v_setsockopt_result
+
+ v_setsockopt_result := f_setsockopt(v_socket_id, {j1939_broadcast:=Enable})
+
+ // configure filters:
+ const J1939_filter c_j1939_filter0 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn :=J1939_PGN_ADDRESS_CLAIMED,
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter1 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_REQUEST, //J1939_PGN_ADDRESS_REQUEST
+ pgn_mask := J1939_PGN_PDU1_MAX}};
+
+ const J1939_filter c_j1939_filter2 := {
+ name_filter:= omit,
+ addr_filter:= omit,
+ pgn_filter :={
+ pgn := J1939_PGN_ADDRESS_COMMANDED,
+ pgn_mask := J1939_PGN_MAX}};
+
+ const SocketCAN_setsockopt_commandu c_commandu_activate_j1939_filters :=
+ {j1939_filter:={c_j1939_filter0, c_j1939_filter1, c_j1939_filter2}}
+
+ v_setsockopt_result := f_setsockopt(v_socket_id, c_commandu_activate_j1939_filters)
+
+ alt_awaitPhaseStartReq(p_phase)
+
+ var SocketCAN_j1939_send_data_to_result send_data_to_result
+ var J1939_hdr v_j1939_destination := {
+ name := omit,
+ pgn := J1939_PGN_REQUEST,
+ addr:= J1939_NO_ADDR}
+
+ send_data_to_result := f_j1939_send_data_to(
+ v_socket_id,
+ v_ifr.if_index,
+ v_j1939_destination,
+ p_pdu_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()
+}
+
+// control
+// {
+// execute(tc_can_raw0())
+// }
+}
diff --git a/demo/Makefile b/demo/Makefile
index bb1de02..b47299d 100644
--- a/demo/Makefile
+++ b/demo/Makefile
@@ -85,12 +85,14 @@
# 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 ../src/SocketCAN_Templates.ttcn \
-../src/SocketCAN_Types.ttcn SocketCANtest.ttcn Isobus.ttcn Isobustest.ttcn IsobusMessageTypes.ttcn \
+../src/SocketCAN_Types.ttcn ../src/J1939.ttcn \
+SocketCANtest.ttcn Isobus.ttcn Isobustest.ttcn IsobusMessageTypes.ttcn \
Isobus_Templates.ttcn IsobusNMMessageTypes.ttcn IsobusCMMessageTypes.ttcn IsobusVTMessageTypes.ttcn \
Isotp.ttcn Isotptest.ttcn \
CAN_matrix_general_types.ttcn CAN_matrix_test.ttcn CAN_matrix.ttcn CAN_matrix_messages.ttcn CANFD_matrix_messages.ttcn \
CAN_matrix_signals.ttcn CAN_matrix_templates.ttcn \
-UnifiedDiagnosticServices.ttcn UnifiedDiagnosticServicestest.ttcn UnifiedDiagnosticServices_Template.ttcn
+UnifiedDiagnosticServices.ttcn UnifiedDiagnosticServicestest.ttcn UnifiedDiagnosticServices_Template.ttcn \
+J1939test.ttcn SocketCAN_J1939_test.ttcn
# ASN.1 modules of this project:
ASN1_MODULES =
@@ -99,12 +101,14 @@
# 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 Isobus.cc Isobustest.cc IsobusMessageTypes.cc \
+SocketCAN_Types.cc J1939.cc \
+SocketCANtest.cc Isobus.cc Isobustest.cc IsobusMessageTypes.cc \
Isobus_Templates.cc IsobusNMMessageTypes.cc IsobusCMMessageTypes.cc IsobusVTMessageTypes.cc \
Isotp.cc Isotptest.cc \
CAN_matrix_general_types.cc CAN_matrix_test.cc CAN_matrix.cc CAN_matrix_messages.cc CANFD_matrix_messages.cc \
CAN_matrix_signals.cc CAN_matrix_templates.cc \
-UnifiedDiagnosticServices.cc UnifiedDiagnosticServicestest.cc UnifiedDiagnosticServices_Template.cc
+UnifiedDiagnosticServices.cc UnifiedDiagnosticServicestest.cc UnifiedDiagnosticServices_Template.cc \
+J1939test.cc SocketCAN_J1939_test.cc
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
diff --git a/demo/SocketCAN_J1939_test.ttcn b/demo/SocketCAN_J1939_test.ttcn
new file mode 100644
index 0000000..64b8da4
--- /dev/null
+++ b/demo/SocketCAN_J1939_test.ttcn
@@ -0,0 +1,269 @@
+/* Copyright (c) 2000-2019 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+// File: SocketCAN_J1939_test.ttcn
+// Description: SocketCAN J1939 testcases for J1939 messages
+//
+
+
+
+module SocketCAN_J1939_test
+{
+import from J1939 all
+import from J1939test all
+
+function create_octetstring_of_size(in integer size) return octetstring {
+
+ var octetstring v_pdu_mod_1024 := ''O
+ var octetstring v_pdu_1024 := ''O
+ var octetstring v_pdu_mod_1048576 := ''O //1024*1024
+ var octetstring v_pdu_1048576 := ''O
+ var octetstring v_pdu_1073741824 := ''O //1024*1024*1024
+ var octetstring v_pdu := ''O
+
+ var integer vcount :=0
+ var integer maxcount
+ maxcount := size mod 1024
+ for (vcount :=0;vcount < maxcount; vcount := vcount+1){
+ v_pdu_mod_1024 := v_pdu_mod_1024 & int2oct((vcount mod 256),1)
+ }
+
+log("1")
+ for (vcount :=0;vcount < 1024; vcount := vcount+1){
+ v_pdu_1024 := v_pdu_1024 & int2oct((vcount mod 256),1)
+ }
+log("2")
+ maxcount := (size /1024) mod 1024
+ for (vcount :=0;vcount < maxcount; vcount := vcount+1){
+ v_pdu_mod_1048576 := v_pdu_mod_1048576 & v_pdu_1024
+ }
+ v_pdu_mod_1048576 := v_pdu_mod_1048576 & v_pdu_mod_1024
+log("3")
+ for (vcount :=0;vcount < 1024; vcount := vcount+1){
+ v_pdu_1048576 := v_pdu_1048576 & v_pdu_1024
+ }
+log("4")
+ maxcount := (size / (1024*1024))
+ for (vcount :=0;vcount < maxcount; vcount := vcount+1){
+ v_pdu_1073741824 := v_pdu_1073741824 & v_pdu_1048576
+ }
+ v_pdu_1073741824 := v_pdu_1073741824 & v_pdu_mod_1048576
+log("5")
+
+ v_pdu := v_pdu_1073741824
+
+ return v_pdu
+}
+
+testcase tc_can_j1939_send_and_receive_can_frame() runs on MTC {
+ var PTC v_ptc_j1939SendInitiator := PTC.create("PTC1_ptc_j1939SendInitiator") alive
+ var PTC v_ptc_j1939FrameReceiver := PTC.create("PTC2_ptc_j1939FrameReceiver") alive
+
+ f_addSyncSlaveSet(v_ptc_j1939SendInitiator, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_j1939FrameReceiver, v_PTCSet)
+
+ connect(mtc:pt_sync, v_ptc_j1939SendInitiator:pt_sync)
+ connect(mtc:pt_sync, v_ptc_j1939FrameReceiver:pt_sync)
+
+ const integer c_send_prio := 2
+ const octetstring c_addr_source1 := '80'O
+ const octetstring c_pgn_destination1 := '00E700'O // ECU to VT
+ const octetstring c_addr_destination1 := '90'O
+
+
+
+ var octetstring v_pdu_send := ''O
+ //v_pdu_send := create_octetstring_of_size(117440505)
+
+ v_pdu_send := create_octetstring_of_size (4193975) //4193976
+
+ log("length of v_pdu_send: ", lengthof(v_pdu_send))
+
+ v_ptc_j1939SendInitiator.start(f_ptc_J1939SendInitiator(
+ e_testbody1,
+ c_send_prio,
+ c_addr_source1,
+ c_pgn_destination1,
+ c_addr_destination1,
+ v_pdu_send))
+
+ v_ptc_j1939FrameReceiver.start(f_ptc_J1939FrameReceiver(
+ e_testbody2,
+ c_addr_destination1, /* p_j1939_addr_source */
+ c_pgn_destination1, /* p_peer_pgn */
+ c_addr_source1, /* p_peer_addr */
+ J1939_NO_NAME, /* p_peer_name */
+ v_pdu_send /* p_j1939_pdu_expected */))
+
+ 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_j1939SendInitiator:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_j1939FrameReceiver:pt_sync)
+
+ all component.kill;
+}
+
+testcase tc_can_j1939_send_and_receive_can_frame_parallel() runs on MTC {
+ var PTC v_ptc_j1939SendInitiator1 := PTC.create("PTC1_ptc_j1939SendInitiator1") alive
+ var PTC v_ptc_j1939FrameReceiver1 := PTC.create("PTC2_ptc_j1939FrameReceiver1") alive
+ var PTC v_ptc_j1939SendInitiator2 := PTC.create("PTC1_ptc_j1939SendInitiator2") alive
+ var PTC v_ptc_j1939FrameReceiver2 := PTC.create("PTC2_ptc_j1939FrameReceiver2") alive
+ f_addSyncSlaveSet(v_ptc_j1939SendInitiator1, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_j1939FrameReceiver1, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_j1939SendInitiator2, v_PTCSet)
+ f_addSyncSlaveSet(v_ptc_j1939FrameReceiver2, v_PTCSet)
+ connect(mtc:pt_sync, v_ptc_j1939SendInitiator1:pt_sync)
+ connect(mtc:pt_sync, v_ptc_j1939FrameReceiver1:pt_sync)
+ connect(mtc:pt_sync, v_ptc_j1939SendInitiator2:pt_sync)
+ connect(mtc:pt_sync, v_ptc_j1939FrameReceiver2:pt_sync)
+
+ const integer c_send_prio := 2
+ const octetstring c_addr_source1 := '80'O
+ const octetstring c_pgn_destination1 := '00E700'O // ECU to VT
+ const octetstring c_addr_destination1 := '90'O
+ const octetstring c_addr_source2 := '80'O
+ const octetstring c_pgn_destination2 := '00E700'O // ECU to VT
+ const octetstring c_addr_destination2 := '91'O
+
+ var octetstring v_pdu_send1 := ''O
+ var octetstring v_pdu_send2 := ''O
+ //v_pdu_send := create_octetstring_of_size(117440505)
+ v_pdu_send1 := create_octetstring_of_size(4193976)
+ log("length of v_pdu_send1: ", lengthof(v_pdu_send1))
+ v_pdu_send2 := create_octetstring_of_size(4193976)
+ log("length of v_pdu_send2: ", lengthof(v_pdu_send2))
+
+ v_ptc_j1939SendInitiator1.start(f_ptc_J1939SendInitiator(
+ e_testbody1,
+ c_send_prio,
+ c_addr_source1,
+ c_pgn_destination1,
+ c_addr_destination1,
+ v_pdu_send1))
+
+ v_ptc_j1939FrameReceiver1.start(f_ptc_J1939FrameReceiver(
+ e_testbody2,
+ c_addr_destination1, /* p_j1939_addr_source */
+ c_pgn_destination1, /* p_peer_pgn */
+ c_addr_source1, /* p_peer_addr */
+ J1939_NO_NAME, /* p_peer_name */
+ v_pdu_send1 /* p_j1939_pdu_expected */))
+
+ v_ptc_j1939SendInitiator2.start(f_ptc_J1939SendInitiator(
+ e_testbody1,
+ c_send_prio,
+ c_addr_source2,
+ c_pgn_destination2,
+ c_addr_destination2,
+ v_pdu_send2))
+
+ v_ptc_j1939FrameReceiver2.start(f_ptc_J1939FrameReceiver(
+ e_testbody2,
+ c_addr_destination2, /* p_j1939_addr_source */
+ c_pgn_destination2, /* p_peer_pgn */
+ c_addr_source2, /* p_peer_addr */
+ J1939_NO_NAME, /* p_peer_name */
+ v_pdu_send2 /* p_j1939_pdu_expected */))
+
+ 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_j1939SendInitiator1:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_j1939FrameReceiver1:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_j1939SendInitiator2:pt_sync)
+ disconnect(mtc:pt_sync, v_ptc_j1939FrameReceiver2:pt_sync)
+ all component.kill;
+}
+
+testcase tc_can_f_j1939_address_claim() runs on MTC {
+ var PTC v_ptc_j1939AddressClaimInitiator := PTC.create("PTC1_ptc_j1939AddressClaimInitiator") alive
+
+ f_addSyncSlaveSet(v_ptc_j1939AddressClaimInitiator, v_PTCSet)
+
+ connect(mtc:pt_sync, v_ptc_j1939AddressClaimInitiator:pt_sync)
+
+ const J1939_NAME c_j1939_name_source := '1122334455667788'O
+
+ v_ptc_j1939AddressClaimInitiator.start(f_j1939_address_claim(
+ e_testbody1,
+ c_j1939_name_source))
+
+ 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_j1939AddressClaimInitiator:pt_sync)
+
+
+ all component.kill;
+}
+
+testcase tc_can_f_j1939_address_claim2() runs on MTC {
+ var PTC v_ptc_j1939AddressClaimInitiator := PTC.create("PTC1_ptc_j1939AddressClaimInitiator") alive
+
+ f_addSyncSlaveSet(v_ptc_j1939AddressClaimInitiator, v_PTCSet)
+
+ connect(mtc:pt_sync, v_ptc_j1939AddressClaimInitiator:pt_sync)
+
+ const J1939_NAME c_j1939_name_source := '1122334455667788'O
+ const octetstring c_j1939_pdu_send := '00EE00'O
+
+ v_ptc_j1939AddressClaimInitiator.start(f_j1939_address_claim2(
+ e_testbody1,
+ c_j1939_name_source,
+ c_j1939_pdu_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_j1939AddressClaimInitiator:pt_sync)
+
+
+ all component.kill;
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+// Insert control part here if applicable!
+
+} // end of module
diff --git a/doc/README.md b/doc/README.md
index 083183d..de9ee7f 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -45,7 +45,7 @@
# or create a physical can interface
# sudo ip link set can0 up type can bitrate 1000000
-ifconfig
+ip a
#--------------------------------------
@@ -113,12 +113,32 @@
There is an endlessly running test case:
ttcn3_start SocketCAN SocketCAN.cfg Isotptest.tc_Isotp_Example001
+-CAN J1939:
+Configure CAN J1939 as following (requires Kernel 5.4 and compiled with can-j1939 kernel module):
+sudo modprobe vcan
+sudo ip link add vcan0 type vcan
+sudo ip link set vcan0 up
+sudo modprobe can-j1939
+
+For the following test cases, the messages are so huge that screen output of the log file takes too long.
+Thus comment out as following the following lines in J1939.cfg:
+//FileMask := LOG_ALL | DEBUG | MATCHING
+//ConsoleMask := LOG_ALL | DEBUG | MATCHING
+
+ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_j1939_send_and_receive_can_frame
+ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_j1939_send_and_receive_can_frame_parallel
+
+Here above lines can be commented in:
+ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_f_j1939_address_claim
+ttcn3_start SocketCAN J1939.cfg SocketCAN_J1939_test.tc_can_f_j1939_address_claim2
+
+
-Merging of logfiles:
To merge the logfies from multiple Parallel Test Componets (PTCs) from a
single run in timely order into sigle file, run:
- $ TTCN3_DIR/bin/ttcn3_logmerge -o log_merged.txt *.log
+ $TTCN3_DIR/bin/ttcn3_logmerge -o log_merged.txt *.log
The merged log-file is found at log_merged.txt
--Dunping CAN Frames using SocketCAN:
+-Dumping CAN Frames using SocketCAN:
To dump all received can frames of e.g. "vcan0" run a seperate terminal:
$ candump "vcan0"
diff --git a/src/Can.ttcn b/src/Can.ttcn
index 95a24d2..4895d42 100644
--- a/src/Can.ttcn
+++ b/src/Can.ttcn
@@ -13,7 +13,7 @@
module Can
{
-import from General_Types all;
+
// special address description flags for the CAN_ID
@@ -126,7 +126,8 @@
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_J1939 (7), // SAE J1939 Protocol
+CAN_NPROTO (8)
}
// CAN payload length and DLC definitions according to ISO 11898-1
diff --git a/src/General_Types.ttcn b/src/General_Types.ttcn
index 4779a25..9f00161 100644
--- a/src/General_Types.ttcn
+++ b/src/General_Types.ttcn
@@ -242,16 +242,16 @@
// Verdicttypes
//****************************************************
- type record of verdicttype Verdicttypes with { variant "" };
+ type record of verdicttype Verdicttypes;
type Verdicttypes VerdicttypeList;
- type set of verdicttype VerdicttypeSet with { variant "" };
+ type set of verdicttype VerdicttypeSet;
//****************************************************
// Anytypes
//****************************************************
type record of anytype Anytypes with { variant "" };
- type Anytypes AnytypeList;
+ type Anytypes AnytypeList with { variant "" };
type set of anytype AnytypeSet with { variant "" };
} // end group NativeTypes
@@ -372,8 +372,8 @@
type record of OCT6 OCT6List with { variant "" };
type record of OCT7 OCT7List with { variant "" };
- type record of Dummy_comptype ListOfDummy_comptype with { variant "" };
- type record of Dummy_CT ListOfDummy_CT with { variant "" };
+ type record of Dummy_comptype ListOfDummy_comptype;
+ type record of Dummy_CT ListOfDummy_CT;
type record of Protocols ProtocolList with { variant "" };
} // end group CompositeTypes
diff --git a/src/J1939.ttcn b/src/J1939.ttcn
new file mode 100644
index 0000000..be62538
--- /dev/null
+++ b/src/J1939.ttcn
@@ -0,0 +1,44 @@
+/* Copyright (c) 2000-2019 Ericsson Telecom AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+
+module J1939 {
+import from General_Types all;
+
+const octetstring J1939_MAX_UNICAST_ADDR := 'FD'O
+const octetstring J1939_IDLE_ADDR := 'FE'O
+const octetstring J1939_NO_ADDR := 'FF'O
+const J1939_NAME J1939_NO_NAME := '0000000000000000'O
+const octetstring J1939_PGN_REQUEST := '00ea00'O /* Request PG */
+const octetstring J1939_PGN_ADDRESS_CLAIMED := '00ee00'O /* Address Claimed */
+const octetstring J1939_PGN_ADDRESS_COMMANDED := '00fed8'O /* Commanded Address */
+const octetstring J1939_PGN_PDU1_MAX := '03ff00'O
+const octetstring J1939_PGN_MAX := '03ffff'O
+const octetstring J1939_NO_PGN := '040000'O
+
+type OCT3 J1939_PGN // max 0x3ffff
+type OCT8 J1939_NAME
+type OCT1 J1939_ADDR
+
+
+type integer J1939_Priority (0..7)
+
+type record J1939_hdr{
+ J1939_NAME name optional,
+ // pgn:
+ // * 8 bit: PS in PDU2 case, else 0
+ // * 8 bit: PF
+ // * 1 bit: DP
+ // * 1 bit: reserved
+ J1939_PGN pgn optional,
+ // * 1 byte address *
+ J1939_ADDR addr optional
+}
+
+}
diff --git a/src/Raw.ttcn b/src/Raw.ttcn
index 0c1f0b8..ae7ffff 100644
--- a/src/Raw.ttcn
+++ b/src/Raw.ttcn
@@ -34,14 +34,4 @@
type bitstring CAN_RAW_err_mask length (32);
-type enumerated DisableEnable_enum {
- Disable (0),
- Enable (1)
-}
-
-type DisableEnable_enum CAN_RAW_loopback_enum;
-type DisableEnable_enum CAN_RAW_recv_own_msgs_enum;
-type DisableEnable_enum CAN_RAW_fd_frames_enum;
-type DisableEnable_enum CAN_RAW_join_filters_enum;
-
}
diff --git a/src/SocketCAN_PT.cc b/src/SocketCAN_PT.cc
index 89d8aa8..69f6c42 100644
--- a/src/SocketCAN_PT.cc
+++ b/src/SocketCAN_PT.cc
@@ -1,1758 +1,2237 @@
-/******************************************************************************
- * Copyright (c) 2000-2019 Ericsson Telecom AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
- *
- * Contributors:
- * Michael Josenhans
- ******************************************************************************/
-//
-// File: SocketCAN_PT.cc
-// Description: SocketCAN_PT test port source
-//
-// Revision R2D
-#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 <linux/sockios.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 //CAN_MTU
-
-// comment out the following define, if your kernel does not have CANFD support
-#define CANFD_SUPPORT
-#ifdef CANFD_SUPPORT
-
-// make sure CANFD_MTU is defined, as not defined in some older kernel versions.
-#ifndef CANFD_MTU
-#define CANFD_MTU (sizeof(struct canfd_frame))
-#endif //CANFD_MTU
-
-// make sure CAN_FD_FRAME is defined, as not defined in some older kernel versions
-// and thus canfd frames can not be used for data transfer between
-// kernel module and userspace
-#ifndef CAN_FD_FRAME
-#define CAN_FD_FRAME 0x0800
-#endif //CAN_FD_FRAME
-
-#define CANFD_FRAME_STRUCT_DEFINED
-#define RAW_CANFD_SUPPORT
-#define BCM_CANFD_SUPPORT
-
-#endif //CANFD_SUPPORT
-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 assume 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);
-
- parameters.ifr().if__index() = ifr.ifr_ifindex;
- parameters.ifr().if__name() =
- "SocketCAN : device name unknown, ioctl failed";
- } else {
-#ifdef CANFD_FRAME_STRUCT_DEFINED
- if (nbytes == CANFD_MTU) {
- log(
- "SocketCAN: Received a CANFD frame from interface %s",
- ifr.ifr_name, nbytes, frame.len);
- } else {
- 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() = 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
- if (nbytes == CANFD_MTU) {
- frameref.can__flags() = BITSTRING(
- int2bit(frame.flags, 8));
- }
-#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].fd = 0;
- 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: {
- const int canfd_on = 1;
- setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on,
- sizeof(canfd_on));
- 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: {
- {
- // Enabling FD support had been successful!
- log(
- "SocketCAN: Enabling FD support had been successful on socket %d",
- sock);
-
- 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());
- fd_frame.flags = bit2int(
- send_par.frame().canfd__frame().can__flags());
- memcpy(fd_frame.data,
- send_par.frame().canfd__frame().can__pdu(), len);
- fd_frame.len = len;
- fd_frame.__res0 = 0x00;
- fd_frame.__res1 = 0x00;
-
- 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 with error code: %d",
- nrOfBytestoSend, nrOfBytesSent);
- 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()) | CAN_FD_FRAME;
- // set CAN_FD_FRAME-flag to indicate canfd frames are following
- 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 */
-
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ * Michael Josenhans
+ ******************************************************************************/
+//
+// File: SocketCAN_PT.cc
+// Description: SocketCAN_PT test port source
+//
+// Revision R2D
+// comment out the following define, if your kernel does not have j1939 support
+#define CANJ1939_SUPPORT
+#ifdef CANJ1939_SUPPORT
+#include <linux/can/j1939.h>
+#endif //CANJ1939_SUPPORT
+
+#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 <linux/sockios.h>
+#include <Logger.hh>
+#include <memory.h>
+#include <Octetstring.hh>
+#include <Hexstring.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
+#define J1939_RECIEVE_BUFSIZE 117440505 //(2²⁴-1)*7= 117440505 Bytes
+
+//// 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 //CAN_MTU
+
+// comment out the following define, if your kernel does not have CANFD support
+#define CANFD_SUPPORT
+#ifdef CANFD_SUPPORT
+
+// make sure CANFD_MTU is defined, as not defined in some older kernel versions.
+#ifndef CANFD_MTU
+#define CANFD_MTU (sizeof(struct canfd_frame))
+#endif //CANFD_MTU
+
+// make sure CAN_FD_FRAME is defined, as not defined in some older kernel versions
+// and thus canfd frames can not be used for data transfer between
+// kernel module and userspace
+#ifndef CAN_FD_FRAME
+#define CAN_FD_FRAME 0x0800
+#endif //CAN_FD_FRAME
+
+#define CANFD_FRAME_STRUCT_DEFINED
+#define RAW_CANFD_SUPPORT
+#define BCM_CANFD_SUPPORT
+
+#endif //CANFD_SUPPORT
+
+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_J1939: {
+#ifdef CANJ1939_SUPPORT
+ SocketCAN__Types::SocketCAN__receive__j1939__message parameters;
+
+ unsigned char *msg = new unsigned char[J1939_RECIEVE_BUFSIZE];
+ long 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, J1939_RECIEVE_BUFSIZE, 0,
+ (struct sockaddr*) &addr, &addr_len);
+
+ //nbytes = read(sock, msg, J1939_RECIEVE_BUFSIZE);
+ if (nbytes > 0 && nbytes < J1939_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);
+ parameters.pgn() = int2oct(addr.can_addr.j1939.pgn, 3);
+ parameters.name() = int2oct(addr.can_addr.j1939.name, 8);
+ parameters.destAddr() = int2oct(addr.can_addr.j1939.addr,
+ 1);
+ incoming_message(parameters);
+ }
+ delete[] msg;
+#else // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not compiled for your current kernel error");
+#endif // CANJ1939_SUPPORT
+ }
+ break;
+
+ 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 assume 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;
+ sock_list[a].j1939_bound = false;
+ sock_list[a].j1939_connected = false;
+ 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);
+
+ parameters.ifr().if__index() = ifr.ifr_ifindex;
+ parameters.ifr().if__name() =
+ "SocketCAN : device name unknown, ioctl failed";
+ } else {
+#ifdef CANFD_FRAME_STRUCT_DEFINED
+ if (nbytes == CANFD_MTU) {
+ log(
+ "SocketCAN: Received a CANFD frame from interface %s",
+ ifr.ifr_name, nbytes, frame.len);
+ } else {
+ 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() = 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
+ if (nbytes == CANFD_MTU) {
+ frameref.can__flags() = BITSTRING(
+ int2bit(frame.flags, 8));
+ }
+#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;
+ sock_list[a].j1939_bound = false;
+ sock_list[a].j1939_connected = false;
+ 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::Handle_Timeout(double time_since_last_call) {}*/
+
+void SocketCAN__PT_PROVIDER::user_map(const char* /*system_port*/,
+ Map_Params& /*params*/) {
+ 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_debugging 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].fd = 0;
+ sock_list[a].status = SOCKET_NOT_ALLOCATED;
+ sock_list[a].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
+ sock_list[a].j1939_bound = false;
+ sock_list[a].j1939_connected = false;
+ }
+
+ log("leaving SocketCAN__PT_PROVIDER::user_map()");
+}
+
+void SocketCAN__PT_PROVIDER::user_unmap(const char* /*system_port*/,
+ Map_Params& /*params*/) {
+ 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 field 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)");
+
+ bool j1939_connected = false;
+ 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_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_J1939)
+ && (sock_list[cn].j1939_connected == false))) {
+ sock = sock_list[cn].fd;
+
+ 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();
+ addr.can_family = AF_CAN;
+ sock_list[cn].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
+ 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);
+ }
+ break;
+ case SocketCAN__Types::SocketCAN__connectu::ALT_j1939:
+#ifdef CANJ1939_SUPPORT
+ addr.can_ifindex = connectu.j1939().if__index();
+ sock_list[cn].protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_J1939;
+
+ addr.can_family = AF_CAN;
+ addr.can_addr.j1939.addr = J1939_NO_ADDR;
+ addr.can_addr.j1939.name = J1939_NO_NAME;
+ addr.can_addr.j1939.pgn = J1939_NO_PGN;
+
+ if (connectu.j1939().j1939__destination().addr().is_present()) {
+ const OPTIONAL<J1939::J1939__ADDR> &addr_ =
+ connectu.j1939().j1939__destination().addr();
+ addr.can_addr.j1939.addr = oct2int(addr_);
+ }
+ if (connectu.j1939().j1939__destination().name().is_present()) {
+ const OPTIONAL<J1939::J1939__NAME> &name =
+ connectu.j1939().j1939__destination().name();
+ //addr.can_addr.j1939.name = oct2int(name);
+ addr.can_addr.j1939.name = (__u64) oct2int(name).get_long_long_val();
+ }
+ if (connectu.j1939().j1939__destination().pgn().is_present()) {
+ const OPTIONAL<J1939::J1939__PGN>& pgn =
+ connectu.j1939().j1939__destination().pgn();
+ addr.can_addr.j1939.pgn = oct2int(pgn);
+ }
+ log("SocketCAN: Sending J1939 message)");
+
+ log("Connecting socket: %d with index: %d to addr %x, name %llx, pgn %x",
+ sock, addr.can_ifindex, addr.can_addr.j1939.addr,
+ addr.can_addr.j1939.name, addr.can_addr.j1939.pgn);
+ //extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
+ j1939_connected = true;
+ 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_J1939;
+ sock_list[cn].j1939_connected = j1939_connected;
+ 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 // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is compiled for your current kernel error");
+#endif // CANJ1939_SUPPORT
+ break;
+ default:
+ TTCN_error(
+ "connectu union selection does not exist on socket %d: \n",
+ sock);
+ break;
+ }
+
+ } 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)
+ || ((sock_list[cn].protocol_family
+ == SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_J1939)
+ && (sock_list[cn].j1939_bound == false))) {
+
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_protocol_family_enum protocol_family;
+ bool j1939_bound = false;
+
+ 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: {
+ const int canfd_on = 1;
+ setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on,
+ sizeof(canfd_on));
+ addr.can_ifindex = bindu.raw().if__index();
+ protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW;
+ }
+ break;
+ case SocketCAN__Types::SocketCAN__bindu::ALT_isotp:
+ addr.can_ifindex = 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;
+ case SocketCAN__Types::SocketCAN__bindu::ALT_j1939:
+#ifdef CANJ1939_SUPPORT
+ addr.can_ifindex = bindu.j1939().if__index();
+ if (bindu.j1939().j1939__source().addr().is_present()) {
+ const OPTIONAL<J1939::J1939__ADDR> &addr_ =
+ bindu.j1939().j1939__source().addr();
+ addr.can_addr.j1939.addr = oct2int(addr_);
+ }
+ if (bindu.j1939().j1939__source().name().is_present()) {
+ const OPTIONAL<J1939::J1939__NAME> &name =
+ bindu.j1939().j1939__source().name();
+ addr.can_addr.j1939.name = (__u64) oct2int(name).get_long_long_val();
+ }
+ if (bindu.j1939().j1939__source().pgn().is_present()) {
+ const OPTIONAL<J1939::J1939__PGN>& pgn =
+ bindu.j1939().j1939__source().pgn();
+ addr.can_addr.j1939.pgn = oct2int(pgn);
+ }
+
+ log("SocketCAN: Binding socket J1939 to addr %x, name %llx, pgn %x",
+ addr.can_addr.j1939.addr, addr.can_addr.j1939.name, addr.can_addr.j1939.pgn);
+
+ j1939_bound=true;
+ protocol_family =
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_J1939;
+#else // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+ break;
+ default:
+ TTCN_error(
+ "bindu union selection does not exist on socket %d: \n",
+ sock);
+ break;
+ }
+ log("Binding socket: %d with index: %d", sock, addr.can_ifindex);
+ 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;
+ sock_list[cn].j1939_bound = j1939_bound;
+ 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: {
+ {
+ // Enabling FD support had been successful!
+ log(
+ "SocketCAN: Enabling FD support had been successful on socket %d",
+ sock);
+
+ 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());
+ fd_frame.flags = bit2int(
+ send_par.frame().canfd__frame().can__flags());
+ memcpy(fd_frame.data,
+ send_par.frame().canfd__frame().can__pdu(), len);
+ fd_frame.len = len;
+ fd_frame.__res0 = 0x00;
+ fd_frame.__res1 = 0x00;
+
+ 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 with error code: %d",
+ nrOfBytestoSend, nrOfBytesSent);
+ 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__j1939__send__data &send_par) {
+#ifdef CANJ1939_SUPPORT
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__j1939__send__data)");
+
+ SocketCAN__Types::SocketCAN__j1939__send__data__result result;
+ int sock;
+ int cn = send_par.id();
+
+ if ((cn < sock_list_length)) {
+ long nrOfBytesSent, nrOfBytestoSend, nrOfBytesRemaining;
+ sock = sock_list[cn].fd;
+
+ log("SocketCAN: Sending J1939 message)");
+ //logOctet("containing data: ", send_par.pdu());
+
+ nrOfBytestoSend = send_par.pdu().lengthof();
+ nrOfBytesRemaining = nrOfBytestoSend;
+ do {
+ nrOfBytesSent = send(sock, (const void*)((const unsigned char*)send_par.pdu()+nrOfBytestoSend-nrOfBytesRemaining), nrOfBytesRemaining, 0);
+ nrOfBytesRemaining = nrOfBytesRemaining - nrOfBytesSent;
+ } while ((nrOfBytesSent >= 0) and (nrOfBytesRemaining != 0));
+
+ log("Sent J1939 message with send of size %d", nrOfBytesSent);
+ if (nrOfBytesSent < 0) {
+ log("Sent J1939 message with pdu of size %d failed", nrOfBytesSent);
+ TTCN_error(
+ "SocketCAN j1939 send with send() error while trying to send J1939 message of %ld 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 J1939 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;
+ }
+
+ log("SocketCAN: Nr of bytes sent = %ld", nrOfBytesSent);
+ } 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__j1939__send__data)");
+#else // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+}
+
+void SocketCAN__PT_PROVIDER::outgoing_send(
+ const SocketCAN__Types::SocketCAN__j1939__send__data__to &send_par) {
+#ifdef CANJ1939_SUPPORT
+ log(
+ "entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__j1939__send__data__to)");
+
+ SocketCAN__Types::SocketCAN__j1939__send__data__to__result result;
+ int sock;
+ int cn = send_par.id();
+
+ if ((cn < sock_list_length)) {
+ struct sockaddr_can destaddr;
+ long nrOfBytesSent, nrOfBytestoSend, nrOfBytesRemaining;
+ sock = sock_list[cn].fd;
+
+ destaddr.can_ifindex = send_par.if__index();
+ destaddr.can_family = AF_CAN;
+ destaddr.can_addr.j1939.addr = J1939_NO_ADDR;
+ destaddr.can_addr.j1939.name = J1939_NO_NAME;
+ destaddr.can_addr.j1939.pgn = J1939_NO_PGN;
+
+ if (send_par.j1939__destination().addr().is_present()) {
+ const OPTIONAL<J1939::J1939__ADDR> &addr =
+ send_par.j1939__destination().addr();
+ destaddr.can_addr.j1939.addr = oct2int(addr);
+ }
+ if (send_par.j1939__destination().name().is_present()) {
+ const OPTIONAL<J1939::J1939__NAME> &name =
+ send_par.j1939__destination().name();
+ //destaddr.can_addr.j1939.name = oct2int(name);
+ destaddr.can_addr.j1939.name = (__u64) oct2int(name).get_long_long_val();
+ }
+ if (send_par.j1939__destination().pgn().is_present()) {
+ const OPTIONAL<J1939::J1939__PGN> &pgn =
+ send_par.j1939__destination().pgn();
+ destaddr.can_addr.j1939.pgn = oct2int(pgn);
+ }
+
+ log("SocketCAN: Sending J1939 message to addr %x, name %llx, pgn %x",
+ destaddr.can_addr.j1939.addr, destaddr.can_addr.j1939.name,
+ destaddr.can_addr.j1939.pgn);
+ //logOctet("containing data: ", send_par.pdu());
+
+ nrOfBytestoSend = send_par.pdu().lengthof();
+ nrOfBytesRemaining = nrOfBytestoSend;
+ do {
+ nrOfBytesSent = sendto(sock, (const void*)((const unsigned char*)send_par.pdu()+nrOfBytestoSend-nrOfBytesRemaining),
+ nrOfBytesRemaining, 0, (struct sockaddr*) &destaddr, sizeof(destaddr));
+ nrOfBytesRemaining = nrOfBytesRemaining - nrOfBytesSent;
+ } while ((nrOfBytesSent >= 0) and (nrOfBytesRemaining != 0));
+
+ log(
+ "Sent J1939 message with send of size %d to addr %x, name %llx, pgn %x",
+ nrOfBytesSent, destaddr.can_addr.j1939.addr,
+ destaddr.can_addr.j1939.name, destaddr.can_addr.j1939.pgn);
+ if (nrOfBytesSent < 0) {
+ log(
+ "Sent J1939 message with pdu of size %d to addr %x, name %llx, pgn %x failed",
+ nrOfBytesSent, destaddr.can_addr.j1939.addr,
+ destaddr.can_addr.j1939.name, destaddr.can_addr.j1939.pgn);
+ result.result().result__code() =
+ SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
+ result.result().err() = errno;
+ result.result().err__text() = "SocketCAN send with send() error";
+ TTCN_error(
+ "SocketCAN j1939 sendto() error while trying to send J1939 message of %ld bytes to addr %x, name %llx, pgn %x",
+ nrOfBytestoSend, destaddr.can_addr.j1939.addr,
+ destaddr.can_addr.j1939.name, destaddr.can_addr.j1939.pgn);
+ } else {
+ log(
+ "SocketCAN send J1939 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;
+ }
+
+ log("SocketCAN: Nr of bytes sent = %ld", nrOfBytesSent);
+ } 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__j1939__send__data__to)");
+#else // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+}
+
+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()) | CAN_FD_FRAME;
+ // set CAN_FD_FRAME-flag to indicate canfd frames are following
+ 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 loopback 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 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;
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_j1939__filter: {
+#ifdef CANJ1939_SUPPORT
+ std::size_t j1939_filters_size =
+ (sizeof(send_par.command().j1939__filter())
+ / sizeof(send_par.command().j1939__filter()[0]));
+
+ struct j1939_filter j1939_filters[j1939_filters_size];
+
+ if (j1939_filters_size == 0) {
+ // deactivate filters
+ res = setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, NULL, 0);
+
+ } else {
+ for (std::size_t i = 0; i < j1939_filters_size; i++) {
+
+ j1939_filters[i].name = J1939_NO_NAME;
+ j1939_filters[i].name_mask = J1939_NO_NAME;
+ j1939_filters[i].pgn = J1939_NO_PGN;
+ j1939_filters[i].pgn_mask = J1939_NO_PGN;
+ j1939_filters[i].addr = J1939_NO_ADDR;
+ j1939_filters[i].addr_mask = J1939_NO_ADDR;
+
+ if (send_par.command().j1939__filter()[i].name__filter().is_present()) {
+ const OPTIONAL<SocketCAN__Types::J1939__NAME__filter> &name_filter =
+ send_par.command().j1939__filter()[i].name__filter();
+ j1939_filters[i].name = oct2int(name_filter().name());
+ j1939_filters[i].name_mask = oct2int(
+ name_filter().name__mask());
+ }
+ if (send_par.command().j1939__filter()[i].pgn__filter().is_present()) {
+ const OPTIONAL<SocketCAN__Types::J1939__PGN__filter> &pgn_filter =
+ send_par.command().j1939__filter()[i].pgn__filter();
+ j1939_filters[i].pgn = oct2int(pgn_filter().pgn());
+ j1939_filters[i].pgn_mask = oct2int(
+ pgn_filter().pgn__mask());
+ }
+ if (send_par.command().j1939__filter()[i].addr__filter().is_present()) {
+ const OPTIONAL<SocketCAN__Types::J1939__ADDR__filter> &addr_filter =
+ send_par.command().j1939__filter()[i].addr__filter();
+ j1939_filters[i].addr = oct2int(addr_filter().addr());
+ j1939_filters[i].addr_mask = oct2int(
+ addr_filter().addr__mask());
+ }
+
+ log(
+ "Setting filter J1939: addr %x, addr_mask, name %llx, name_mask %llx, pgn %x, pgn_mask %x",
+ j1939_filters[i].name, j1939_filters[i].name_mask,
+ j1939_filters[i].pgn, j1939_filters[i].pgn_mask,
+ j1939_filters[i].addr, j1939_filters[i].addr_mask);
+
+ };
+ res = setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER,
+ &j1939_filters, sizeof(j1939_filters));
+ }
+ if (res < 0) {
+ TTCN_error(
+ "SocketCAN setsockopt j1939_filter 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 j1939_filter failed";
+
+ } else {
+ log(
+ "SocketCAN: setsockopt j1939_filter 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 // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_j1939__promisc: {
+#ifdef CANJ1939_SUPPORT
+ int j1939_promisc = send_par.command().j1939__promisc();
+ res = setsockopt(sock, SOL_CAN_J1939, SO_J1939_PROMISC,
+ &j1939_promisc, sizeof(j1939_promisc));
+
+ if (res < 0) {
+ int myerrno = errno;
+ TTCN_error(
+ "SocketCAN setsockopt j1939_promisc 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 j1939_promisc failed";
+ } else {
+ log(
+ "SocketCAN: setsockopt j1939_promisc 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 // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_j1939__prio: {
+#ifdef CANJ1939_SUPPORT
+ int j1939_prio = send_par.command().j1939__prio();
+ res = setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO,
+ &j1939_prio, sizeof(j1939_prio));
+ if (res < 0) {
+ int myerrno = errno;
+ TTCN_error(
+ "SocketCAN setsockopt j1939_prio 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 j1939_prio failed";
+ } else {
+ log("SocketCAN: setsockopt j1939_prio 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 // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+ }
+ break;
+
+ case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_j1939__broadcast: {
+#ifdef CANJ1939_SUPPORT
+ int j1939_broadcast = send_par.command().j1939__broadcast();
+ res = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &j1939_broadcast,
+ sizeof(j1939_broadcast));
+ if (res < 0) {
+ int myerrno = errno;
+ TTCN_error(
+ "SocketCAN setsockopt j1939_broadcast 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 j1939_broadcast failed";
+ } else {
+ log(
+ "SocketCAN: setsockopt j1939_broadcast 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 // CANJ1939_SUPPORT
+ TTCN_error("SocketCAN: CAN J1939 is not supported by your current kernel error");
+#endif // CANJ1939_SUPPORT
+ }
+ 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;
+ sock_list[send_par.id()].j1939_bound = false;
+ sock_list[send_par.id()].j1939_connected = false;
+ 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;
+ sock_list[a].j1939_bound = false;
+ sock_list[a].j1939_connected = false;
+
+ 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 8c2b5a2..94d70dc 100644
--- a/src/SocketCAN_PT.hh
+++ b/src/SocketCAN_PT.hh
@@ -1,134 +1,130 @@
-/******************************************************************************
- * Copyright (c) 2000-2019 Ericsson Telecom AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
- *
- * Contributors:
- * Michel Josenhans
- ******************************************************************************/
-//
-// File: SocketCAN_PT.hh
-// Description: SocketCAN test port header
-//
-// Revision R2D
-
-#ifndef SocketCAN__PT_HH
-#define SocketCAN__PT_HH
-
-#include <TTCN3.hh>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "linux/can.h"
-#include "SocketCAN_Types.hh"
-
-// Note: Header file SocketCAN_PortType.hh must not be included into this file!
-// (because it includes this file)
-// Please add the declarations of message types manually.
-namespace SocketCAN__Types {
-class SocketCAN;
-}
-
-namespace SocketCAN__PortType {
-
-class SocketCAN__PT_PROVIDER: public PORT {
-public:
- SocketCAN__PT_PROVIDER(const char *par_port_name = NULL);
- ~SocketCAN__PT_PROVIDER();
-
- void set_parameter(const char *parameter_name, const char *parameter_value);
-
-private:
- /* void Handle_Fd_Event(int fd, boolean is_readable,
- boolean is_writable, boolean is_error); */
- void Handle_Fd_Event_Error(int fd);
- void Handle_Fd_Event_Writable(int fd);
- void Handle_Fd_Event_Readable(int fd);
- /* void Handle_Timeout(double time_since_last_call); */
-protected:
- void user_map(const char *system_port);
- void user_unmap(const char *system_port);
-
- void user_start();
- void user_stop();
-
- void outgoing_send(const SocketCAN__Types::SocketCAN__socket& send_par);
- void outgoing_send(const SocketCAN__Types::SocketCAN__ioctl& send_par);
- void outgoing_send(const SocketCAN__Types::SocketCAN__connect& send_par);
- void outgoing_send(const SocketCAN__Types::SocketCAN__bind& send_par);
- 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(
- const SocketCAN__Types::SocketCAN__socket__result& incoming_par) = 0;
- virtual void incoming_message(
- const SocketCAN__Types::SocketCAN__ioctl__result& incoming_par) = 0;
- virtual void incoming_message(
- const SocketCAN__Types::SocketCAN__connect__result& incoming_par) = 0;
- virtual void incoming_message(
- const SocketCAN__Types::SocketCAN__bind__result& incoming_par) = 0;
- virtual void incoming_message(
- 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();
- void reset_configuration();
- void InitStrPar(char *&par, const char *name, const char *val);
- void log(const char *fmt, ...);
- void logOctet(const char *prompt, const OCTETSTRING& msg);
- void logHex(const char *prompt, const HEXSTRING& msg);
- void logInteger(const char *prompt, const int number);
- void logBitstring(const char *prompt, const BITSTRING& msg);
- void setUpSocket();
- void closeDownSocket();
-
-private:
- enum socket_allocation_enum {
- SOCKET_NOT_ALLOCATED = 0, SOCKET_OPEN = 1
- };
- enum socket_protocol_family_enum {
- SOCKET_NO_PROTOCOL = 0,
- SOCKET_PROTOCOL_CAN_BCM = 1,
- SOCKET_PROTOCOL_CAN_RAW = 2,
- SOCKET_PROTOCOL_CAN_ISOTP = 6
- };
-
- struct sock_data {
- int fd;
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_allocation_enum status;
- SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_protocol_family_enum protocol_family;
- struct sockaddr_can remote_Addr;
- };
-
- sock_data *sock_list;
- int num_of_sock;
- int sock_list_length;
-
- int target_fd;
- // test port parameters
- char* can_interface_name;
- bool debugging;
- bool debugging_configured;
- bool config_finished;
-};
-
-} /* end of namespace */
-
-#endif
+/******************************************************************************
+ * Copyright (c) 2000-2019 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ * Michel Josenhans
+ ******************************************************************************/
+//
+// File: SocketCAN_PT.hh
+// Description: SocketCAN test port header
+//
+// Revision R2D
+
+#ifndef SocketCAN__PT_HH
+#define SocketCAN__PT_HH
+
+#include <TTCN3.hh>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "linux/can.h"
+#include "../demo/SocketCAN_Types.hh"
+
+
+// Note: Header file SocketCAN_PortType.hh must not be included into this file!
+// (because it includes this file)
+// Please add the declarations of message types manually.
+
+namespace SocketCAN__PortType {
+
+class SocketCAN__PT_PROVIDER : public PORT {
+public:
+ SocketCAN__PT_PROVIDER(const char *par_port_name);
+ ~SocketCAN__PT_PROVIDER();
+
+ void set_parameter(const char *parameter_name,
+ const char *parameter_value);
+
+private:
+ /* void Handle_Fd_Event(int fd, boolean is_readable,
+ boolean is_writable, boolean is_error); */
+ void Handle_Fd_Event_Error(int fd);
+ void Handle_Fd_Event_Writable(int fd);
+ void Handle_Fd_Event_Readable(int fd);
+ /* void Handle_Timeout(double time_since_last_call); */
+protected:
+ void user_map(const char *system_port, Map_Params& params);
+ void user_unmap(const char *system_port, Map_Params& params);
+
+ void user_start();
+ void user_stop();
+
+ void outgoing_send(const SocketCAN__Types::SocketCAN__socket& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__ioctl& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__connect& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__bind& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__send__data& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__j1939__send__data& send_par);
+ void outgoing_send(const SocketCAN__Types::SocketCAN__j1939__send__data__to& 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(const SocketCAN__Types::SocketCAN__socket__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__ioctl__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__connect__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__bind__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__send__data__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__j1939__send__data__result& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__j1939__send__data__to__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__receive__j1939__message& incoming_par) = 0;
+ virtual void incoming_message(const SocketCAN__Types::SocketCAN__setsockopt__result& incoming_par) = 0;
+ void set_asp_params();
+ void reset_configuration();
+ void InitStrPar(char *&par, const char *name, const char *val);
+ void log(const char *fmt, ...);
+ void logOctet(const char *prompt, const OCTETSTRING& msg);
+ void logHex(const char *prompt, const HEXSTRING& msg);
+ void logInteger(const char *prompt, const int number);
+ void logBitstring(const char *prompt, const BITSTRING& msg);
+ void setUpSocket();
+ void closeDownSocket();
+
+private:
+ enum socket_allocation_enum {
+ SOCKET_NOT_ALLOCATED = 0, SOCKET_OPEN = 1
+ };
+ enum socket_protocol_family_enum {
+ SOCKET_NO_PROTOCOL = 0,
+ SOCKET_PROTOCOL_CAN_BCM = 1,
+ SOCKET_PROTOCOL_CAN_RAW = 2,
+ SOCKET_PROTOCOL_CAN_ISOTP = 6,
+ SOCKET_PROTOCOL_CAN_J1939 = 7
+ };
+
+ struct sock_data {
+ int fd;
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_allocation_enum status;
+ SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_protocol_family_enum protocol_family;
+ bool j1939_bound;
+ bool j1939_connected;
+ struct sockaddr_can remote_Addr;
+ };
+
+
+ sock_data *sock_list;
+ int num_of_sock;
+ int sock_list_length;
+
+ int target_fd;
+ // test port parameters
+ char* can_interface_name;
+ bool debugging;
+ bool debugging_configured;
+ bool config_finished;
+};
+
+} /* end of namespace */
+
+#endif
diff --git a/src/SocketCAN_PortType.ttcn b/src/SocketCAN_PortType.ttcn
index 598e94e..09284b3 100644
--- a/src/SocketCAN_PortType.ttcn
+++ b/src/SocketCAN_PortType.ttcn
@@ -30,6 +30,10 @@
in SocketCAN_bind_result;
out SocketCAN_send_data;
in SocketCAN_send_data_result;
+ out SocketCAN_j1939_send_data;
+ in SocketCAN_j1939_send_data_result;
+ out SocketCAN_j1939_send_data_to;
+ in SocketCAN_j1939_send_data_to_result;
out SocketCAN_write_data;
in SocketCAN_write_data_result;
out SocketCAN_write_isotp;
@@ -37,6 +41,7 @@
in SocketCAN_receive_CAN_or_CAN_FD_frame;
in SocketCAN_receive_BCM_message;
in SocketCAN_receive_isotp_pdu;
+ in SocketCAN_receive_j1939_message;
out SocketCAN_setsockopt;
in SocketCAN_setsockopt_result;
out SocketCAN_close;
diff --git a/src/SocketCAN_Templates.ttcn b/src/SocketCAN_Templates.ttcn
index e94ffad..57616a7 100644
--- a/src/SocketCAN_Templates.ttcn
+++ b/src/SocketCAN_Templates.ttcn
@@ -18,6 +18,7 @@
import from SocketCAN_Types all;
import from Bcm all
import from Can all
+import from J1939 all
template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {
result_code := v_result_code,
@@ -52,6 +53,16 @@
result := p_result
}
+template SocketCAN_j1939_send_data_result
+a_SocketCAN_j1939_send_data_result(template SocketCAN_Result p_result) := {
+ result := p_result
+}
+
+template SocketCAN_j1939_send_data_to_result
+a_SocketCAN_j1939_send_data_to_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
@@ -104,9 +115,24 @@
frame := p_frame
}
+template SocketCAN_receive_j1939_message a_SocketCAN_receive_j1939_message(
+ template SocketCAN_socketid p_id,
+ template SocketCAN_ifr p_ifr,
+ template J1939_PGN p_pgn,
+ template J1939_ADDR p_destAddr,
+ template J1939_NAME p_name,
+ template SocketCAN_J1939_PDU p_pdu) := {
+ id := p_id,
+ ifr := ?,
+ pgn := p_pgn,
+ destAddr := p_destAddr,
+ name := p_name,
+ pdu := p_pdu
+ }
+
template SocketCAN_setsockopt_result
a_SocketCAN_setsockopt_result(template SocketCAN_Result p_result) := {
result := p_result
}
-}
+}
\ No newline at end of file
diff --git a/src/SocketCAN_Types.ttcn b/src/SocketCAN_Types.ttcn
index bbae2ac..181951a 100644
--- a/src/SocketCAN_Types.ttcn
+++ b/src/SocketCAN_Types.ttcn
@@ -19,12 +19,16 @@
import from Bcm all
import from Can all
import from Raw all
+ import from J1939 all
+
+const integer J1939_FILTER_MAX := 512
type integer SocketCAN_socketid;
type charstring SocketCAN_if_name;
type integer SocketCAN_if_index (-32767 .. +32767);
type octetstring SocketCAN_Isotp_PDU
+type octetstring SocketCAN_J1939_PDU length(0..117440505); // (2^24-1)*7= 117440505
type record SocketCAN_timeval
{
@@ -90,13 +94,19 @@
}
type union SocketCAN_connectu{
- SocketCAN_connect_bcm bcm
+ SocketCAN_connect_bcm bcm,
+ SocketCAN_connect_j1939 j1939
}
type record SocketCAN_connect_bcm {
SocketCAN_if_index if_index
}
+type record SocketCAN_connect_j1939 {
+ SocketCAN_if_index if_index,
+ J1939_hdr j1939_destination
+}
+
type record SocketCAN_connect{
SocketCAN_socketid id,
SocketCAN_connectu connectu
@@ -116,9 +126,15 @@
CAN_id tx_can_id
}
+type record SocketCAN_bind_j1939 {
+ SocketCAN_if_index if_index,
+ J1939_hdr j1939_source
+}
+
type union SocketCAN_bindu{
SocketCAN_bind_raw raw,
- SocketCAN_bind_isotp isotp
+ SocketCAN_bind_isotp isotp,
+ SocketCAN_bind_j1939 j1939
}
type record SocketCAN_bind{
@@ -142,6 +158,26 @@
SocketCAN_Result result
}
+type record SocketCAN_j1939_send_data{
+ SocketCAN_socketid id,
+ SocketCAN_J1939_PDU pdu
+}
+
+type record SocketCAN_j1939_send_data_result{
+ SocketCAN_Result result
+}
+
+type record SocketCAN_j1939_send_data_to{
+ SocketCAN_socketid id,
+ SocketCAN_if_index if_index,
+ J1939_hdr j1939_destination,
+ SocketCAN_J1939_PDU pdu
+}
+
+type record SocketCAN_j1939_send_data_to_result{
+ SocketCAN_Result result
+}
+
type record SocketCAN_write_data{
SocketCAN_socketid id,
SocketCAN_bcm_frame bcm_tx_msg
@@ -179,34 +215,52 @@
SocketCAN_Isotp_PDU pdu
}
+type record SocketCAN_receive_j1939_message { // recieved J1939 message
+ SocketCAN_socketid id,
+ SocketCAN_ifr ifr,
+ J1939_PGN pgn,
+ J1939_ADDR destAddr,
+ J1939_NAME name,
+ SocketCAN_J1939_PDU pdu
+}
+
type record length (0 .. 255) of CAN_RAW_filter CAN_RAW_filters
-
+type record length (0 .. J1939_FILTER_MAX) of J1939_filter J1939_filters
+
+type record J1939_NAME_filter {
+ J1939_NAME name,
+ J1939_NAME name_mask
+}
+
+type record J1939_ADDR_filter {
+ J1939_ADDR addr,
+ J1939_ADDR addr_mask
+}
+
+type record J1939_PGN_filter {
+ J1939_PGN pgn,
+ J1939_PGN pgn_mask
+}
+
+type record J1939_filter {
+ J1939_NAME_filter name_filter optional,
+ J1939_ADDR_filter addr_filter optional,
+ J1939_PGN_filter pgn_filter optional
+}
+
type union SocketCAN_setsockopt_commandu {
CAN_RAW_filters rfilter,
CAN_RAW_err_mask err_mask,
CAN_RAW_loopback_enum loopback,
CAN_RAW_recv_own_msgs_enum recv_own_msgs,
CAN_RAW_fd_frames_enum fd_frames,
- CAN_RAW_join_filters_enum join_filters
+ CAN_RAW_join_filters_enum join_filters,
+ J1939_filters j1939_filter,
+ J1939_PROMISC_enum j1939_promisc,
+ J1939_Priority j1939_prio,
+ J1939_Broadcast_enum j1939_broadcast
}
-//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
@@ -220,4 +274,15 @@
SocketCAN_socketid id
}
+type enumerated DisableEnable_enum {
+ Disable (0),
+ Enable (1)
+}
+
+type DisableEnable_enum CAN_RAW_loopback_enum;
+type DisableEnable_enum CAN_RAW_recv_own_msgs_enum;
+type DisableEnable_enum CAN_RAW_fd_frames_enum;
+type DisableEnable_enum CAN_RAW_join_filters_enum;
+type DisableEnable_enum J1939_PROMISC_enum;
+type DisableEnable_enum J1939_Broadcast_enum;
}