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;
 }