Uh oh!
There was an error while loading. Please reload this page.
forked from bluerobotics/ping-python
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpingproxy.py
More file actions
Latest commit
executable file
·113 lines (86 loc) · 3.38 KB
/
Copy pathpingproxy.py
File metadata and controls
executable file
·113 lines (86 loc) · 3.38 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
#!/usr/bin/env python3
# PingProxy.py
# Connect multiple udp clients to a single serial device
frombrpingimportPingParser
importserial
importsocket
importtime
fromcollectionsimportdeque
importerrno
classPingClient(object):
def__init__(self):
## Queued messages received from client
self.rx_msgs=deque([])
## Parser to verify client comms
self.parser=PingParser()
## Digest incoming client data
# @return None
defparse(self, data):
forbinbytearray(data):
ifself.parser.parse_byte(b) ==PingParser.NEW_MESSAGE:
self.rx_msgs.append(self.parser.rx_msg)
## Dequeue a message received from client
# @return None: if there are no comms in the queue
# @return PingMessage: the next ping message in the queue
defdequeue(self):
iflen(self.rx_msgs) ==0:
returnNone
returnself.rx_msgs.popleft()
classPingProxy(object):
def__init__(self, device=None, port=None):
## A serial object for ping device comms
self.device=device
## UDP port number for server
self.port=port
ifself.deviceisNone:
raiseException("A device is required")
ifself.portisNone:
raiseException("A port is required")
## Connected client dictionary
self.clients= {}
## Socket to serve on
self.socket=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.setblocking(False)
self.socket.bind(('0.0.0.0', self.port))
## Run proxy tasks
# @return None
defrun(self):
try:
data, address=self.socket.recvfrom(4096)
# new client
ifaddressnotinself.clients:
self.clients[address] =PingClient()
# digest data coming in from client
self.clients[address].parse(data)
exceptExceptionase:
ifisinstance(e, OSError) ande.errno==errno.EAGAIN:
pass# waiting for data
else:
print("Error reading data", e)
# read ping device
device_data=self.device.read(self.device.in_waiting)
# send ping device data to all clients
ifdevice_data: # don't write empty data
forclientinself.clients:
# print("writing to client", client)
self.socket.sendto(device_data, client)
# send all client comms to ping device
forclientinself.clients:
c=self.clients[client]
msg=c.dequeue()
whilemsgisnotNone:
self.device.write(msg.msg_data)
msg=c.dequeue()
if__name__=='__main__':
importargparse
parser=argparse.ArgumentParser(description="Ping udp proxy server.")
parser.add_argument('--device', action="store", required=True, type=str, help="Ping device serial port.")
parser.add_argument('--baudrate', action="store", type=int, default=115200, help="Ping device baudrate.")
parser.add_argument('--port', action="store", type=int, default=9090, help="Server udp port.")
args=parser.parse_args()
s=serial.Serial(args.device, args.baudrate, exclusive=True)
proxy=PingProxy(s, args.port)
whileTrue:
proxy.run()
time.sleep(0.001)