-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEthernetServer.py
More file actions
173 lines (125 loc) · 5.07 KB
/
Copy pathEthernetServer.py
File metadata and controls
173 lines (125 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
'''
Ethernet Handler Module
Subsribe Topics:
can.send
Publish Topics:
Ethernet.log
'''
from ModuleBase import Module
from ModuleBase import ModuleManager
from pubsub import pub
import socket
import struct
import time
import psutil
class EthernetHandler(Module):
def __init__(self):
super().__init__()
pub.subscribe(self.message_listener, "ethernet.send")
self.conn = None
self.addr = None
self.connected = False
self.PORT = 226
if not self.check_process():
raise Exception("USB Port is in use, please close any other programs using this port and restart the program \
Please use this command to check what program is using this port: netstat -ano | findstr :<port_number>")
self.init_socket()
# checks if any process is using PORT
def check_process(self):
for proc in psutil.process_iter(['pid', 'name', 'connections']):
for conn in proc.info['connections']:
if conn.laddr.port == self.PORT:
return False
return True
# initializes socket
def init_socket(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(("", self.PORT))
self.socket.listen()
# waits for client connection
def wait_for_client(self):
if not self.socket:
self.init_socket()
self.conn, self.addr = self.socket.accept()
self.connected = True
print(f"Connected to {self.addr}")
# callback function for "ethernet.send" pubsub channel
def message_listener(self, message):
# constructing data_byte struct
# if message is CAN: START, length of data, "CAN", data
if message["type"] == "CAN":
START = "X".encode()
type = "CAN".encode()
data = [message["address"]] + message["data"]
format_string = f"1s1B3s{len(data)}B"
data_bytes = struct.pack(format_string, START, len(data), type, *data)
elif message["type"] == "TST":
START = "X".encode()
type = "TST".encode()
start_time = time.time()
time_byte = struct.pack("d", start_time)
data_bytes = struct.pack("1s1B3s", START, len(time_byte), type)
data_bytes = data_bytes + time_byte
# else type is LID, SON, IMU
else:
pass
# send
if self.connected:
try:
self.conn.sendall(data_bytes)
except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError):
print(f"Disconnect from {self.addr}")
self.connected = False
self.socket.close()
self.wait_for_client()
def run(self):
# receive
if self.connected:
try:
data_receive = self.conn.recv(5)
if data_receive:
data = struct.unpack(f"1s1B3s", data_receive)
if data[0].decode() == "X":
frame_length = data[1]
type = data[2].decode()
else:
frame_length = 0
else:
frame_length = 0
data_frame = self.conn.recv(frame_length)
if data_frame:
if type == "CAN":
data = struct.unpack(f"{frame_length}B", data_frame)
address, data = data[0], data[1:]
pub.sendMessage("can.receive", message = {"address": address, "data": data})
elif type == "TST":
data = struct.unpack("d", data_frame)
time_rec = data[0]
print((time.time() - time_rec))
else: # LID, SON, IMU
pass
except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError):
print(f"Disconnect from {self.addr}")
self.connected = False
self.socket.close()
self.socket = None
self.wait_for_client()
else:
self.wait_for_client()
class TestEthernetHandler(Module):
def __init__(self):
super().__init__()
def run(self):
pub.sendMessage("ethernet.send", message = {"type": "TST", "address": 0x15, "data": [0x20, 0x10, 0x00]})
if __name__ == "__main__":
from USBCameraServer import USBCameraHandler, USBCameraDisplay
EthernetHandler = EthernetHandler()
TestEthernetHandler = TestEthernetHandler()
USBCameraHandler = USBCameraHandler()
USBCameraDisplay = USBCameraDisplay()
EthernetHandler.start(200)
TestEthernetHandler.start(100)
USBCameraHandler.start(80)
USBCameraDisplay.start(1)