From d71717be3d799849348839bbf71d280cdd22c9ef Mon Sep 17 00:00:00 2001 From: cliechti Date: Wed, 5 Aug 2009 13:23:43 +0000 Subject: - move to_bytes from rfc2217 module to core - add data escape function in rfc2217.PortManager (also renamed class) - use escaping for outgoing data in example - multi port TCP/IP serial gateway extended with RFC 2217 support git-svn-id: http://svn.code.sf.net/p/pyserial/code/trunk/pyserial@297 f19166aa-fa4f-0410-85c2-fa1106f25c8a --- examples/port_publisher.py | 28 +++++++++++++++++++++++++--- examples/tcp_serial_redirect.py | 5 ++++- 2 files changed, 29 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/port_publisher.py b/examples/port_publisher.py index e695a98..1d50774 100644 --- a/examples/port_publisher.py +++ b/examples/port_publisher.py @@ -1,6 +1,7 @@ #! /usr/bin/env python """\ Multi-port serial<->TCP/IP forwarder. +- RFC 2217 - check existence of serial port periodically - start/stop forwarders - each forwarder creates a server socket and opens the serial port @@ -9,10 +10,13 @@ Multi-port serial<->TCP/IP forwarder. - only one client per connection """ import sys, os, time +import traceback import socket import select + import serial -import traceback +import serial.rfc2217 + import avahi import dbus @@ -69,7 +73,10 @@ class ZeroconfService: class Forwarder(ZeroconfService): """\ Single port serial<->TCP/IP forarder that depends on an external select - loop. Zeroconf publish/unpublish on open/close. + loop. + - Buffers for serial -> network and network -> serial + - RFC 2217 state + - Zeroconf publish/unpublish on open/close. """ def __init__(self, device, name, network_port, on_close=None): @@ -84,6 +91,7 @@ class Forwarder(ZeroconfService): self.serial.timeout = 0 self.socket = None self.server_socket = None + self.rfc2217 = None # instantiate later, when connecting def __del__(self): try: @@ -145,6 +153,11 @@ class Forwarder(ZeroconfService): self.on_close = None callback(self) + def write(self, data): + """the write method is used by serial.rfc2217.PortManager. it has to + write to the network.""" + self.buffer_ser2net += data + def update_select_maps(self, read_map, write_map, error_map): """Update dictionaries for select call. insert fd->callback mapping""" if self.alive: @@ -180,6 +193,9 @@ class Forwarder(ZeroconfService): if data: # store data in buffer if there is a client connected if self.socket is not None: + # escape outgoing data when needed (Telnet IAC (0xff) character) + if self.rfc2217: + data = serial.to_bytes(self.rfc2217.escape(data)) self.buffer_ser2net += data else: self.handle_serial_error() @@ -207,6 +223,9 @@ class Forwarder(ZeroconfService): # read a chunk from the serial port data = self.socket.recv(1024) if data: + # Process RFC 2217 stuff when enabled + if self.rfc2217: + data = serial.to_bytes(self.rfc2217.filter(data)) # add data to buffer self.buffer_net2ser += data else: @@ -239,6 +258,7 @@ class Forwarder(ZeroconfService): self.socket.setblocking(0) if not options.quiet: print '%s: Connected by %s:%s' % (self.device, addr[0], addr[1]) + self.rfc2217 = serial.rfc2217.PortManager(self.serial, self, debug_output=False) else: # reject connection if there is already one connection.close() @@ -251,6 +271,8 @@ class Forwarder(ZeroconfService): def handle_disconnect(self): """Socket gets disconnected""" + # stop RFC 2217 state machine + self.rfc2217 = None # clear send buffer self.buffer_ser2net = '' # close network connection @@ -275,7 +297,7 @@ if __name__ == '__main__': %prog [options] Announce the existence of devices using zeroconf and provide -a TCP/IP <-> serial port gateway. +a TCP/IP <-> serial port gateway (implements RFC 2217). Note that the TCP/IP server is not protected. Everyone can connect to it! diff --git a/examples/tcp_serial_redirect.py b/examples/tcp_serial_redirect.py index 896e0a0..7b371b2 100644 --- a/examples/tcp_serial_redirect.py +++ b/examples/tcp_serial_redirect.py @@ -69,6 +69,9 @@ class Redirector: # do the newline conversion # XXX fails for CR+LF in input when it is cut in half at the begin or end of the string data = net_newline.join(data.split(ser_newline)) + # escape outgoing data when needed (Telnet IAC (0xff) character) + if self.rfc2217: + data = serial.to_bytes(self.rfc2217.escape(data)) self._write_lock.acquire() try: self.socket.sendall(data) # send it over TCP @@ -96,7 +99,7 @@ class Redirector: if not data: break if self.rfc2217: - data = ''.join(self.rfc2217.filter(data)) + data = serial.to_bytes(self.rfc2217.filter(data)) if self.ser_newline and self.net_newline: # do the newline conversion # XXX fails for CR+LF in input when it is cut in half at the begin or end of the string -- cgit v1.2.1