bugfixes and new test cases
diff --git a/README.md b/README.md
index 70fd3f6..e626961 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,117 @@
-# titan.TestPorts.SocketCANasp
-
-Main project page:
-
-https://projects.eclipse.org/projects/tools.titan
-
-The source code of the TTCN-3 compiler and executor:
-
-https://github.com/eclipse/titan.core
+# titan.TestPorts.SocketCANasp

+

+Main project page:

+

+https://projects.eclipse.org/projects/tools.titan

+

+The source code of the TTCN-3 compiler and executor:

+

+https://github.com/eclipse/titan.core

+

+

+References:

+https://www.kernel.org/doc/Documentation/networking/can.txt

+

+Other useful documentation:

+https://docs.python.org/3/library/socket.html (search for: "AF_CAN")

+https://media.readthedocs.org/pdf/python-can/latest/python-can.pdf

+http%3A%2F%2Fwww.can-cia.de%2Ffileadmin%2Fresources%2Fdocuments%2Fproceedings%2F2012_hartkopp.pdf

+http://www.can-cia.de/fileadmin/resources/documents/proceedings/2012_hartkopp.pdf

+http://v2.can-newsletter.org/uploads/media/raw/46c15d02e1fdd3b04e671693ec548ff7.pdf

+

+# See file: src/initscript.sh:

+

+#--------------------------------------

+#!/bin/bash

+

+# Add vcan module to kernel

+sudo modprobe vcan

+

+# Setup of virtual can vcan0

+sudo ip link add dev vcan0 type vcan

+# set it up at as a canfd can interface

+sudo ip link set vcan0 mtu 72

+sudo ip link set vcan0 up

+

+# Setup of virtual can vcan1

+sudo ip link add dev vcan1 type vcan

+sudo ip link set vcan1 up

+

+# example configuration of a physical can bus interface

+#sudo ip link set can0 up type can bitrate 1000000

+

+ifconfig

+

+#--------------------------------------

+

+cd src

+./demo/initscript.sh 

+

+or alternatively

+source demo/initscript.sh

+

+make clean; make

+

+ttcn3_start SocketCAN SocketCAN.cfg

+

+or to run a certain testcase:

+

+ttcn3_start SocketCAN SocketCAN.cfg  SocketCANtest.tc_can_raw1 SocketCANtest.tc_can_bcm1

+

+Review the newly created log files in the src directory

+and use e.g. Wireshark to trace the CAN interfacce.

+

+#--------------------------------------

+Notes:

+-Using multiple Test interfacces:

+ Currently the init script sets up multiple virtual can interfaces ("vcan0", 

+ "vcan1" in oder to allow using multiple CAN interfaces.

+ The CAN interfaces have to be defined in the TTCN configuration files or may 

+ alternatively be defined in the optional parameters of port messages commands 

+ ioctl and send_data.

+ 

+ Handling of multiple CAN interfaces is work in progress and no test cases are

+ provided. In order to configure usage with multiple test interfaces, 

+ test interfaces for each interface have to be defined in the MTC.

+ 

+-CAN RAW:

+ CAN and CANFD has been implemented and tested.

+ Depending on the availability of the C-code #define "CAN_FD_FRAME"

+ in /usr/include/linux/can/bcm.h, CAN-FD support is enabled at compile time.

+ If you kernel does not have CANFD support comment out the #define "CAN_FD_FRAME

+ the file "src/SocketCAN_PT.cc"

+ The RAW setsockopt has path coverage. However no test coverage that insures

+ the setsockopt functionality provided by the kernel is working correctly. 

+ For this purpose in the future might be added additional test cases.

+

+-CAN BCM:

+ TX_SETUP, TX_DELETE have been tested, TX_READ is known to fail test cases.

+ Some tests have indicated, that that SocketCAN BCM does not support concurrently

+ active BCM channels.

+ The BCM has test coverage for TX_SETUP and TX_DELETE. 

+ Return values other than the error code by the BCM are not yet supported.

+

+-ISOTP:

+ Iso TP functionality has been added, however currently no options like padding 

+ are supported. Feel free to request needed options.

+

+ First install the isotp kernel module as descibed here:

+ https://github.com/hartkopp/can-isotp-modules

+  

+  ./make_isotp.sh

+  sudo insmod ./can-isotp.ko

+ 

+

+ There is an endlessly running test case: 

+ ttcn3_start SocketCAN SocketCAN.cfg Isotptest.tc_Isotp_Example001

+ 

+-Merging of logfiles:

+ To merge the logfies from multiple Parallel Test Componets (PTCs) from a

+ single run in timely order into sigle file, run in demo directory:

+   $  ./merge.sh

+      the merged and pretty printed log file is found in "demo/log_merged_pretty.txt"

+ 

+

+-Dunping CAN Frames using SocketCAN:

+ To dump all received can frames of e.g. "vcan0" run a seperate terminal:

+   $ candump "vcan0"

diff --git a/demo/Isotptest.ttcn b/demo/Isotptest.ttcn
index 51fc61d..995339a 100644
--- a/demo/Isotptest.ttcn
+++ b/demo/Isotptest.ttcn
@@ -171,7 +171,6 @@
 runs on PTC_isotp_CT {
   pt_socketCAN.send(SocketCAN_close:{id:= p_socket_id});
 }
-
 function f_send_isotp_message(in SocketCAN_socketid p_socket_id, 
   in octetstring p_pdu)
 runs on PTC_isotp_CT{
diff --git a/demo/SocketCAN.cfg b/demo/SocketCAN.cfg
index 07e237b..eabc996 100644
--- a/demo/SocketCAN.cfg
+++ b/demo/SocketCAN.cfg
@@ -28,7 +28,8 @@
 
 [EXECUTE]
 //CAN RAW tests
-SocketCAN_RAW_test.tc_can_raw_send_and_receive_frame
+SocketCAN_RAW_test.tc_can_raw_send_and_receive_can_frame
+SocketCAN_RAW_test.tc_can_raw_send_and_receive_canfd_frame
 SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FILTER
 SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_ERR_FILTER
 SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_LOOPBACK
@@ -36,6 +37,7 @@
 SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_FD_FRAMES
 SocketCAN_RAW_test.tc_can_raw_setsockopt_CAN_RAW_JOIN_FILTERS
 //CAN BCM tests
-SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE
+SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE_can_frame
 // broken CAN BCM tests: 
-//SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken
+SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_DELETE_canfd_frame
+//SocketCAN_BCM_test.tc_can_bcm_TX_SETUP_TX_READ
diff --git a/demo/SocketCAN_BCM_test.ttcn b/demo/SocketCAN_BCM_test.ttcn
index a28cc23..543dd4e 100644
--- a/demo/SocketCAN_BCM_test.ttcn
+++ b/demo/SocketCAN_BCM_test.ttcn
@@ -21,7 +21,7 @@
 
 template SocketCAN_CAN_or_CAN_FD_frame a_CAN_frame (template CAN_frame p_can_frame) := {can_frame := p_can_frame}
 
-testcase tc_can_bcm_TX_SETUP_TX_DELETE() runs on MTC {
+testcase tc_can_bcm_TX_SETUP_TX_DELETE_can_frame() runs on MTC {
   // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving 
   // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66). 
 
@@ -37,6 +37,7 @@
   connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
 
   var CAN_frame  v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
+  var CANFD_frame  v_canfd_frame1
 
   var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame   
 
@@ -47,16 +48,16 @@
   v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O}; 
 
   template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
-        {can_frame := v_can_frame1},
-        {can_frame := v_can_frame2},
-        {can_frame := v_can_frame3},
-        {can_frame := v_can_frame4},
-        {can_frame := v_can_frame5},
-        {can_frame := v_can_frame1}, 
-        {can_frame := v_can_frame2},
-        {can_frame := v_can_frame3},
-        {can_frame := v_can_frame4},
-        {can_frame := v_can_frame5}
+    {can_frame := v_can_frame1},
+    {can_frame := v_can_frame2},
+    {can_frame := v_can_frame3},
+    {can_frame := v_can_frame4},
+    {can_frame := v_can_frame5},
+    {can_frame := v_can_frame1}, 
+    {can_frame := v_can_frame2},
+    {can_frame := v_can_frame3},
+    {can_frame := v_can_frame4},
+    {can_frame := v_can_frame5}
   }
 
   v_bcm_activation_frame := {
@@ -121,8 +122,7 @@
   all component.kill;     
 }
 
-
-testcase tc_can_bcm_TX_SETUP_TX_DELETE_TX_READ__broken() runs on MTC {
+testcase tc_can_bcm_TX_SETUP_TX_DELETE_canfd_frame() runs on MTC {
   // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), but after receiving 
   // a sequnce of 10 frames the cyclic sending of the frames is stopped with TX_DELETE (can id = 66). 
 
@@ -137,88 +137,95 @@
   connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
   connect(mtc:pt_sync, v_ptc_rawFrameReceiver2:pt_sync)
 
-  var CAN_frame  v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
+  var CANFD_frame  v_canfd_frame1, v_canfd_frame2, v_canfd_frame3, v_canfd_frame4, v_canfd_frame5
 
-  var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame, v_bcm_read_status_frame
+  var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame   
+  
+  v_canfd_frame1 := 
+  {can_id := '00000011'O, 
+    can_flags := '10101010'B,
+    can_pdu := '1111111111111111'O
+  };
+  
+  v_canfd_frame2 := 
+  {can_id := '00000012'O, 
+    can_flags := '10101010'B,
+    can_pdu := '22222222222222222222222222222222'O
+  };
+  
+  v_canfd_frame3 := 
+  {can_id := '00000013'O, 
+    can_flags := '10101010'B,
+    can_pdu := '4444444444444444444444444444444444444444444444444444444444444444'O
+  };
+  
+  v_canfd_frame4 := 
+  {can_id := '00000014'O, 
+    can_flags := '10101010'B,
+    can_pdu := '55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555'O
+  };
 
-  v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O}; 
-  v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};  
-  v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O}; 
-  v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O}; 
-  v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O}; 
-
+  v_canfd_frame5 := 
+  {can_id := '00000015'O, 
+    can_flags := '01010101'B,
+    can_pdu := '0123'O      
+  };
+  
   template SocketCAN_CAN_or_CAN_FD_frames a_expected_can_frames := {
-        {can_frame := v_can_frame1},
-        {can_frame := v_can_frame2},
-        {can_frame := v_can_frame3},
-        {can_frame := v_can_frame4},
-        {can_frame := v_can_frame5},
-        {can_frame := v_can_frame1}, 
-        {can_frame := v_can_frame2},
-        {can_frame := v_can_frame3},
-        {can_frame := v_can_frame4},
-        {can_frame := v_can_frame5}
+    {canfd_frame := v_canfd_frame1},
+    {canfd_frame := v_canfd_frame2},
+    {canfd_frame := v_canfd_frame3},
+    {canfd_frame := v_canfd_frame4},
+    {canfd_frame := v_canfd_frame5}
   }
 
-v_bcm_activation_frame := {
+  v_bcm_activation_frame := {
     opcode := '00000001'O, // TX_SETUP
-    flags  := '00000000000000000000000000000011'B,  // refers to SETTIMER | STARTTIMER
+    flags  := '00000000000000000000000000000011'B,  // refers to SETTIMER | STARTTIMER 
+                                                    // CAN_FD_FRAME flag is automatically set the
+                                                    // test port for CANFD frames
     count  := 0,
     ival1  := {0, 0},
     ival2  := {0, 100000},
     can_id := '00000042'O, // should become octetstring in the future
-    frames := {can_frame := {
-        v_can_frame1, 
-        v_can_frame2,
-        v_can_frame3,
-        v_can_frame4,
-        v_can_frame5}}
+    frames := {canfd_frame := {
+        v_canfd_frame1,
+        v_canfd_frame2,
+        v_canfd_frame3,
+        v_canfd_frame4, 
+        v_canfd_frame5}}
   }
 
   v_bcm_deactivation_frame := {
     opcode := '00000002'O, // TX_DELETE
-    flags  := '00000000000000000000000000000000'B,
+    flags  := '00001000000000000000000000000000'B,
+                                                    // CAN_FD_FRAME flag is automatically set the
+                                                    // test port for CANFD frames
     count  := 0,
     ival1  := {0, 0},
     ival2  := {0, 0},
     can_id := '00000042'O,
-    frames := {can_frame := {}}
+    frames := {canfd_frame := {}} // needs to be canfd-frame here, to stop canfd frames
   }
 
-  v_bcm_read_status_frame := {
-    opcode := '00000003'O, // TX_READ
-    flags  := 
-    // workaround for titan constants instead of enums: 
-    ('00000000000000000000000000000001'B << 0) or4b // enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) instead of 0
-    ('00000000000000000000000000000001'B << 1) or4b // enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) instead of 1
-    ('00000000000000000000000000000001'B << 4),     // enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX) instead of 4
-    count  := 0,
-    ival1  := {0, 0},
-    ival2  := {0, 0},
-    can_id := '00000042'O,
-    frames := {can_frame := {}}
-  }
-  
-  
   var BCM_cmds v_cmds := 
   {
-    //{phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
-    {phase := e_testbody3, bcm_frame := v_bcm_read_status_frame},
-    {phase := e_testbody4, bcm_frame := v_bcm_deactivation_frame},
-    {phase := e_testbody6, bcm_frame := v_bcm_read_status_frame}
+    {phase := e_testbody2, bcm_frame := v_bcm_activation_frame},
+    {phase := e_testbody5, bcm_frame := v_bcm_deactivation_frame}
   }
 
-  v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendReceiveInitiator(v_cmds))
+  v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendInitiator(v_cmds))
 
-  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1, v_frame_to_receive5
-  v_frame_to_receive1 := {can_frame := v_can_frame1}
-  v_frame_to_receive5 := {can_frame := v_can_frame5}
+  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1
+  
+  v_frame_to_receive1 := {canfd_frame := v_canfd_frame1}
+
 
   // stop when receiving v_frame_to_receive
   v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody3, v_frame_to_receive1))
 
   // stop when receiving v_frame_to_receive
-  v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody5, a_expected_can_frames, e_testbody6, 2.0))
+  v_ptc_rawFrameReceiver2.start(f_ptc_RawFrameSequenceReceiver(e_testbody4, a_expected_can_frames, e_testbody5, 2.0))
 
   var e_Phase v_phase
 
@@ -239,4 +246,90 @@
   all component.kill;     
 }
 
+
+testcase tc_can_bcm_TX_SETUP_TX_READ() runs on MTC {
+  // here are 5 CAN frames cyclicly started with TX_SETUP (can_id = 66), then with TX_READ the status is read
+
+  var PTC v_ptc_bcmConfigurator := PTC.create("PTC1_ptc_bcmConfigurator") alive
+  var PTC v_ptc_rawFrameReceiver1 := PTC.create("PTC2_ptc_rawFrameReceiver1") alive
+
+  f_addSyncSlaveSet(v_ptc_bcmConfigurator, v_PTCSet)
+  f_addSyncSlaveSet(v_ptc_rawFrameReceiver1, v_PTCSet)
+
+  connect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+  connect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+
+
+  var CAN_frame  v_can_frame1, v_can_frame2, v_can_frame3, v_can_frame4, v_can_frame5;
+  var CANFD_frame v_canfd_frame1
+  var SocketCAN_bcm_frame v_bcm_activation_frame, v_bcm_deactivation_frame, v_bcm_read_status_frame
+
+  v_can_frame1 := {can_id := '00000001'O, can_pdu := '1111111111111111'O}; 
+  v_can_frame2 := {can_id := '00000002'O, can_pdu := '2222222222222222'O};  
+  v_can_frame3 := {can_id := '00000003'O, can_pdu := '3333333333333333'O}; 
+  v_can_frame4 := {can_id := '00000004'O, can_pdu := '4444444444444444'O}; 
+  v_can_frame5 := {can_id := '00000005'O, can_pdu := '5555555555555555'O}; 
+
+  v_bcm_activation_frame := {
+    opcode := '00000001'O, // TX_SETUP
+    flags  := '00000000000000000000000000000011'B,  // refers to SETTIMER | STARTTIMER
+    count  := 0,
+    ival1  := {0, 0},
+    ival2  := {0, 100000},
+    can_id := '00000042'O, // should become octetstring in the future
+    frames := {can_frame := {
+        v_can_frame1, 
+        v_can_frame2,
+        v_can_frame3,
+        v_can_frame4,
+        v_can_frame5}}
+  }
+
+  v_bcm_read_status_frame := {
+    opcode := '00000003'O, // TX_READ
+    flags  := 
+    // workaround for titan constants instead of enums: 
+    ('00000000000000000000000000000001'B << 0) or4b // enum2int(e_CAN_BCM_SETTIMER_BITINDEX)) instead of 0
+    ('00000000000000000000000000000001'B << 1) or4b // enum2int(e_CAN_BCM_TX_COUNTEVT_BITINDEX)) instead of 1
+    ('00000000000000000000000000000001'B << 4),     // enum2int(e_CAN_BCM_TX_CP_CAN_ID_BITINDEX) instead of 4
+    count  := 0,
+    ival1  := {0, 0},
+    ival2  := {0, 0},
+    can_id := '00000042'O,
+    frames := {can_frame := {}}
+  }
+
+
+  var BCM_cmds v_cmds := 
+  {
+    {phase := e_testbody1, bcm_frame := v_bcm_activation_frame},
+    {phase := e_testbody3, bcm_frame := v_bcm_read_status_frame}
+  }
+
+  v_ptc_bcmConfigurator.start(f_ptc_bcmComandSendReceiveInitiator(v_cmds))
+
+  var SocketCAN_CAN_or_CAN_FD_frame v_frame_to_receive1
+  v_frame_to_receive1 := {can_frame := v_can_frame1}
+
+  // stop when receiving v_frame_to_receive
+  v_ptc_rawFrameReceiver1.start(f_ptc_RawFrameReceiver(e_testbody1, v_frame_to_receive1))
+
+  var e_Phase v_phase
+
+  for(v_phase := c_firstPhase; v_phase < e_testcase_complete; v_phase := f_incMTCPhase(v_phase)) {
+    f_startPhase(v_phase)
+    log("MTC: ", v_phase)
+    f_awaitEndPhase(v_phase)
+  }
+
+
+  all component.done;
+  log("MTC done")
+
+  disconnect(mtc:pt_sync, v_ptc_bcmConfigurator:pt_sync)
+  disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver1:pt_sync)
+
+  all component.kill;     
+}
+
 }
diff --git a/demo/SocketCAN_RAW_test.ttcn b/demo/SocketCAN_RAW_test.ttcn
index 4745b4c..01e1349 100644
--- a/demo/SocketCAN_RAW_test.ttcn
+++ b/demo/SocketCAN_RAW_test.ttcn
@@ -22,7 +22,7 @@
 import from Raw all
 import from CanError all
 
-testcase tc_can_raw_send_and_receive_frame() runs on MTC {
+testcase tc_can_raw_send_and_receive_can_frame() runs on MTC {
   var PTC v_ptc_rawSendInitiator := PTC.create("PTC1_ptc_rawSendInitiator") alive
   var PTC v_ptc_rawFrameReceiver := PTC.create("PTC2_ptc_rawFrameReceiver") alive
 
@@ -57,6 +57,45 @@
   all component.kill;      
 }
 
+testcase tc_can_raw_send_and_receive_canfd_frame() runs on MTC {
+  var PTC v_ptc_rawSendInitiator := PTC.create("PTC1_ptc_rawSendInitiator") alive
+  var PTC v_ptc_rawFrameReceiver := PTC.create("PTC2_ptc_rawFrameReceiver") alive
+
+
+  f_addSyncSlaveSet(v_ptc_rawSendInitiator, v_PTCSet)
+  f_addSyncSlaveSet(v_ptc_rawFrameReceiver, v_PTCSet)
+  
+  connect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
+  connect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
+
+  var SocketCAN_CAN_or_CAN_FD_frame v_canfd_frame_to_send
+  v_canfd_frame_to_send := {canfd_frame := 
+    {can_id := '00000015'O, 
+      can_flags := '10101010'B,
+      can_pdu := '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'O}
+  }
+
+  v_ptc_rawSendInitiator.start(f_ptc_RawSendInitiator(e_testbody2, v_canfd_frame_to_send))
+  v_ptc_rawFrameReceiver.start(f_ptc_RawFrameReceiver(e_testbody3, v_canfd_frame_to_send))
+
+  var e_Phase v_phase
+
+  for(v_phase := c_firstPhase; v_phase < e_testcase_complete;v_phase := f_incMTCPhase(v_phase)) {
+    f_startPhase(v_phase)
+    log("MTC: ", v_phase)
+    f_awaitEndPhase(v_phase)
+  }
+
+  all component.done;
+  log("MTC done")
+
+
+  disconnect(mtc:pt_sync, v_ptc_rawSendInitiator:pt_sync)
+  disconnect(mtc:pt_sync, v_ptc_rawFrameReceiver:pt_sync)
+
+  all component.kill;      
+}
+
 testcase tc_can_raw_setsockopt_CAN_RAW_FILTER() runs on MTC {
 
   var PTC v_ptc_rawSetFilters := PTC.create("PTC1_ptc_rawSetFilters") alive
diff --git a/demo/SocketCAN_Templates.ttcn b/demo/SocketCAN_Templates.ttcn
index 43cff60..6c25425 100644
--- a/demo/SocketCAN_Templates.ttcn
+++ b/demo/SocketCAN_Templates.ttcn
@@ -1,107 +1,107 @@
-/* Copyright (c) 2010, 2016  Ericsson AB

-* All rights reserved. This program and the accompanying materials

-* are made available under the terms of the Eclipse Public License v1.0

-* which accompanies this distribution, and is available at

-* http://www.eclipse.org/legal/epl-v10.html

-*

-* Contributors:

-* Michael Josenhans

-******************************************************************************/

-//

-//  File:               SocketCANtest.ttcn

-//  Description:        SocketCAN port type test

-//

+/* Copyright (c) 2010, 2016  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Michael Josenhans
+******************************************************************************/
+//
+//  File:               SocketCANtest.ttcn
+//  Description:        SocketCAN port type test
+//
 
 
-module SocketCAN_Templates {

-

-import from SocketCAN_Types all;

-import from Bcm all

-import from Can all

-

-template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {          

-  result_code   := v_result_code,

-  err           := *,

-  err_text      := *

-}

-

-template SocketCAN_socket_result 

-a_SocketCAN_socket_result(template SocketCAN_Result p_result) := {

-  id := ?, 

-  result := p_result

-}

-

-template SocketCAN_ioctl_result 

-a_SocketCAN_ioctl_result(template SocketCAN_Result p_result) := {

-  ifr := ?,

-  result := p_result

-}

-

-template SocketCAN_connect_result

-a_SocketCAN_connect_result(template SocketCAN_Result p_result) := {

-  result := p_result

-}

-

-template SocketCAN_bind_result

-a_SocketCAN_bind_result(template SocketCAN_Result p_result) := {

-  result := p_result

-}

-

-template SocketCAN_send_data_result

-a_SocketCAN_send_data_result(template SocketCAN_Result p_result) := {

-  result := p_result

-}

-

-template SocketCAN_write_data_result

-a_SocketCAN_write_data_result(template SocketCAN_Result p_result) := {

-  result := p_result

-}

-

-template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_frame(

-  template SocketCAN_socketid p_id, 

-  template CAN_id p_can_id,

-  template CAN_PDU p_can_pdu) := { 

-  // recieved CAN frame

-  id        := p_id,

-  ifr       := ?,

-  frame     := {can_frame := {can_id := p_can_id, can_pdu := p_can_pdu}}, 

-  timestamp := ?

-}

-

-

-template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_FD_frame(

-  template SocketCAN_socketid p_id, 

-  template CAN_id p_can_id,

-  template CAN_PDU p_can_pdu) := { 

-  // recieved CAN or CAN FD frame

-  id        := p_id,

-  ifr       := ?,

-  frame     := {canfd_frame := {can_id := p_can_id, can_pdu := p_can_pdu}}, 

-  timestamp := ?

-}

-

-template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_or_CAN_FD_frame(

-  template SocketCAN_socketid p_id, 

-  template SocketCAN_CAN_or_CAN_FD_frame p_frame) := { 

-  // recieved CAN or CAN FD frame

-  id        := p_id,

-  ifr       := ?,

-  frame     := p_frame, 

-  timestamp := ?

-}

-

-template SocketCAN_receive_BCM_message a_SocketCAN_receive_BCM_message(

-  template SocketCAN_socketid p_id, 

-  template SocketCAN_bcm_frame p_frame) := { 

-  // recieved CAN or CAN FD frame

-  id        := p_id,

-  ifr       := ?,

-  frame     := p_frame

-}

-

-template SocketCAN_setsockopt_result

-a_SocketCAN_setsockopt_result(template SocketCAN_Result p_result) := {

-  result := p_result

-}

-

-}

+module SocketCAN_Templates {
+
+import from SocketCAN_Types all;
+import from Bcm all
+import from Can all
+
+template SocketCAN_Result a_result(in SocketCAN_Result_code v_result_code) := {          
+  result_code   := v_result_code,
+  err           := *,
+  err_text      := *
+}
+
+template SocketCAN_socket_result 
+a_SocketCAN_socket_result(template SocketCAN_Result p_result) := {
+  id := ?, 
+  result := p_result
+}
+
+template SocketCAN_ioctl_result 
+a_SocketCAN_ioctl_result(template SocketCAN_Result p_result) := {
+  ifr := ?,
+  result := p_result
+}
+
+template SocketCAN_connect_result
+a_SocketCAN_connect_result(template SocketCAN_Result p_result) := {
+  result := p_result
+}
+
+template SocketCAN_bind_result
+a_SocketCAN_bind_result(template SocketCAN_Result p_result) := {
+  result := p_result
+}
+
+template SocketCAN_send_data_result
+a_SocketCAN_send_data_result(template SocketCAN_Result p_result) := {
+  result := p_result
+}
+
+template SocketCAN_write_data_result
+a_SocketCAN_write_data_result(template SocketCAN_Result p_result) := {
+  result := p_result
+}
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_frame(
+  template SocketCAN_socketid p_id, 
+  template CAN_id p_can_id,
+  template CAN_PDU p_can_pdu) := { 
+  // recieved CAN frame
+  id        := p_id,
+  ifr       := ?,
+  frame     := {can_frame := {can_id := p_can_id, can_pdu := p_can_pdu}}, 
+  timestamp := ?
+}
+
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_FD_frame(
+  template SocketCAN_socketid p_id, 
+  template CAN_id p_can_id,
+  template CAN_PDU p_can_pdu) := { 
+  // recieved CAN or CAN FD frame
+  id        := p_id,
+  ifr       := ?,
+  frame     := {canfd_frame := {can_id := p_can_id, can_pdu := p_can_pdu}}, 
+  timestamp := ?
+}
+
+template SocketCAN_receive_CAN_or_CAN_FD_frame a_SocketCAN_receive_CAN_or_CAN_FD_frame(
+  template SocketCAN_socketid p_id, 
+  template SocketCAN_CAN_or_CAN_FD_frame p_frame) := { 
+  // recieved CAN or CAN FD frame
+  id        := p_id,
+  ifr       := ?,
+  frame     := p_frame, 
+  timestamp := ?
+}
+
+template SocketCAN_receive_BCM_message a_SocketCAN_receive_BCM_message(
+  template SocketCAN_socketid p_id, 
+  template SocketCAN_bcm_frame p_frame) := { 
+  // recieved CAN or CAN FD frame
+  id        := p_id,
+  ifr       := ?,
+  frame     := p_frame
+}
+
+template SocketCAN_setsockopt_result
+a_SocketCAN_setsockopt_result(template SocketCAN_Result p_result) := {
+  result := p_result
+}
+
+}
\ No newline at end of file
diff --git a/src/SocketCAN_PT.cc b/src/SocketCAN_PT.cc
index 1a5d68b..752db17 100644
--- a/src/SocketCAN_PT.cc
+++ b/src/SocketCAN_PT.cc
@@ -1,1727 +1,1753 @@
-/******************************************************************************
- * Copyright (c) 2010, 2016  Ericsson AB
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Michael Josenhans
- ******************************************************************************/
-//
-//  File:               SocketCAN_PT.cc
-//  Description:        SocketCAN_PT test port source
-//
-// Revision R1A
-#include "SocketCAN_PT.hh"
-#include "SocketCAN_PortType.hh"
-
-#include <Addfunc.hh>
-#include <Bitstring.hh>
-#include <Charstring.hh>
-#include <errno.h>
-#include <Error.hh>
-#include <Hexstring.hh>
-#include <Integer.hh>
-#include <linux/can/bcm.h>
-#include <linux/can/raw.h>
-#include <linux/if.h>
-#include <Logger.hh>
-#include <memory.h>
-#include <Octetstring.hh>
-#include <Optional.hh>
-#include <Port.hh>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <Template.hh>
-#include <unistd.h>
-#include <algorithm>
-#include <cerrno>
-#include <cstdarg>
-#include <cstddef>
-#include <cstring>
-#include <iostream>
-
-struct bcm_msg_head;
-struct can_frame;
-struct canfd_frame;
-
-
-#define DEFAULT_NUM_SOCK          10
-#define BCM_FRAME_BUFFER_SIZE    256
-#define BCM_FRAME_FLAGS_SIZE      32 // size of SocketCAN_bcm_frame in Bit
-#define ISOTP_RECIEVE_BUFSIZE   5000
-
-
-// workaround, as some of those below may not yet be defined in "linux/can/raw.h":
-#define CAN_RAW_FILTER            1 /* set 0 .. n can_filter(s)          */
-#define CAN_RAW_ERR_FILTER        2 /* set filter for error frames       */
-#define CAN_RAW_LOOPBACK          3 /* local loopback (default:on)       */
-#define CAN_RAW_RECV_OWN_MSGS     4 /* receive my own msgs (default:off) */
-#define CAN_RAW_FD_FRAMES         5 /* allow CAN FD frames (default:off) */
-#define CAN_RAW_JOIN_FILTERS      6 /* all filters must match to trigger */
-
-// workaround, as not yet defined in all versions of "linux/Can.h":
-#ifndef CAN_MAX_DLEN
-#define CAN_MAX_DLEN 8
-#endif
-
-// workaround, as not defined in some older kernel versions
-#ifndef	CAN_MTU
-#define CAN_MTU		(sizeof(struct can_frame))
-#endif  //CANFD_MTU
-
-// workaround, as canfd not defined in some older kernel versions
-// and thus canfd frames can not be used for data transfer between 
-// kernel module and userspace.
-#ifdef	CANFD_MTU
-#define CANFD_FRAME_STRUCT_DEFINED             true
-#define RAW_CANFD_SUPPORT                      true
-#endif  //CANFD_MTU
-
-// has to be defined in later kernel versions in bcm.h as #define CAN_FD_FRAME   0x0800
-#ifdef  CAN_FD_FRAME
-#define BCM_CANFD_SUPPORT                      true
-#endif
-
-namespace SocketCAN__PortType {
-
-SocketCAN__PT_PROVIDER::SocketCAN__PT_PROVIDER(const char *par_port_name) :
-		PORT(par_port_name), num_of_sock(0), sock_list_length(0), target_fd(-1), can_interface_name(
-		NULL), debugging(false), debugging_configured(false), config_finished(
-				false) {
-	sock_list = NULL;
-	//&num_of_sock = 0;
-	//sock_list_length = 0;
-}
-
-SocketCAN__PT_PROVIDER::~SocketCAN__PT_PROVIDER() {
-	Free(sock_list);
-	reset_configuration();
-}
-
-void SocketCAN__PT_PROVIDER::set_parameter(const char * parameter_name,
-		const char * parameter_value) {
-	log("entering SocketCAN__PT_PROVIDER::set_parameter(%s, %s)",
-			parameter_name, parameter_value);
-
-	if (config_finished) {
-		reset_configuration();
-		config_finished = false;
-	}
-
-	if (strcmp(parameter_name, "SocketCAN_can_interface_name") == 0) {
-		InitStrPar(can_interface_name, parameter_name, parameter_value);
-	} else if (strcmp(parameter_name, "SocketCAN_debugging") == 0) {
-		if (strcmp(parameter_value, "YES") == 0) {
-			debugging = true;
-			debugging_configured = true;
-			log("Reading testport parameter debugging: ", debugging);
-		} else if (strcmp(parameter_value, "NO") == 0) {
-			debugging = false;
-			debugging_configured = true;
-			log("Reading testport parameter debugging: ", debugging);
-		}
-	} else {
-		TTCN_error(
-				"SocketCAN parameter configuration error: Configuration file does not correctly configure parameter 'SocketCAN_debugging' however parameter name '%s' as parameter value: '%s'!!\nExpecting: \n*.*.SocketCAN_debugging := \"YES\"\n or \n*.*.SocketCAN_debugging := \"NO\"",
-				parameter_name, parameter_value);
-	}
-
-	log("leaving SocketCAN__PT_PROVIDER::set_parameter(%s, %s)", parameter_name,
-			parameter_value);
-}
-
-/*void SocketCAN__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
- boolean is_writable, boolean is_error) {}*/
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Error(int /*fd*/) {
-
-}
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/) {
-
-}
-
-void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int sock) {
-	log("entering SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
-	int res;
-
-	for (int a = 0; a < sock_list_length; a++) {
-		if ((sock == sock_list[a].fd)
-				and (sock_list[a].status != SOCKET_NOT_ALLOCATED)) {
-			switch (sock_list[a].protocol_family) {
-			case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP: {
-				SocketCAN__Types::SocketCAN__receive__isotp__pdu parameters;
-
-				unsigned char msg[ISOTP_RECIEVE_BUFSIZE];
-
-				int nbytes = 0;
-				struct sockaddr_can addr;
-				socklen_t addr_len = sizeof(addr);
-				//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
-				// struct sockaddr *src_addr, socklen_t *addrlen);
-				nbytes = recvfrom(sock, msg, ISOTP_RECIEVE_BUFSIZE, 0,
-						(struct sockaddr*) &addr, &addr_len);
-
-				//nbytes = read(sock, msg, ISOTP_RECIEVE_BUFSIZE);
-				if(nbytes > 0 && nbytes < ISOTP_RECIEVE_BUFSIZE) {
-					struct ifreq ifr;
-					ifr.ifr_ifindex = addr.can_ifindex;
-					parameters.ifr().if__index() = ifr.ifr_ifindex;
-					parameters.ifr().if__name() = ifr.ifr_name;
-					parameters.id() = a;
-					parameters.pdu() = OCTETSTRING(nbytes, msg);
-					incoming_message(parameters);
-				}
-			}
-			break;
-			case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW: {
-				SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame parameters;
-
-				struct sockaddr_can addr;
-				socklen_t addr_len = sizeof(addr);
-				//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
-				// struct sockaddr *src_addr, socklen_t *addrlen);
-#ifdef	CANFD_FRAME_STRUCT_DEFINED   // struct canfd_frame is supported
-				struct canfd_frame frame; // always asume a CANFD_Frame shall be received
-				ssize_t nbytes = recvfrom(sock, &frame, CANFD_MTU, 0,
-						(struct sockaddr*) &addr, &addr_len);
-#else   //CANFD_FRAME_STRUCT_DEFINED
-				struct can_frame frame; // CANFD_Frame is not supported by this kernel version
-				ssize_t nbytes = recvfrom(sock, &frame, CAN_MTU, 0,
-						(struct sockaddr*) &addr, &addr_len);
-#endif  //CANFD_FRAME_STRUCT_DEFINED
-
-				if (nbytes <= 0) {
-					//there is an empty message, or error in receive
-					//remove the socket
-					TTCN_error(
-							"Closing socket %d with interface index %d due to an empty message or error in reception\n",
-							sock, addr.can_ifindex);
-					std::cout << "close_fd" << sock << std::endl;
-					sock_list[a].status = SOCKET_NOT_ALLOCATED;
-					sock_list[a].protocol_family =
-							SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
-					num_of_sock--;
-					Handler_Remove_Fd_Read(sock);
-					close(sock);
-				} else
-
-				if ((nbytes == CAN_MTU)
-#ifdef	CANFD_FRAME_STRUCT_DEFINED
-						or (nbytes == CANFD_MTU)
-#endif  //CANFD_FRAME_STRUCT_DEFINED
-						) {
-					// A CAN Frame has been received. However use the struct canfd_frame to access it.
-					// As it is a CAN frame, the flags field contains invalid data and the can_dlc field
-					// is here called len as in CAN FD.
-					struct ifreq ifr;
-					ifr.ifr_ifindex = addr.can_ifindex;
-					/* get interface name of the received CAN frame */
-					res = ioctl(sock, SIOCGIFNAME, &ifr);
-					if (res != 0) {
-						TTCN_error(
-								"SocketCAN frame reception: Ioctl failed while retrieving the interface name from the socket: %d with interface index %d\n",
-								sock, ifr.ifr_ifindex);
-#ifdef	CANFD_FRAME_STRUCT_DEFINED
-						log("SocketCAN: Received a CAN frame from interface %s",
-								ifr.ifr_name, nbytes, frame.len);
-#else   //CANFD_FRAME_STRUCT_DEFINED
-						log("SocketCAN: Received a CAN frame from interface %s",
-								ifr.ifr_name, nbytes, frame.can_dlc);
-#endif  //CANFD_FRAME_STRUCT_DEFINED
-						parameters.ifr().if__index() = ifr.ifr_ifindex;
-						parameters.ifr().if__name() =
-								"SocketCAN : device name unknown, ioctl failed";
-					} else {
-						parameters.ifr().if__index() = ifr.ifr_ifindex;
-						parameters.ifr().if__name() =
-								"SocketCAN : device name unknown, ioctl failed";
-						parameters.ifr().if__name() = ifr.ifr_name;
-					}
-
-					struct timeval tv;
-					res = ioctl(sock, SIOCGSTAMP, &tv);
-					if (res != 0) {
-						TTCN_error(
-								"SocketCAN frame reception: Ioctl failed while retrieving the timestamp from the socket: %d with interface name %s\n",
-								sock, ifr.ifr_name);
-
-					} else {
-						parameters.timestamp().tv__sec() = tv.tv_sec;
-						parameters.timestamp().tv__usec() = tv.tv_usec;
-					}
-					parameters.ifr().if__index() = ifr.ifr_ifindex;
-					parameters.ifr().if__name() = ifr.ifr_name;
-					parameters.id() = a;
-
-					INTEGER can_id;
-					can_id.set_long_long_val(frame.can_id);
-#ifdef CANFD_FRAME_STRUCT_DEFINED
-					const INTEGER len = frame.len;
-#else  //CANFD_FRAME_STRUCT_DEFINED
-					const INTEGER len = frame.can_dlc;
-#endif //CANFD_FRAME_STRUCT_DEFINED
-					// frame type specific part:
-					if (nbytes == CAN_MTU) {
-						// CAN frame received:
-						Can::CAN__frame& frameref =
-								parameters.frame().can__frame();
-						log(
-								"Received a CAN frame from interface %s of %d bytes and with payload length %d",
-								ifr.ifr_name, nbytes, (int) len);
-						parameters.ifr().if__index() = ifr.ifr_ifindex;
-						parameters.ifr().if__name() = ifr.ifr_name;
-						parameters.id() = a;
-						frameref.can__id() = int2oct(can_id, 4);
-						frameref.can__pdu() = OCTETSTRING(len, frame.data);
-					} else {
-						// CAN FD frame received:
-						Can::CANFD__frame& frameref =
-								parameters.frame().canfd__frame();
-						log(
-								"Received a CAN FD frame from interface %s of %d bytes and with payload length %d",
-								ifr.ifr_name, nbytes, (int) len);
-						frameref.can__id() = int2oct(can_id, 4);
-#ifdef CANFD_FRAME_STRUCT_DEFINED
-						frameref.can__flags() = BITSTRING(
-								int2bit(frame.flags,
-										frameref.can__flags().lengthof()));
-#endif //CANFD_FRAME_STRUCT_DEFINED
-						frameref.can__pdu() = OCTETSTRING(len, frame.data);
-					}
-					incoming_message(parameters);
-				}
-			}
-				break;
-			case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM: {
-				SocketCAN__Types::SocketCAN__receive__BCM__message parameters;
-				struct sockaddr_can addr;
-				struct {
-					struct bcm_msg_head msg_head;
-#ifdef CANFD_FRAME_STRUCT_DEFINED
-					struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
-#else  //CANFD_FRAME_STRUCT_DEFINED
-					struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
-#endif //CANFD_FRAME_STRUCT_DEFINED
-				} bcm_msg;
-				struct ifreq ifr;
-
-				socklen_t addr_len = sizeof(addr);
-				ssize_t nbytes = recvfrom(sock, &bcm_msg,
-						sizeof(struct can_frame), 0, (struct sockaddr*) &addr,
-						&addr_len);
-				if (nbytes < 0) {
-					//there is an empty message, or error in receive
-					//remove the socket
-					TTCN_error(
-							"Closing socket %d with interface index %d due to an empty BCM message or error in reception\n",
-							sock, addr.can_ifindex);
-					std::cout << "close_fd" << sock << std::endl;
-					sock_list[a].status = SOCKET_NOT_ALLOCATED;
-					sock_list[a].protocol_family =
-							SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
-					num_of_sock--;
-					Handler_Remove_Fd_Read(sock);
-					close(sock);
-				} else {
-					ifr.ifr_ifindex = addr.can_ifindex;
-					// get interface name of the received CAN frame
-
-					// currently handling of can_ifindex == 0 (= any interface) is unclear.
-//					res = ioctl(sock, SIOCGIFNAME, &ifr);
-//					if (res == -1) {
-//						TTCN_error(
-//								"Ioctl failed while receiving a BCM message frame on socket: %d with interface index %d with errno: %d\n",
-//								sock, ifr.ifr_ifindex, errno);
-//					}
-					const INTEGER msg_head_flags = bcm_msg.msg_head.flags;
-					log(
-							"Received a BCM message from interface index %d of bytes %d",
-							ifr.ifr_ifindex, nbytes);
-					parameters.id() = bcm_msg.msg_head.can_id;
-					parameters.ifr().if__index() = ifr.ifr_ifindex;
-					parameters.ifr().if__name() = ifr.ifr_name;
-
-					uint32_t nframes = bcm_msg.msg_head.nframes;
-					INTEGER opcode;
-					opcode.set_long_long_val(bcm_msg.msg_head.opcode);
-					parameters.frame().opcode() = int2oct(opcode, 4);
-					parameters.frame().flags() = BITSTRING(
-							int2bit(INTEGER(msg_head_flags),
-							BCM_FRAME_FLAGS_SIZE));
-					parameters.frame().count() = bcm_msg.msg_head.count;
-					parameters.frame().ival1().tv__sec() =
-							bcm_msg.msg_head.ival1.tv_sec;
-					parameters.frame().ival1().tv__usec() =
-							bcm_msg.msg_head.ival1.tv_usec;
-					parameters.frame().ival2().tv__sec() =
-							bcm_msg.msg_head.ival2.tv_sec;
-					parameters.frame().ival2().tv__usec() =
-							bcm_msg.msg_head.ival2.tv_usec;
-					INTEGER bcm_head_can_id;
-					bcm_head_can_id.set_long_long_val(bcm_msg.msg_head.can_id);
-					parameters.frame().can__id() = int2oct(bcm_head_can_id, 4);
-#ifdef BCM_CANFD_SUPPORT
-					long flags = bcm_msg.msg_head.flags;
-					if ((flags & CAN_FD_FRAME ) == CAN_FD_FRAME ) {
-						// Handle CAN FD frames
-
-						parameters.frame().frames().can__frame().set_size(nframes);
-						for (uint32_t i = 0; i < nframes; i++) {
-							INTEGER len;
-							len = bcm_msg.frame[i].len;
-							if (len > CANFD_MAX_DLEN) {
-								TTCN_error("Writing data: CAN FD pdu size too large\n");
-							};
-							INTEGER can_id;
-							can_id.set_long_long_val(bcm_msg.frame[i].can_id);
-							parameters.frame().frames().canfd__frame()[i].can__id() = int2oct(can_id, 4);
-							//Here the bitstring shall be stored into a
-							parameters.frame().frames().canfd__frame()[i].can__flags() =
-							BITSTRING(32,
-									(const unsigned char*) &(bcm_msg.frame[i].flags));
-							parameters.frame().frames().canfd__frame()[i].can__pdu() =
-							OCTETSTRING(len,
-									(const unsigned char*) &(bcm_msg.frame[i].data));
-						}
-						incoming_message(parameters);
-					}
-					else
-#endif //BCM_CANFD_SUPPORT
-					{
-						parameters.frame().frames().can__frame().set_size(
-								nframes);
-						for (uint32_t i = 0; i < nframes; i++) {
-							INTEGER len;
-#ifdef	CANFD_FRAME_STRUCT_DEFINED   // struct canfd_frame is supported
-							len = bcm_msg.frame[i].len;
-#else   //CANFD_FRAME_STRUCT_DEFINED   // struct canfd_frame is supported
-							len = bcm_msg.frame[i].can_dlc;
-#endif	//CANFD_FRAME_STRUCT_DEFINED   // struct canfd_frame is supported
-							// Handle legacy CAN frames
-							if (len > CAN_MAX_DLEN) {
-								TTCN_error(
-										"Writing data: CAN pdu size too large\n");
-								len = CAN_MAX_DLEN;
-							};
-							INTEGER can_id;
-							can_id.set_long_long_val(bcm_msg.frame[i].can_id);
-							parameters.frame().frames().can__frame()[i].can__id() =
-									int2oct(can_id, 4);
-							parameters.frame().frames().can__frame()[i].can__pdu() =
-									OCTETSTRING(len,
-											(const unsigned char*) &(bcm_msg.frame[i].data));
-
-						}
-						incoming_message(parameters);
-					}
-				}
-			}
-				break;
-			default: {
-				TTCN_error(
-						"SocketCAN Handle_Fd_Event_Readable (%d): unhandled protocol configured",
-						sock);
-			}
-				break;
-			}
-		}
-	}
-	log("leaving SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");
-}
-
-void SocketCAN__PT_PROVIDER::user_map(const char */*system_port */) {
-	log("entering SocketCAN__PT_PROVIDER::user_map()");
-
-	config_finished = true;
-
-	if (debugging_configured == false) {
-		// The debugging mode has not been defined in TTCN configuration file.
-		TTCN_error(
-				"Missing mandatory parameter: SocketCAN_debuhhing for can_interface_name %s \n",
-				can_interface_name);
-	}
-
-	if (sock_list != NULL)
-		TTCN_error("SocketCAN Test Port (%s): Internal error: "
-				"sock_list is not NULL when mapping.", port_name);
-	sock_list = (sock_data*) Malloc(DEFAULT_NUM_SOCK * sizeof(*sock_list));
-	num_of_sock = 0;
-	sock_list_length = DEFAULT_NUM_SOCK;
-	for (int a = 0; a < sock_list_length; a++) {
-		sock_list[a].status = SOCKET_NOT_ALLOCATED;
-		sock_list[a].protocol_family =
-				SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
-	}
-
-	log("leaving SocketCAN__PT_PROVIDER::user_map()");
-}
-
-void SocketCAN__PT_PROVIDER::user_unmap(const char * /*system_port*/) {
-	log("entering SocketCAN__PT_PROVIDER::user_unmap()");
-
-	closeDownSocket();
-
-	log("leaving SocketCAN__PT_PROVIDER::user_unmap()");
-}
-
-void SocketCAN__PT_PROVIDER::user_start() {
-
-}
-
-void SocketCAN__PT_PROVIDER::user_stop() {
-
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__socket& send_par) {
-	log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
-	int cn;
-	SocketCAN__Types::SocketCAN__socket__result result;
-
-	if (num_of_sock < sock_list_length) {
-		cn = 0;
-		while (sock_list[cn].status == SOCKET_OPEN) {
-			cn++;
-		}
-	} else {
-		sock_list = (sock_data*) Realloc(sock_list,
-				2 * sock_list_length * sizeof(*sock_list));
-		for (int a = sock_list_length; a < sock_list_length * 2; a++) {
-			sock_list[a].status = SOCKET_NOT_ALLOCATED;
-		}
-		cn = sock_list_length;
-		sock_list_length *= 2;
-	}
-
-	//extern int socket (int __domain, int __type, int __protocol) __THROW;
-	target_fd = socket(send_par.domain(), send_par.ptype(),
-			send_par.protocol());
-	if (target_fd <= 0) {
-		TTCN_error("Cannot open socket \n");
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = errno;
-		result.result().err__text() = "Cannot open socket";
-	} else {
-		log("SocketCAN opened socket %d \n", target_fd);
-		sock_list[cn].fd = target_fd;
-		sock_list[cn].status = SOCKET_OPEN;
-
-		num_of_sock++;
-
-		//Handler_Add_Fd_Read(target_fd);
-
-		result.id() = cn;
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() = OMIT_VALUE;
-	}
-
-	incoming_message(result);
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__socket)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__ioctl& send_par) {
-	log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__ioctl)");
-
-	struct ifreq ifr;
-
-	int sock;
-	int cn = send_par.id();
-	int res;
-	SocketCAN__Types::SocketCAN__ioctl__result result;
-
-	if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
-		sock = sock_list[cn].fd;
-		if (send_par.ifu().is_present()) {
-			const OPTIONAL<SocketCAN__Types::SocketCAN__ioctl__ifu>& ifu =
-					send_par.ifu();
-			switch (ifu().get_selection()) {
-			case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__name:
-				strcpy(ifr.ifr_name, ifu().if__name());
-				res = ioctl(sock, SIOCGIFINDEX, &ifr);
-				if (res != 0) {
-					TTCN_error(
-							"Ioctl failed on socket: %d with interface name %s\n",
-							sock, (const char *) ifu().if__name());
-					result.ifr().if__name() = ifu().if__name();
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() = "Ioctl failed";
-
-				} else {
-					log("SocketCAN ioctl successful on socket %d \n", sock);
-					result.ifr().if__name() = ifu().if__name();
-					result.ifr().if__index() = ifr.ifr_ifindex;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() = OMIT_VALUE;
-				}
-
-				break;
-			case SocketCAN__Types::SocketCAN__ioctl__ifu::ALT_if__index:
-				res = ioctl(sock, SIOCGIFNAME, &ifr);
-				if (res != 0) {
-					TTCN_error(
-							"Ioctl failed on socket: %d with interface index %llu \n",
-							sock, ifu().if__index().get_long_long_val());
-					result.ifr().if__index() = ifr.ifr_ifindex;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() = "Ioctl failed";
-				} else {
-					log("SocketCAN ioctl successful on socket %d \n", sock);
-					result.ifr().if__name() = ifr.ifr_name;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() = OMIT_VALUE;
-				}
-				break;
-			default:
-				TTCN_error("Ioctl failed due to unknown union selection");
-				break;
-			}
-		} else {
-			// optional ifu filed is not present, set take interface name from applicable TTCN configuration file
-			if (can_interface_name == NULL) {
-				TTCN_error(
-						"Missing mandatory parameter: \"SocketCAN_can_interface_name\" has not been defined in function call to Send Data nor in test configuration file! ");
-			} else {
-				strcpy(ifr.ifr_name, can_interface_name);
-				res = ioctl(sock, SIOCGIFINDEX, &ifr);
-				if (res != 0) {
-					TTCN_error(
-							"Ioctl failed on socket: %d with interface name %s \n",
-							sock, can_interface_name);
-					result.ifr().if__index() = ifr.ifr_ifindex;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() = "Ioctl failed";
-				} else {
-					log("SocketCAN ioctl successful on socket %d \n", sock);
-					result.ifr().if__name() = ifr.ifr_name;
-					result.ifr().if__index() = ifr.ifr_ifindex;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() = OMIT_VALUE;
-				}
-				if (strlen(can_interface_name) <= IFNAMSIZ) {
-					std::strcpy(ifr.ifr_name, can_interface_name);
-
-				} else {
-					TTCN_error(
-							"Ioctl failed due to interface name too long.\n");
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() =
-							"Ioctl failed due to interface name too long";
-				}
-			}
-		}
-	} else {
-		TTCN_error("Ioctl failed due to unknown socket reference: %d \n", cn);
-		result.ifr().if__name() = ifr.ifr_name;
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() =
-				"Ioctl failed due to unknown socket reference";
-	}
-	incoming_message(result);
-	log("SocketCAN__PT::outgoing_send(SocketCAN__ioctl)");
-}
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__connect& send_par) {
-//Client connects to BCM
-	log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
-
-	int sock;
-	struct sockaddr_can addr;
-	int cn = send_par.id();
-	int res;
-	SocketCAN__Types::SocketCAN__connect__result result;
-
-	if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
-		if (sock_list[cn].protocol_family
-				== SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
-			sock = sock_list[cn].fd;
-
-			addr.can_family = AF_CAN;
-
-			SocketCAN__Types::SocketCAN__connectu connectu = send_par.connectu();
-			switch (connectu.get_selection()) {
-			case SocketCAN__Types::SocketCAN__connectu::ALT_bcm:
-				addr.can_ifindex = connectu.bcm().if__index();
-				sock_list[cn].protocol_family
-						= SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
-				break;
-			default:
-				TTCN_error(
-						"connectu union selection does not exist on socket %d: \n",
-						sock);
-				break;
-			}
-			log("Connecting socket: %d with index: %d", sock, addr.can_ifindex);
-			//extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
-			res = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
-			if (res != 0) {
-				TTCN_error("Connecting to socket %d failed: \n", sock);
-				log("Connecting to socket %d failed", sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-				result.result().err__text() = "Connecting to socket failed";
-			} else {
-				log("Connecting socket %d was successful", sock);
-				sock_list[cn].protocol_family =
-						SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM;
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-				sock_list[cn].remote_Addr.can_family = AF_CAN;
-				Handler_Add_Fd_Read(target_fd);
-			}
-		} else {
-			TTCN_error("Socket reference already connected or bound: %d \n",
-					cn);
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-			result.result().err() = OMIT_VALUE;
-			result.result().err__text() =
-					"Socket reference already connected or bound";
-		}
-	} else {
-		TTCN_error("Unknown socket reference: %d \n", cn);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() = "Unknown socket reference";
-	}
-	incoming_message(result);
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__connect)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__bind& send_par) {
-//Client binds
-	log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
-
-	int sock;
-	struct sockaddr_can addr;
-	int cn = send_par.id();
-	int res;
-	SocketCAN__Types::SocketCAN__bind__result result;
-
-	if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
-		if (sock_list[cn].protocol_family
-				== SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL) {
-			int if_index;
-			SocketCAN__PortType::SocketCAN__PT_PROVIDER::socket_protocol_family_enum protocol_family;
-			sock = sock_list[cn].fd;
-
-			addr.can_family = AF_CAN;
-
-			SocketCAN__Types::SocketCAN__bindu bindu = send_par.bindu();
-
-			switch (bindu.get_selection()) {
-			case SocketCAN__Types::SocketCAN__bindu::ALT_raw:
-				if_index = bindu.raw().if__index();
-				protocol_family
-						= SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW;
-				break;
-			case SocketCAN__Types::SocketCAN__bindu::ALT_isotp:
-				if_index = bindu.isotp().if__index();
-				addr.can_addr.tp.rx_id = oct2int(bindu.isotp().rx__can__id());
-				addr.can_addr.tp.tx_id = oct2int(bindu.isotp().tx__can__id());
-				protocol_family
-						= SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP;
-				break;
-			default:
-				TTCN_error(
-						"bindu union selection does not exist on socket %d: \n",
-						sock);
-				break;
-			}
-			addr.can_ifindex = if_index;
-			log("Binding socket: %d with index: %d", sock, if_index);
-			res = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-			if (res != 0) {
-				log("Binding to socket %d failed", sock);
-				TTCN_error("Binding to socket %d failed:\n", sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-			} else {
-				log("Binding socket %d was successful", sock);
-				sock_list[cn].protocol_family = protocol_family ;
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-				sock_list[cn].remote_Addr.can_family = AF_CAN;
-				Handler_Add_Fd_Read(target_fd);
-			}
-		} else {
-			TTCN_error("Socket reference already connected or bound: %d \n",
-					cn);
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-			result.result().err() = errno;
-			result.result().err__text() =
-					"Socket reference already connected or bound";
-		}
-	} else {
-		TTCN_error("Unknown socket reference: %d \n", cn);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() = "Unknown socket reference";
-	}
-	incoming_message(result);
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__bind)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__send__data& send_par) {
-	log(
-			"entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
-
-	SocketCAN__Types::SocketCAN__send__data__result result;
-	int res = 0;
-	int sock;
-	int cn = send_par.id();
-
-	if ((cn < sock_list_length)) {
-		struct sockaddr_can addr;
-		struct ifreq ifr;
-		int nrOfBytesSent, nrOfBytestoSend;
-		sock = sock_list[cn].fd;
-
-		if (send_par.ifu().is_present()) {
-			const OPTIONAL<SocketCAN__Types::SocketCAN__send__data__ifu>& ifu =
-					send_par.ifu();
-			switch (ifu().get_selection()) {
-			case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__index:
-				addr.can_ifindex = ifu().if__index();
-				addr.can_family = AF_CAN;
-				break;
-			case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__name:
-				strcpy(ifr.ifr_name, ifu().if__name());
-				res = ioctl(sock, SIOCGIFINDEX, &ifr);
-				if (res != 0) {
-					TTCN_error(
-							"SocketCAN: Send CAN frame: Ioctl failed while retrieving the interface : %d with interface index %s\n",
-							sock, ifr.ifr_name);
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() =
-							"SocketCAN: Send CAN frame: Ioctl failed while retrieving the interface";
-				}
-				addr.can_ifindex = ifr.ifr_ifindex;
-				addr.can_family = AF_CAN;
-				break;
-			case SocketCAN__Types::SocketCAN__send__data__ifu::ALT_if__any:
-				addr.can_ifindex = 0;
-				addr.can_family = AF_CAN;
-				break;
-			default:
-				TTCN_error(
-						"SocketCAN: Send CAN frame: Unknown union selection");
-				res = -1;
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() =
-						"SocketCAN: Send CAN frame: Unknown union selection";
-			}
-		} else {
-			// optional ifu filed is not present, thus send to any interface:
-			addr.can_ifindex = 0;
-			addr.can_family = AF_CAN;
-		}
-
-		if (res == 0) { // check if previous interface inquiry step failed
-			switch (send_par.frame().get_selection()) {
-			case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame: {
-				struct can_frame frame;
-
-				log("SocketCAN: Sending CAN frame)");
-				logOctet(" to can id: ",
-						send_par.frame().can__frame().can__id());
-				logOctet("containing data: ",
-						send_par.frame().can__frame().can__pdu());
-
-				size_t can_dlc =
-						send_par.frame().can__frame().can__pdu().lengthof();
-				frame.can_id = oct2int(send_par.frame().can__frame().can__id());
-				memcpy(frame.data, send_par.frame().can__frame().can__pdu(),
-						can_dlc);
-				frame.can_dlc = can_dlc;
-
-				nrOfBytestoSend = sizeof(frame);
-				if (send_par.ifu().is_present()) {
-					nrOfBytesSent = sendto(sock, &frame, nrOfBytestoSend, 0,
-							(struct sockaddr*) &addr, sizeof(addr));
-					if (nrOfBytesSent < 0) {
-						log(
-								"SocketCAN: Sent CAN frame with sendto of size %d failed",
-								nrOfBytesSent);
-						TTCN_error(
-								"SocketCAN send with sendto() error while trying to send %d bytes",
-								nrOfBytestoSend);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-						result.result().err() = errno;
-						result.result().err__text() =
-								"SocketCAN send with sendto() error";
-					} else {
-						log(
-								"SocketCAN send data with sendto() successful on socket %d \n",
-								sock);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-						result.result().err() = OMIT_VALUE;
-						result.result().err__text() = OMIT_VALUE;
-					}
-				} else {
-					nrOfBytesSent = send(sock, &frame, nrOfBytestoSend, 0);
-					log("Sent CAN frame with send of size %d", nrOfBytesSent);
-					if (nrOfBytesSent < 0) {
-						log("Sent CAN frame with send of size %d failed",
-								nrOfBytesSent);
-						TTCN_error(
-								"SocketCAN send with send() error while trying to send CAN frame of %d bytes",
-								nrOfBytestoSend);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-						result.result().err() = errno;
-						result.result().err__text() =
-								"SocketCAN send with send() error";
-					} else {
-						log(
-								"SocketCAN send data with send() successful on socket %d \n",
-								sock);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-						result.result().err() = OMIT_VALUE;
-						result.result().err__text() = OMIT_VALUE;
-					}
-				}
-			}
-				break;
-#ifdef RAW_CANFD_SUPPORT
-			case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
-				struct canfd_frame fd_frame;
-
-				log("SocketCAN: Sending CAN FD frame)");
-				logOctet(" to can id: ",
-						send_par.frame().canfd__frame().can__id());
-				logBitstring("with flags: ",
-						send_par.frame().canfd__frame().can__flags());
-				logOctet("containing data: ",
-						send_par.frame().canfd__frame().can__pdu());
-
-				size_t len =
-						send_par.frame().canfd__frame().can__pdu().lengthof();
-				fd_frame.can_id = oct2int(
-						send_par.frame().canfd__frame().can__id());
-				memcpy(fd_frame.data,
-						send_par.frame().canfd__frame().can__pdu(), len);
-				fd_frame.len = len;
-
-				nrOfBytestoSend = sizeof(fd_frame);
-				if (send_par.ifu().is_present()) {
-
-					nrOfBytesSent = sendto(sock, &fd_frame, nrOfBytestoSend, 0,
-							(struct sockaddr*) &addr, sizeof(addr));
-					if (nrOfBytesSent < 0) {
-						TTCN_error(
-								"SocketCAN FD send with sendto() error while trying to send %d bytes",
-								nrOfBytestoSend);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-						result.result().err() = errno;
-						result.result().err__text() =
-								"SocketCAN FD send with sendto() error";
-					} else {
-						log(
-								"SocketCAN: Sent CAN FD frame with sendto() of size %d",
-								nrOfBytesSent);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-						result.result().err() = OMIT_VALUE;
-						result.result().err__text() = OMIT_VALUE;
-					}
-				} else {
-					nrOfBytesSent = send(sock, &fd_frame, nrOfBytestoSend, 0);
-					if (nrOfBytesSent < 0) {
-						TTCN_error(
-								"SocketCAN FD send with send() error while trying to send %d bytes",
-								nrOfBytestoSend);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-						result.result().err() = errno;
-						result.result().err__text() =
-								"SocketCAN FD send with send() error";
-					} else {
-						log(
-								"SocketCAN: Sent CAN FD frame with send() of size %d",
-								nrOfBytesSent);
-						result.result().result__code() =
-								SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-						result.result().err() = OMIT_VALUE;
-						result.result().err__text() = OMIT_VALUE;
-					}
-				}
-			}
-				break;
-#else  // RAW_CANFD_SUPPORT
-				case SocketCAN__Types::SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame: {
-					TTCN_error(
-							"SocketCAN: CAN FD is not supported by your current kernel error");
-					result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() =
-					"SocketCAN: CAN FD is not supported by your current kernel error";
-				}
-				break;
-#endif // RAW_CANFD_SUPPORT
-
-			default:
-				TTCN_error("SocketCAN send unknown frame type error");
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() =
-						"SocketCAN send unknown frame type error";
-				break;
-			}
-			log("SocketCAN: Nr of bytes sent = %d", nrOfBytesSent);
-			if ((nrOfBytesSent > 0) and (nrOfBytesSent != nrOfBytestoSend)
-					and (nrOfBytestoSend != 0)) {
-				TTCN_error(
-						"Send system call failed: %d bytes were sent instead of %d",
-						nrOfBytesSent, nrOfBytestoSend);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() =
-						"SocketCAN write failed as wrong number of bytes have been written";
-			}
-		}
-	} else {
-		TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() = "Unknown socket reference";
-	}
-	incoming_message(result);
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__send__data)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__write__data& send_par) {
-	log(
-			"entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
-
-	SocketCAN__Types::SocketCAN__write__data__result result;
-	int sock;
-	int cn = send_par.id();
-
-	if ((cn < sock_list_length)
-			and (sock_list[cn].protocol_family
-					== SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_BCM)
-			and (sock_list[cn].status == SOCKET_OPEN)) {
-		sock = sock_list[cn].fd;
-
-		switch (send_par.bcm__tx__msg().frames().get_selection()) {
-		case Bcm::SocketCAN__bcm__frame_frames::ALT_can__frame: {
-			int nrOfBytesSent = 0;
-			int nrOfBytestoSend = 0;
-			struct {
-				struct bcm_msg_head msg_head;
-				struct can_frame frame[BCM_FRAME_BUFFER_SIZE];
-			} bcm_msg;
-
-			const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
-					send_par.bcm__tx__msg();
-
-			int nframes = bcm__tx__msg.frames().can__frame().lengthof();
-
-			if (nframes > BCM_FRAME_BUFFER_SIZE) {
-				TTCN_error(
-						"SocketCAN: Writing data: number of CAN frames too large: %d \n",
-						nframes);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-				result.result().err__text() =
-						"SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent";
-				TTCN_error(
-						"SocketCAN sending CAN data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN frames to be sent");
-			} else {
-				const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
-						send_par.bcm__tx__msg();
-
-				bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
-				bcm_msg.msg_head.flags = bit2int(
-						send_par.bcm__tx__msg().flags());
-				bcm_msg.msg_head.count = bcm__tx__msg.count();
-				bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
-				bcm_msg.msg_head.ival1.tv_usec =
-						bcm__tx__msg.ival1().tv__usec();
-				bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
-				bcm_msg.msg_head.ival2.tv_usec =
-						bcm__tx__msg.ival2().tv__usec();
-				bcm_msg.msg_head.can_id = oct2int(bcm__tx__msg.can__id());
-				bcm_msg.msg_head.nframes = nframes;
-
-				log("SocketCAN: Sending BCM Message)");
-				logOctet(" opcode: ", bcm__tx__msg.opcode());
-				logBitstring(" flags: ", bcm__tx__msg.flags());
-				logInteger(" count: ", bcm__tx__msg.count());
-				logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
-				logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
-				logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
-				logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
-				logOctet(" can_id: ", bcm__tx__msg.can__id());
-				logInteger(" nframes: ", nframes);
-
-				for (int i = 0; i < nframes; i++) {
-					const Bcm::SocketCAN__bcm__frame_frames_can__frame& frame =
-							bcm__tx__msg.frames().can__frame();
-
-					bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
-					unsigned int can_dlc;
-					can_dlc = frame[i].can__pdu().lengthof();
-					if (can_dlc > CAN_MAX_DLEN) {
-						TTCN_error(
-								"SocketCAN writing data: CAN pdu size too large\n");
-						can_dlc = CAN_MAX_DLEN;
-					};
-					log(" containing CAN frame:)");
-					logOctet("   can id: ", frame[i].can__id());
-					logInteger("   can dlc: ", can_dlc);
-
-					bcm_msg.frame[i].can_dlc = can_dlc;
-					for (unsigned int j = 0; j < can_dlc; j++) {
-						bcm_msg.frame[i].data[j] = oct2int(
-								frame[i].can__pdu()[j]);
-						logOctet("   data: ", frame[i].can__pdu()[j]);
-					}
-				}
-				// assuming that the struct within the structure are aligned cm_msg without passing
-				// BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
-				nrOfBytestoSend = sizeof(struct bcm_msg_head)
-						+ nframes * sizeof(struct can_frame);
-
-				nrOfBytesSent = write(sock, &bcm_msg, (int) nrOfBytestoSend);
-
-				if ((nrOfBytesSent) < 0) {
-					int myerrno = errno;
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = myerrno;
-					result.result().err__text() =
-							"SocketCAN sending CAN data with write() failed";
-					logInteger("bcm_msg.msg_head.can_id: ",
-							(bcm_msg.msg_head.can_id));
-					logInteger("bcm_msg.msg_head.count: ",
-							bcm_msg.msg_head.count);
-					logInteger("bcm_msg.msg_head.flags: ",
-							bcm_msg.msg_head.flags);
-					logInteger("bcm_msg.msg_head.ival1.tv_sec: ",
-							bcm_msg.msg_head.ival1.tv_sec);
-					logInteger("bcm_msg.msg_head.ival1.tv_usec: ",
-							bcm_msg.msg_head.ival1.tv_usec);
-					logInteger("bcm_msg.msg_head.ival2.tv_sec: ",
-							bcm_msg.msg_head.ival2.tv_sec);
-					logInteger("bcm_msg.msg_head.ival2.tv_usec: ",
-							bcm_msg.msg_head.ival2.tv_usec);
-					logInteger("bcm_msg.msg_head.nframes: ",
-							bcm_msg.msg_head.nframes);
-					logInteger("bcm_msg.msg_head.opcode: ",
-							bcm_msg.msg_head.opcode);
-
-					TTCN_error(
-							//"SocketCAN sending CAN data with write() failed");
-							"SocketCAN sending CAN data with write() failed. nrOfBytestoSend: %d, sizeof(struct bcm_msg_head): %d, nframes: %d, sizeof(struct can_frame): %d, nrOfBytesSent: %d, errno: %d\n",
-							nrOfBytestoSend,
-							((int) sizeof(struct bcm_msg_head)),
-							((int) nframes), ((int) sizeof(struct can_frame)),
-							(int) nrOfBytesSent, (int) myerrno);
-				} else {
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-					result.result().err() = nrOfBytesSent;
-					result.result().err__text() = OMIT_VALUE;
-				}
-				log("Nr of bytes sent = %d", nrOfBytesSent);
-
-				if (nrOfBytesSent != nrOfBytestoSend) {
-					TTCN_error(
-							"SocketCAN frame  write failed: %d bytes were sent instead of %d",
-							nrOfBytesSent, nrOfBytestoSend);
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() =
-							"SocketCAN write failed as wrong number of bytes have been written";
-				}
-			}
-		}
-			break;
-#ifdef BCM_CANFD_SUPPORT
-			case Bcm::SocketCAN__bcm__frame_frames::ALT_canfd__frame: {
-				int nrOfBytesSent = 0;
-				int nrOfBytestoSend = 0;
-				struct {
-					struct bcm_msg_head msg_head;
-					struct canfd_frame frame[BCM_FRAME_BUFFER_SIZE];
-				}bcm_msg;
-
-				const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
-				send_par.bcm__tx__msg();
-
-				unsigned int nframes =
-				bcm__tx__msg.frames().canfd__frame().lengthof();
-
-				if (nframes > BCM_FRAME_BUFFER_SIZE) {
-					TTCN_error(
-							"SocketCAN writing data: number of CAN FD frames too large: %d \n",
-							nframes);
-					result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() =
-					"SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent";
-					TTCN_error(
-							"SocketCAN sending CAN FD data with write() failed, as more than BCM_FRAME_BUFFER_SIZE number of CAN FD frames to be sent");
-				} else {
-					const Bcm::SocketCAN__bcm__frame& bcm__tx__msg =
-					send_par.bcm__tx__msg();
-
-					bcm_msg.msg_head.opcode = oct2int(bcm__tx__msg.opcode());
-					bcm_msg.msg_head.flags = bit2int(
-							send_par.bcm__tx__msg().flags());
-					bcm_msg.msg_head.count = bcm__tx__msg.count();
-					bcm_msg.msg_head.ival1.tv_sec = bcm__tx__msg.ival1().tv__sec();
-					bcm_msg.msg_head.ival1.tv_usec =
-					bcm__tx__msg.ival1().tv__usec();
-					bcm_msg.msg_head.ival2.tv_sec = bcm__tx__msg.ival2().tv__sec();
-					bcm_msg.msg_head.ival2.tv_usec =
-					bcm__tx__msg.ival2().tv__usec();
-					bcm_msg.msg_head.nframes = nframes;
-
-					log("SocketCAN: Sending BCM Message)");
-					logOctet(" opcode: ", bcm__tx__msg.opcode());
-					logBitstring(" flags: ", bcm__tx__msg.flags());
-					logInteger(" count: ", bcm__tx__msg.count());
-					logInteger(" ival1: ", bcm__tx__msg.ival1().tv__sec());
-					logInteger(" ival1: ", bcm__tx__msg.ival1().tv__usec());
-					logInteger(" ival2: ", bcm__tx__msg.ival2().tv__sec());
-					logInteger(" ival2: ", bcm__tx__msg.ival2().tv__usec());
-					logOctet(" can_id: ", send_par.bcm__tx__msg().can__id());
-					logInteger(" nframes: ", nframes);
-
-					for (unsigned int i = 0; i < nframes; i++) {
-						const Bcm::SocketCAN__bcm__frame_frames_canfd__frame& frame =
-						bcm__tx__msg.frames().canfd__frame();
-
-						bcm_msg.frame[i].can_id = oct2int(frame[i].can__id());
-						bcm_msg.frame[i].flags = bit2int(frame[i].can__flags());
-						unsigned int len = frame[i].can__pdu().lengthof();
-						if (len > CANFD_MAX_DLEN) {
-							TTCN_error("Writing data: CAN FD pdu size too large\n");
-							len = CANFD_MAX_DLEN;
-						};
-						log(" containing CAN FD frame:)");
-						logOctet("   can id: ", frame[i].can__id());
-						logInteger("   can len: ", len);
-
-						bcm_msg.frame[i].len = len;
-						for (unsigned int j = 0; j < len; j++) {
-							bcm_msg.frame[i].data[j] = oct2int(
-									frame[i].can__pdu()[j]);
-							logOctet("   data: ", frame[i].can__pdu()[j]);
-						}
-					}
-					// assuming that the structs within the structure are aligned cm_msg without passing
-					// BCM_write does not calculate unused fields from nframes to BCM_FRAME_BUFFER_SIZE
-					nrOfBytestoSend = sizeof(struct bcm_msg_head)
-					+ nframes * sizeof(struct canfd_frame);
-					nrOfBytesSent = write(sock, &bcm_msg, nrOfBytestoSend);
-
-					if (nrOfBytesSent < 0) {
-						result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-						result.result().err() = errno;
-						result.result().err__text() =
-						"SocketCAN sending CAN FD data with write() failed";
-						TTCN_error(
-								"SocketCAN sending CAN FD data with write() failed");
-					} else {
-						result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-						result.result().err() = OMIT_VALUE;
-						result.result().err__text() = OMIT_VALUE;
-					}
-				}
-
-				log("Nr of bytes sent = %d", nrOfBytesSent);
-
-				if (nrOfBytesSent != nrOfBytestoSend) {
-					TTCN_error(
-							"SocketCAN CAN fd frame write failed: %d bytes were sent instead of %d",
-							nrOfBytesSent, nrOfBytestoSend);
-					result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() =
-					"SocketCAN write failed as wrong number of bytes have been written";
-				}
-			}
-			break;
-#endif //BCM_CANFD_SUPPORT
-
-		default:
-			TTCN_error("SocketCAN write unknown frame type error");
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-			result.result().err() = OMIT_VALUE;
-			result.result().err__text() =
-					"SocketCAN write unknown frame type error";
-			break;
-		}
-	} else {
-		TTCN_error(
-				"SocketCAN  write data failed due to unknown socket reference: %d \n",
-				cn);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() =
-				"SocketCAN  write data failed due to unknown socket reference";
-	}
-	incoming_message(result);
-	log(
-			"leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__data)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__write__isotp& send_par) {
-	log(
-			"entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__isotp)");
-
-	SocketCAN__Types::SocketCAN__write__isotp__result result;
-	int sock;
-	int cn = send_par.id();
-
-	if ((cn < sock_list_length)
-			and (sock_list[cn].protocol_family
-					== SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP)
-			and (sock_list[cn].status == SOCKET_OPEN)) {
-		sock = sock_list[cn].fd;
-
-		int nrOfBytesSent = 0;
-		int nrOfBytestoSend = send_par.pdu().lengthof();
-
-		logOctet("Writing ISOTP data on socket: ", send_par.pdu());
-		nrOfBytesSent = write(sock, send_par.pdu(), nrOfBytestoSend);
-		log(
-				"Written to ISOTP %d bytes data of the expected %d bytes on socket %d: ",
-				nrOfBytesSent, nrOfBytestoSend, sock);
-		if (nrOfBytesSent != nrOfBytestoSend) {
-			TTCN_warning(
-					"SocketCAN write isotp has written %d bytes, which are fewer than expected %d bytes to socket: %d \n",
-					nrOfBytesSent, nrOfBytestoSend, sock);
-		}
-		if (nrOfBytesSent < 0) {
-			TTCN_error("SocketCAN write isotp failed with error code %d:\n",
-			errno);
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-			result.result().err() = errno;
-			result.result().err__text() = "SocketCAN write isotp failed";
-		} else {
-			log(
-					"SocketCAN: write isotp successful on socket %d",
-					sock);
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-			result.result().err() = OMIT_VALUE;
-			result.result().err__text() = OMIT_VALUE;
-		}
-	} else {
-		TTCN_error(
-				"SocketCAN write isotp failed due to unknown socket reference: %d with protocol family %d and status %d\n",
-				cn, sock_list[cn].protocol_family, sock_list[cn].status);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = OMIT_VALUE;
-		result.result().err__text() =
-				"SocketCAN write isotp failed due to unknown socket reference";
-	}
-	incoming_message(result);
-	log(
-			"leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__write__isotp)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__setsockopt& send_par) {
-	log(
-			"entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
-
-	int sock;
-	int cn = send_par.id();
-	int res;
-	SocketCAN__Types::SocketCAN__setsockopt__result result;
-
-	if ((cn < sock_list_length) and (sock_list[cn].status == SOCKET_OPEN)) {
-		sock = sock_list[cn].fd;
-
-		SocketCAN__Types::SocketCAN__setsockopt__commandu::union_selection_type command_selection =
-				send_par.command().get_selection();
-
-		switch (command_selection) {
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_rfilter: {
-
-			std::size_t rfilter_size = (sizeof(send_par.command().rfilter())
-					/ sizeof(send_par.command().rfilter()[0]));
-
-			struct can_filter rfilter[rfilter_size];
-
-			if (rfilter_size == 0) {
-				// deactivate filters
-				res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
-			} else {
-				for (std::size_t i = 0; i < rfilter_size; i++) {
-					rfilter[i].can_id = oct2int(
-							send_par.command().rfilter()[i].can__id());
-					rfilter[i].can_mask = oct2int(
-							send_par.command().rfilter()[i].can__mask());
-				};
-				res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
-						sizeof(rfilter));
-			}
-			if (res < 0) {
-				TTCN_error(
-						"SocketCAN  setsockopt rfilter failed with error code %d:\n",
-						errno);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-				result.result().err__text() =
-						"SocketCAN  setsockopt rfilter failed";
-
-			} else {
-				log("SocketCAN: setsockopt rfilter successful on socket %d",
-						sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-			}
-		}
-			break;
-
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_err__mask: {
-			can_err_mask_t err_mask = bit2int(send_par.command().err__mask());
-			res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask,
-					sizeof(err_mask));
-			if (res < 0) {
-				int myerrno = errno;
-				TTCN_error(
-						"SocketCAN  setsockopt can__err__mask failed with error code %d:\n",
-						myerrno);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = myerrno;
-				result.result().err__text() =
-						"SocketCAN  setsockopt can__err__mask failed";
-			} else {
-				log(
-						"SocketCAN: setsockopt can__err__mask successful on socket %d",
-						sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-			}
-		}
-			break;
-
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_loopback: {
-
-			int loopback = send_par.command().loopback();
-			res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback,
-					sizeof(loopback));
-			if (res < 0) {
-				int myerrno = errno;
-				TTCN_error(
-						"SocketCAN  setsockopt loopbackfailed with error code %d:\n",
-						myerrno);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = myerrno;
-				result.result().err__text() =
-						"SocketCAN  setsockopt loopback failed";
-			} else {
-				log("SocketCAN: setsockopt loopback successful on socket %d",
-						sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-			}
-		}
-			break;
-
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_recv__own__msgs: {
-
-			int recv_own_msgs = send_par.command().recv__own__msgs();
-			res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
-					&recv_own_msgs, sizeof(recv_own_msgs));
-			if (res < 0) {
-				TTCN_error(
-						"SocketCAN  setsockopt recv__own__msg failed with error code %d:\n",
-						errno);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-				result.result().err__text() =
-						"SocketCAN  setsockopt recv__own__msg failed";
-			} else {
-				log(
-						"SocketCAN: setsockopt recv__own__msg successful on socket %d",
-						sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-			}
-		}
-			break;
-
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_fd__frames: {
-
-			int fd_frames = send_par.command().fd__frames();
-
-			res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_frames,
-					sizeof(fd_frames));
-			if (res < 0) {
-				TTCN_error(
-						"SocketCAN  setsockopt fd__frames failed with error code %d:\n",
-						errno);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-				result.result().err() = errno;
-				result.result().err__text() =
-						"SocketCAN  setsockopt fd__frames failed";
-			} else {
-				log("SocketCAN: setsockopt fd__frames successful on socket %d",
-						sock);
-				result.result().result__code() =
-						SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-				result.result().err() = OMIT_VALUE;
-				result.result().err__text() = OMIT_VALUE;
-			}
-		}
-			break;
-		case SocketCAN__Types::SocketCAN__setsockopt__commandu::ALT_join__filters: {
-			{
-				int join_filters = send_par.command().join__filters();
-
-				res = setsockopt(sock, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,
-						&join_filters, sizeof(join_filters));
-				if (res < 0) {
-					TTCN_error(
-							"SocketCAN  setsockopt join__filters failed with error code %d:\n",
-							errno);
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-					result.result().err() = errno;
-					result.result().err__text() =
-							"SocketCAN  setsockopt join__filters failed";
-				} else {
-					log(
-							"SocketCAN: setsockopt join__filterssuccessful on socket %d",
-							sock);
-					result.result().result__code() =
-							SocketCAN__Types::SocketCAN__Result__code::SocketCAN__SUCCESS;
-					result.result().err() = OMIT_VALUE;
-					result.result().err__text() = OMIT_VALUE;
-				}
-			}
-		}
-			break;
-		default: {
-			TTCN_error(
-					"SocketCAN: Unknown SocketCAN_setsockopt commandu union selection: %d \n",
-					cn);
-			result.result().result__code() =
-					SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-			result.result().err() = OMIT_VALUE;
-			result.result().err__text() =
-					"SocketCAN: Unknown SocketCAN_setsockopt commandu union selection";
-			break;
-		}
-		}
-	} else {
-		TTCN_error("SocketCAN: Unknown socket reference: %d \n", cn);
-		result.result().result__code() =
-				SocketCAN__Types::SocketCAN__Result__code::SocketCAN__ERROR;
-		result.result().err() = errno;
-		result.result().err__text() = "SocketCAN: Unknown socket reference";
-	}
-	incoming_message(result);
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__setsockopt)");
-}
-
-void SocketCAN__PT_PROVIDER::outgoing_send(
-		const SocketCAN__Types::SocketCAN__close& send_par) {
-	log("entering SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
-	int sock = sock_list[send_par.id()].fd;
-
-	sock_list[send_par.id()].status = SOCKET_NOT_ALLOCATED;
-	sock_list[send_par.id()].fd = 0;
-	sock_list[send_par.id()].protocol_family =
-			SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
-	num_of_sock--;
-	Handler_Remove_Fd_Read(sock);
-
-	close(sock);
-
-	log("leaving SocketCAN__PT_PROVIDER::outgoing_send(SocketCAN__close)");
-}
-
-void SocketCAN__PT_PROVIDER::reset_configuration() {
-	free(can_interface_name);
-	can_interface_name = NULL;
-	debugging = false;
-	debugging_configured = false;
-}
-
-void SocketCAN__PT_PROVIDER::InitStrPar(char *&par, const char* name,
-		const char* val) {
-	if (name)
-		log("%s: Reading testport parameter: "
-				"%s = %s", port_name, name, val);
-
-	if (par)
-		free(par);
-	par = (char*) malloc(strlen(val) + 1);
-	if (par == NULL)
-		TTCN_error("Not enough memory.");
-	strcpy(par, val);
-}
-
-void SocketCAN__PT_PROVIDER::log(const char *fmt, ...) {
-	if (debugging == true) {
-		TTCN_Logger::begin_event(TTCN_DEBUG);
-		TTCN_Logger::log_event("SocketCAN test port (%s): ", get_name());
-		va_list args;
-		va_start(args, fmt);
-		TTCN_Logger::log_event_va_list(fmt, args);
-		va_end(args);
-		TTCN_Logger::end_event();
-	}
-}
-
-void SocketCAN__PT_PROVIDER::logOctet(const char *prompt,
-		const OCTETSTRING& msg) {
-	if (debugging == true) { //if debug
-		TTCN_Logger::begin_event(TTCN_DEBUG);
-		TTCN_Logger::log_event_str(prompt);
-		TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
-
-		for (int i = 0; i < msg.lengthof(); i++) {
-			TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
-		}
-		TTCN_Logger::log_event("\n");
-		TTCN_Logger::end_event();
-	}
-}
-
-void SocketCAN__PT_PROVIDER::logHex(const char *prompt, const HEXSTRING& msg) {
-	if (debugging == true) { //if debug
-		TTCN_Logger::begin_event(TTCN_DEBUG);
-		TTCN_Logger::log_event_str(prompt);
-		TTCN_Logger::log_event("Size: %d,\nMsg: ", msg.lengthof());
-
-		for (int i = 0; i < msg.lengthof(); i++) {
-			TTCN_Logger::log_event(" %02x", ((const unsigned char*) msg)[i]);
-		}
-		TTCN_Logger::log_event("\n");
-		TTCN_Logger::end_event();
-	}
-}
-
-void SocketCAN__PT_PROVIDER::logInteger(const char *prompt, const int number) {
-	if (debugging) { //if debug
-		TTCN_Logger::begin_event(TTCN_DEBUG);
-		TTCN_Logger::log_event_str(prompt);
-		TTCN_Logger::log_event("Value: %d,\n: ", number);
-		TTCN_Logger::log_event("\n");
-		TTCN_Logger::end_event();
-	}
-}
-
-void SocketCAN__PT_PROVIDER::logBitstring(const char *prompt,
-		const BITSTRING& msg) {
-	if (debugging == true) { //if debug
-		TTCN_Logger::begin_event(TTCN_DEBUG);
-		TTCN_Logger::log_event_str(prompt);
-		int len = msg.lengthof();
-		TTCN_Logger::log_event("Size: %d,\nMsg: 0b", len);
-		for (int i = 0; i < msg.lengthof(); i++) {
-			TTCN_Logger::log_event("%d", (int) bit2int(msg[i]));
-		}
-		TTCN_Logger::log_event("\n");
-		TTCN_Logger::end_event();
-	}
-}
-
-void SocketCAN__PT_PROVIDER::setUpSocket() {
-	log("entering SocketCAN__PT_PROVIDER::setUpSocket()");
-	log("leaving SocketCAN__PT_PROVIDER::setUpSocket()");
-}
-
-void SocketCAN__PT_PROVIDER::closeDownSocket() {
-	log("entering SocketCAN__PT_PROVIDER::closeDownSocket()");
-
-	for (int a = 0; a < sock_list_length; a++) {
-		if (sock_list[a].status == SOCKET_OPEN) {
-			sock_list[a].status = SOCKET_NOT_ALLOCATED;
-			sock_list[a].protocol_family =
-					SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_NO_PROTOCOL;
-			close(sock_list[a].fd);
-			Handler_Remove_Fd_Read(sock_list[a].fd);
-		}
-	}
-
-	Free(sock_list);
-	sock_list = NULL;
-
-	log("leaving SocketCAN__PT_PROVIDER::closeDownSocket()");
-}
-
-}
-/* end of namespace */
-
+/******************************************************************************

+ * Copyright (c) 2010, 2016  Ericsson AB

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ * Michael Josenhans

+ ******************************************************************************/

+//

+//  File:               SocketCAN_PT.cc

+//  Description:        SocketCAN_PT test port source

+//

+// Revision R1A

+#include "SocketCAN_PT.hh"

+#include "SocketCAN_PortType.hh"

+

+#include <Addfunc.hh>

+#include <Bitstring.hh>

+#include <Charstring.hh>

+#include <errno.h>

+#include <Error.hh>

+#include <Hexstring.hh>

+#include <Integer.hh>

+#include <linux/can/bcm.h>

+#include <linux/can/raw.h>

+#include <linux/if.h>

+#include <Logger.hh>

+#include <memory.h>

+#include <Octetstring.hh>

+#include <Optional.hh>

+#include <Port.hh>

+#include <stdlib.h>

+#include <sys/ioctl.h>

+#include <Template.hh>

+#include <unistd.h>

+#include <algorithm>

+#include <cerrno>

+#include <cstdarg>

+#include <cstddef>

+#include <cstring>

+#include <iostream>

+

+struct bcm_msg_head;

+struct can_frame;

+struct canfd_frame;

+

+#define DEFAULT_NUM_SOCK          10

+#define BCM_FRAME_BUFFER_SIZE    256

+#define BCM_FRAME_FLAGS_SIZE      32 // size of SocketCAN_bcm_frame in Bit

+#define ISOTP_RECIEVE_BUFSIZE   5000

+

+// workaround, as some of those below may not yet be defined in "linux/can/raw.h":

+#define CAN_RAW_FILTER            1 /* set 0 .. n can_filter(s)          */

+#define CAN_RAW_ERR_FILTER        2 /* set filter for error frames       */

+#define CAN_RAW_LOOPBACK          3 /* local loopback (default:on)       */

+#define CAN_RAW_RECV_OWN_MSGS     4 /* receive my own msgs (default:off) */

+#define CAN_RAW_FD_FRAMES         5 /* allow CAN FD frames (default:off) */

+#define CAN_RAW_JOIN_FILTERS      6 /* all filters must match to trigger */

+

+// workaround, as not yet defined in all versions of "linux/Can.h":

+#ifndef CAN_MAX_DLEN

+#define CAN_MAX_DLEN 8

+#endif

+

+// workaround, as not defined in some older kernel versions

+#ifndef	CAN_MTU

+#define CAN_MTU		(sizeof(struct can_frame))

+#endif  //CAN_MTU

+

+#ifndef	CANFD_MTU

+#define CANFD_MTU	(sizeof(struct canfd_frame))

+#endif  //CANFD_MTU

+

+// workaround, as canfd not defined in some older kernel versions

+// and thus canfd frames can not be used for data transfer between 

+// kernel module and userspace.

+#ifdef	CANFD_MTU

+#define CANFD_FRAME_STRUCT_DEFINED             true

+#define RAW_CANFD_SUPPORT                      true

+#endif  //CANFD_MTU

+

+// has to be defined in later kernel versions in bcm.h as #define CAN_FD_FRAME   0x0800

+#ifdef  CAN_FD_FRAME

+#define BCM_CANFD_SUPPORT                      true

+#endif

+

+namespace SocketCAN__PortType {

+

+SocketCAN__PT_PROVIDER::SocketCAN__PT_PROVIDER(const char *par_port_name) :

+		PORT(par_port_name), num_of_sock(0), sock_list_length(0), target_fd(-1), can_interface_name(

+				NULL), debugging(false), debugging_configured(false), config_finished(

+				false) {

+	sock_list = NULL;

+	//&num_of_sock = 0;

+	//sock_list_length = 0;

+}

+

+SocketCAN__PT_PROVIDER::~SocketCAN__PT_PROVIDER() {

+	Free(sock_list);

+	reset_configuration();

+}

+

+void SocketCAN__PT_PROVIDER::set_parameter(const char * parameter_name,

+		const char * parameter_value) {

+	log("entering SocketCAN__PT_PROVIDER::set_parameter(%s, %s)",

+			parameter_name, parameter_value);

+

+	if (config_finished) {

+		reset_configuration();

+		config_finished = false;

+	}

+

+	if (strcmp(parameter_name, "SocketCAN_can_interface_name") == 0) {

+		InitStrPar(can_interface_name, parameter_name, parameter_value);

+	} else if (strcmp(parameter_name, "SocketCAN_debugging") == 0) {

+		if (strcmp(parameter_value, "YES") == 0) {

+			debugging = true;

+			debugging_configured = true;

+			log("Reading testport parameter debugging: ", debugging);

+		} else if (strcmp(parameter_value, "NO") == 0) {

+			debugging = false;

+			debugging_configured = true;

+			log("Reading testport parameter debugging: ", debugging);

+		}

+	} else {

+		TTCN_error(

+				"SocketCAN parameter configuration error: Configuration file does not correctly configure parameter 'SocketCAN_debugging' however parameter name '%s' as parameter value: '%s'!!\nExpecting: \n*.*.SocketCAN_debugging := \"YES\"\n or \n*.*.SocketCAN_debugging := \"NO\"",

+				parameter_name, parameter_value);

+	}

+

+	log("leaving SocketCAN__PT_PROVIDER::set_parameter(%s, %s)", parameter_name,

+			parameter_value);

+}

+

+/*void SocketCAN__PT_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,

+ boolean is_writable, boolean is_error) {}*/

+

+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Error(int /*fd*/) {

+

+}

+

+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/) {

+

+}

+

+void SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable(int sock) {

+	log("entering SocketCAN__PT_PROVIDER::Handle_Fd_Event_Readable()");

+	int res;

+

+	for (int a = 0; a < sock_list_length; a++) {

+		if ((sock == sock_list[a].fd)

+				and (sock_list[a].status != SOCKET_NOT_ALLOCATED)) {

+			switch (sock_list[a].protocol_family) {

+			case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_ISOTP: {

+				SocketCAN__Types::SocketCAN__receive__isotp__pdu parameters;

+

+				unsigned char msg[ISOTP_RECIEVE_BUFSIZE];

+

+				int nbytes = 0;

+				struct sockaddr_can addr;

+				socklen_t addr_len = sizeof(addr);

+				//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

+				// struct sockaddr *src_addr, socklen_t *addrlen);

+				nbytes = recvfrom(sock, msg, ISOTP_RECIEVE_BUFSIZE, 0,

+						(struct sockaddr*) &addr, &addr_len);

+

+				//nbytes = read(sock, msg, ISOTP_RECIEVE_BUFSIZE);

+				if (nbytes > 0 && nbytes < ISOTP_RECIEVE_BUFSIZE) {

+					struct ifreq ifr;

+					ifr.ifr_ifindex = addr.can_ifindex;

+					parameters.ifr().if__index() = ifr.ifr_ifindex;

+					parameters.ifr().if__name() = ifr.ifr_name;

+					parameters.id() = a;

+					parameters.pdu() = OCTETSTRING(nbytes, msg);

+					incoming_message(parameters);

+				}

+			}

+				break;

+			case SocketCAN__PortType::SocketCAN__PT_PROVIDER::SOCKET_PROTOCOL_CAN_RAW: {

+				SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame parameters;

+

+				struct sockaddr_can addr;

+				socklen_t addr_len = sizeof(addr);

+				//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

+				// struct sockaddr *src_addr, socklen_t *addrlen);

+#ifdef	CANFD_FRAME_STRUCT_DEFINED   // struct canfd_frame is supported

+				struct canfd_frame frame; // always 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 */

+