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 */
+