From 0c8eb74c1758868b3299faf7b03fea0bf3d87c0b Mon Sep 17 00:00:00 2001
From: Claudiu MILEA <cmilea@bitdefender.com>
Date: Sat, 3 Jun 2023 15:54:00 +0300
Subject: [PATCH] Add separate sockets to ECU processes for packet sniffing

---
 .../ecu_coordinator.py                        | 29 +++++++++++++------
 chassis-powertrain-body-setup/ecu_process.py  | 20 +++++++++----
 .../periodic_send_thread.py                   |  1 -
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/chassis-powertrain-body-setup/ecu_coordinator.py b/chassis-powertrain-body-setup/ecu_coordinator.py
index 90eedca..949be80 100644
--- a/chassis-powertrain-body-setup/ecu_coordinator.py
+++ b/chassis-powertrain-body-setup/ecu_coordinator.py
@@ -1,13 +1,13 @@
-from scapy.config import conf
-from scapy.contrib.cansocket_python_can import CANSocket
-from scapy.main import load_contrib
+import time
 
-from can_id_sheet import VehicleSegment
+from can_id_sheet import VehicleSegment, CANFrame
 from ecu_process import GenericECU
 
+from scapy.config import conf
+from scapy.contrib.cansocket_python_can import CANSocket
+from scapy.main import load_contrib
 from time import sleep
 import multiprocessing as mp
-
 import can
 
 
@@ -30,6 +30,12 @@ def coordinate_python_can():
         sleep(5)
 
 
+def get_filtered_can_socket(vehicle_segment: VehicleSegment):
+    filters = [{'can_id': f.value, 'can_mask': 0x7FF} for f in CANFrame if
+               f.execution == vehicle_segment]
+    return CANSocket(bustype='virtual', channel='vcan0', bitrate=250000, can_filters=filters)
+
+
 if __name__ == '__main__':
     # CAN related setup
     # load_layer("can")
@@ -38,15 +44,20 @@ if __name__ == '__main__':
     conf.contribs['CANSocket'] = {'use-python-can': True}
     load_contrib('cansocket')
     socket = CANSocket(bustype='virtual', channel='vcan0', bitrate=250000)
-
     # socket = CANSocket(channel='vcan0')
 
     # multiprocessing setup
     mp.set_start_method('fork')
     processes = [
-        GenericECU(socket=socket, vehicle_segment=VehicleSegment.Chassis),
-        GenericECU(socket=socket, vehicle_segment=VehicleSegment.PowerTrain),
-        GenericECU(socket=socket, vehicle_segment=VehicleSegment.Body),
+        GenericECU(tx_socket=socket,
+                   rx_socket=get_filtered_can_socket(VehicleSegment.Chassis),
+                   vehicle_segment=VehicleSegment.Chassis),
+        GenericECU(tx_socket=socket,
+                   rx_socket=get_filtered_can_socket(VehicleSegment.PowerTrain),
+                   vehicle_segment=VehicleSegment.PowerTrain),
+        GenericECU(tx_socket=socket,
+                   rx_socket=get_filtered_can_socket(VehicleSegment.Body),
+                   vehicle_segment=VehicleSegment.Body)
     ]
 
     for p in processes:
diff --git a/chassis-powertrain-body-setup/ecu_process.py b/chassis-powertrain-body-setup/ecu_process.py
index 4c7520a..38ed04e 100644
--- a/chassis-powertrain-body-setup/ecu_process.py
+++ b/chassis-powertrain-body-setup/ecu_process.py
@@ -11,28 +11,36 @@ from scapy.sendrecv import *
 
 class GenericECU(Process):
     def __init__(self,
-                 socket,  # type: CANSocket
+                 tx_socket,  # type: CANSocket
+                 rx_socket,  # type: CANSocket
                  vehicle_segment: VehicleSegment
                  ):
+        def sniff_function(pkt):
+            print(pkt.__repr__())
         Process.__init__(self)
-        self.socket = socket
+        self.tx_socket = tx_socket
+        self.rx_socket = rx_socket
         self.frames_to_send = [frame for frame in CANFrame if frame.source == vehicle_segment]
         self.name = vehicle_segment.name
 
-        # split frames of this ECU by sending frequency and schedule them on separate cyclic threads
-        tasks = []
         ecu_work_description = f'Work description for {self.name} ECU:\n'
+        tasks = [AsyncSniffer(opened_socket=self.rx_socket, prn=sniff_function)]
+
+        # split frames of this ECU by sending frequency and schedule them on separate cyclic threads
         for freq in Frequency:
             frames_for_freq = list(filter(lambda x: x.interval == freq, self.frames_to_send))
             if not frames_for_freq:
                 continue
-            tasks.append(PeriodicSendingTask(socket=self.socket, frames=frames_for_freq, interval_s=freq.value))
+            tasks.append(PeriodicSendingTask(socket=self.tx_socket, frames=frames_for_freq, interval_s=freq.value))
             ecu_work_description += f' - Created cyclic thread which will send {frames_for_freq} every {freq.value}s.\n'
+
         self.tasks = tasks
+
         print(ecu_work_description)
 
+
     def run(self):
-        print(f'Hello from ECU with segment: {self.name} and socket: {self.socket}.')
+        print(f'Hello from ECU with segment: {self.name} and socket: {self.tx_socket}.')
 
         for t in self.tasks:
             t.start()
diff --git a/chassis-powertrain-body-setup/periodic_send_thread.py b/chassis-powertrain-body-setup/periodic_send_thread.py
index bc230c0..ab435c0 100644
--- a/chassis-powertrain-body-setup/periodic_send_thread.py
+++ b/chassis-powertrain-body-setup/periodic_send_thread.py
@@ -28,7 +28,6 @@ class PeriodicSendingTask(Thread):
         msg_due_time_ns = time.perf_counter_ns()
 
         while not self.stopped:
-            # to be replaced with sending
             send(self.packets, verbose=0, socket=self.socket)
             print(f'Sent {len(self.packets)} packets at {time.time()}, frequency = {self.interval_s}s')
 
-- 
GitLab