-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathguri.py
More file actions
156 lines (128 loc) · 4.39 KB
/
Copy pathguri.py
File metadata and controls
156 lines (128 loc) · 4.39 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
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
from serial.serialutil import SerialException
from twisted.internet.protocol import Protocol, ReconnectingClientFactory
from twisted.python import log
import sys
log.startLogging(sys.stdout)
client_list = []
device_list = []
recv_ack = True
class SerialClient(Protocol):
def __init__(self, network, options):
self.options = options
self.network = network
self.buf = ""
self.timeout = 0.09
self.timer = reactor.callLater(self.timeout, self.flushBuf)
def connectionFailed(self):
if self.options.verbose >= 2:
log.err("-- connection to serial device failed ---")
reactor.stop()
def connectionMade(self):
if self.options.verbose >= 2:
log.msg("-- connected to serial device ---")
device_list.append(self)
def dataReceived(self, data):
if not self.timer.active():
self.timer = reactor.callLater(self.timeout, self.flushBuf)
self.buf += data
def flushBuf(self):
if "" != self.buf:
if not self.network.connected:
log.err("!! received data, but not connected to TCP/IP endpoint")
else:
if options.verbose >= 1:
log.msg(">> data: ", " ".join([hex(ord(c))[2:].zfill(2) for c in self.buf]))
recv_ack = False
self.network.notifyAll(self.buf)
reactor.callLater(1, self.checkRecvACK, [self.buf])
self.buf = ""
def checkRecvACK(self, buf):
if not recv_ack:
reactor.stop()
self.network.notifyAll(buf)
class NetworkClient(Protocol):
options = None
def connectionMade(self):
if self.options.verbose >= 2:
log.msg("-- tcp client connected")
client_list.append(self)
def dataReceived(self, data):
if options.verbose >= 1:
log.msg("<< data:", " ".join([hex(ord(c))[2:].zfill(2) for c in data]))
for com in device_list:
if 6 == ord(data[0]):
recv_ack = True
com.transport.write(data)
def connectionLost(self, reason):
if self.options.verbose >= 2:
log.err("-- tcp client disconnected (%s)" % reason.value)
if self in client_list:
client_list.remove(self)
def notifyClient(self, data):
self.transport.write(data)
class NetworkClientFactory(ReconnectingClientFactory):
protocol = NetworkClient
def __init__(self, options):
self.options = options
self.connected = False
client_list = []
def buildProtocol(self, addr):
self.connected = True
self.resetDelay()
proto = self.protocol()
proto.options = self.options
return proto
def clientConnectionFailed(self, connector, reason):
self.connected = False
if self.options.verbose >= 2:
log.err("-- tcp connection failed (%s) ---\n" % (reason.value))
ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
def clientConnectionLost(self, connector, reason):
self.connected = False
if self.options.verbose >= 2:
log.err("-- tcp connection lost (%s) ---\n" % (reason.value))
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
def notifyAll(self, data):
for socket in client_list:
socket.transport.write(data)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
prog = 'Guri connector',
description = 'TTY to TCP/IP redirection',
add_help = True)
parser.add_argument('device',
metavar = '<device>',
help = 'The serial device to communicate with')
parser.add_argument('host',
metavar = '<remote-host>',
help = 'Remote host to connect to')
parser.add_argument('--port', '-p',
metavar = '<port>',
default = 7001,
type = int,
dest = 'port',
help = 'Remote port')
parser.add_argument('--baudrate', '-r',
dest = 'baudrate',
type = int,
help = "Set baudrate, defaults to %(default)s",
default = 19200,
metavar = '<rate>')
parser.add_argument('--verbose', '-v',
action = 'count',
help = 'Increase verbosity. Default is only show errors, -v show messages from downstream, -vv shows upstream/downstream -vvv adds a timestamp')
parser.add_argument('--version', '-V', action='version', version='%(prog)s 1.0')
options = parser.parse_args()
factory = NetworkClientFactory(options)
factory.noisy = True if options.verbose >= 3 else False
reactor.connectTCP(options.host, options.port, factory)
try:
SerialPort(SerialClient(factory, options), options.device, reactor, baudrate=options.baudrate)
reactor.run()
except SerialException, e:
log.err("Could not open serial device %s" % options.device)
log.err("Error: %s" % e)
sys.exit(1)