3
#(C)2002-2003 Chris Liechti <cliechti@gmx.net>
4
#redirect data from a TCP/IP connection to a serial port and vice versa
5
#requires Python 2.2 'cause socket.sendall is used
7
"""USAGE: tcp_serial_redirect.py [options]
8
Simple Serial to Network (TCP/IP) redirector.
11
-p, --port=PORT serial port, a number, defualt = 0 or a device name
12
-b, --baud=BAUD baudrate, default 9600
13
-r, --rtscts enable RTS/CTS flow control (default off)
14
-x, --xonxoff enable software flow control (default off)
15
-P, --localport TCP/IP port on which to run the server (default 7777)
17
Note: no security measures are implemeted. Anyone can remotely connect
18
to this service over the network.
19
Only one connection at once is supported. If the connection is terminaed
20
it waits for the next connect.
23
import sys, os, serial, threading, getopt, socket
32
def __init__(self, serial, socket):
37
"""connect the serial port to the tcp port by copying everything
38
from one side to the other"""
40
self.thread_read = threading.Thread(target=self.reader)
41
self.thread_read.setDaemon(1)
42
self.thread_read.start()
46
"""loop forever and copy serial->socket"""
49
data = self.serial.read(1) #read one, blocking
50
n = self.serial.inWaiting() #look if there is more
52
data = data + self.serial.read(n) #and get as much as possible
54
self.socket.sendall(data) #send it over TCP
55
except socket.error, msg:
57
#probably got disconnected
62
"""loop forever and copy socket->serial"""
65
data = self.socket.recv(1024)
68
self.serial.write(data) #get a bunch of bytes and send them
69
except socket.error, msg:
71
#probably got disconnected
74
self.thread_read.join()
80
self.thread_read.join()
82
if __name__ == '__main__':
85
#parse command line options
87
opts, args = getopt.getopt(sys.argv[1:],
89
["help", "port=", "baud=", "rtscts", "xonxoff", "localport="])
90
except getopt.GetoptError:
91
# print help information and exit:
92
print >>sys.stderr, __doc__
99
ser.timeout = 1 #required so that the reader thread can exit
103
if o in ("-h", "--help"): #help text
106
elif o in ("-p", "--port"): #specified port
111
elif o in ("-b", "--baud"): #specified baudrate
113
ser.baudrate = int(a)
115
raise ValueError, "Baudrate must be a integer number"
116
elif o in ("-r", "--rtscts"):
118
elif o in ("-x", "--xonxoff"):
120
elif o in ("-P", "--localport"):
124
raise ValueError, "Local port must be an integer number"
126
print "--- TCP/IP to Serial redirector --- type Ctrl-C / BREAK to quit"
130
except serial.SerialException, e:
131
print "Could not open serial port %s: %s" % (ser.portstr, e)
134
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
135
srv.bind( ('', localport) )
139
print "Waiting for connection..."
140
connection, addr = srv.accept()
141
print 'Connected by', addr
142
#enter console->serial loop
143
r = Redirector(ser, connection)
147
except socket.error, msg:
150
print "\n--- exit ---"
3
# (C) 2002-2006 Chris Liechti <cliechti@gmx.net>
4
# redirect data from a TCP/IP connection to a serial port and vice versa
5
# requires Python 2.2 'cause socket.sendall is used
8
import sys, os, serial, threading, socket
17
def __init__(self, serial, socket):
22
"""connect the serial port to the tcp port by copying everything
23
from one side to the other"""
25
self.thread_read = threading.Thread(target=self.reader)
26
self.thread_read.setDaemon(1)
27
self.thread_read.start()
31
"""loop forever and copy serial->socket"""
34
data = self.serial.read(1) #read one, blocking
35
n = self.serial.inWaiting() #look if there is more
37
data = data + self.serial.read(n) #and get as much as possible
39
self.socket.sendall(data) #send it over TCP
40
except socket.error, msg:
42
#probably got disconnected
47
"""loop forever and copy socket->serial"""
50
data = self.socket.recv(1024)
53
self.serial.write(data) #get a bunch of bytes and send them
54
except socket.error, msg:
56
#probably got disconnected
59
self.thread_read.join()
65
self.thread_read.join()
68
if __name__ == '__main__':
71
parser = optparse.OptionParser(usage="""\
72
%prog [options] [port [baudrate]]
73
Simple Serial to Network (TCP/IP) redirector.
75
Note: no security measures are implemeted. Anyone can remotely connect
76
to this service over the network.
77
Only one connection at once is supported. When the connection is terminated
78
it waits for the next connect.
80
parser.add_option("-p", "--port", dest="port",
81
help="port, a number (default 0) or a device name (deprecated option)",
84
parser.add_option("-b", "--baud", dest="baudrate", action="store", type='int',
85
help="set baudrate, default 9600", default=9600)
87
parser.add_option("", "--parity", dest="parity", action="store",
88
help="set parity, one of [N, E, O], default=N", default='N')
90
parser.add_option("", "--rtscts", dest="rtscts", action="store_true",
91
help="enable RTS/CTS flow control (default off)", default=False)
93
parser.add_option("", "--xonxoff", dest="xonxoff", action="store_true",
94
help="enable software flow control (default off)", default=False)
96
parser.add_option("", "--cr", dest="cr", action="store_true",
97
help="do not send CR+LF, send CR only", default=False)
99
parser.add_option("", "--lf", dest="lf", action="store_true",
100
help="do not send CR+LF, send LF only", default=False)
102
parser.add_option("", "--rts", dest="rts_state", action="store", type='int',
103
help="set initial RTS line state (possible values: 0, 1)", default=None)
105
parser.add_option("", "--dtr", dest="dtr_state", action="store", type='int',
106
help="set initial DTR line state (possible values: 0, 1)", default=None)
108
parser.add_option("-q", "--quiet", dest="quiet", action="store_true",
109
help="suppress non error messages", default=False)
111
parser.add_option("-P", "--localport", dest="local_port", action="store", type='int',
112
help="local TCP port", default=7777)
115
(options, args) = parser.parse_args()
118
baudrate = options.baudrate
120
if options.port is not None:
121
parser.error("no arguments are allowed, options only when --port is given")
125
baudrate = int(args[0])
127
parser.error("baudrate must be a number, not %r" % args[0])
130
parser.error("too many arguments")
132
if port is None: port = 0
134
if options.cr and options.lf:
135
parser.error("ony one of --cr or --lf can be specified")
137
ser = serial.Serial()
139
ser.baudrate = baudrate
140
ser.rtscts = options.rtscts
141
ser.xonxoff = options.xonxoff
142
ser.timeout = 1 #required so that the reader thread can exit
144
if not options.quiet:
145
print "--- TCP/IP to Serial redirector --- type Ctrl-C / BREAK to quit"
146
print "--- %s %s,%s,%s,%s ---" % (ser.portstr, ser.baudrate, 8, ser.parity, 1)
150
except serial.SerialException, e:
151
print "Could not open serial port %s: %s" % (ser.portstr, e)
154
if options.rts_state is not None:
155
ser.setRTS(options.rts_state)
157
if options.dtr_state is not None:
158
ser.setDTR(options.dtr_state)
160
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
161
srv.bind( ('', options.local_port) )
165
print "Waiting for connection on %s..." % options.local_port
166
connection, addr = srv.accept()
167
print 'Connected by', addr
168
#enter console->serial loop
169
r = Redirector(ser, connection)
173
except socket.error, msg:
176
print "\n--- exit ---"