summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2013-07-31 16:26:07 +0000
committercliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2013-07-31 16:26:07 +0000
commit08cf708dfc2e857dd2d946c16e0a96d18bbe6d18 (patch)
tree3d10b9c50fc231c0a3e9a2a080734513f195e9a0
parentd0f8df1b85a744e55026296c4ea1a8061b93d3a5 (diff)
downloadpyserial-08cf708dfc2e857dd2d946c16e0a96d18bbe6d18.tar.gz
rfc2217: zero polls value (baudrate, data size, stop bits, parity) (Erik Lundh)
git-svn-id: http://svn.code.sf.net/p/pyserial/code/trunk/pyserial@461 f19166aa-fa4f-0410-85c2-fa1106f25c8a
-rw-r--r--CHANGES.txt2
-rw-r--r--serial/rfc2217.py119
2 files changed, 81 insertions, 40 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 1658dea..eebf8d4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -441,6 +441,8 @@ Version 2.7 2012-nn-nn
- Posix: add platform specific method: outWaiting (already pesent for Win32)
- Posix: rename flowControl to setXON to match name on Win32, add
flowControlOut function
+- rfc2217: zero polls value (baudrate, data size, stop bits, parity) (Erik
+ Lundh)
Bugfixes:
diff --git a/serial/rfc2217.py b/serial/rfc2217.py
index 776a210..fa9e07a 100644
--- a/serial/rfc2217.py
+++ b/serial/rfc2217.py
@@ -7,7 +7,7 @@
# protocol to access serial ports over TCP/IP and allows setting the baud rate,
# modem control lines etc.
#
-# (C) 2001-2009 Chris Liechti <cliechti@gmx.net>
+# (C) 2001-2013 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt
# TODO:
@@ -226,7 +226,8 @@ class TelnetOption(object):
"""Manage a single telnet option, keeps track of DO/DONT WILL/WONT."""
def __init__(self, connection, name, option, send_yes, send_no, ack_yes, ack_no, initial_state, activation_callback=None):
- """Init option.
+ """\
+ Initialize option.
:param connection: connection used to transmit answers
:param name: a readable name for debug outputs
:param send_yes: what to send when option is to be enabled.
@@ -289,8 +290,10 @@ class TelnetOption(object):
class TelnetSubnegotiation(object):
- """A object to handle subnegotiation of options. In this case actually
- sub-sub options for RFC 2217. It is used to track com port options."""
+ """\
+ A object to handle subnegotiation of options. In this case actually
+ sub-sub options for RFC 2217. It is used to track com port options.
+ """
def __init__(self, connection, name, option, ack_option=None):
if ack_option is None: ack_option = option
@@ -306,9 +309,11 @@ class TelnetSubnegotiation(object):
return "%s:%s" % (self.name, self.state)
def set(self, value):
- """request a change of the value. a request is sent to the server. if
+ """\
+ request a change of the value. a request is sent to the server. if
the client needs to know if the change is performed he has to check the
- state of this object."""
+ state of this object.
+ """
self.value = value
self.state = REQUESTED
self.connection.rfc2217SendSubnegotiation(self.option, self.value)
@@ -316,8 +321,10 @@ class TelnetSubnegotiation(object):
self.connection.logger.debug("SB Requesting %s -> %r" % (self.name, self.value))
def isReady(self):
- """check if answer from server has been received. when server rejects
- the change, raise a ValueError."""
+ """\
+ check if answer from server has been received. when server rejects
+ the change, raise a ValueError.
+ """
if self.state == REALLY_INACTIVE:
raise ValueError("remote rejected value for option %r" % (self.name))
return self.state == ACTIVE
@@ -325,9 +332,11 @@ class TelnetSubnegotiation(object):
active = property(isReady)
def wait(self, timeout=3):
- """wait until the subnegotiation has been acknowledged or timeout. It
+ """\
+ wait until the subnegotiation has been acknowledged or timeout. It
can also throw a value error when the answer from the server does not
- match the value sent."""
+ match the value sent.
+ """
timeout_time = time.time() + timeout
while time.time() < timeout_time:
time.sleep(0.05) # prevent 100% CPU load
@@ -337,8 +346,10 @@ class TelnetSubnegotiation(object):
raise SerialException("timeout while waiting for option %r" % (self.name))
def checkAnswer(self, suboption):
- """check an incoming subnegotiation block. the parameter already has
- cut off the header like sub option number and com port option value."""
+ """\
+ check an incoming subnegotiation block. the parameter already has
+ cut off the header like sub option number and com port option value.
+ """
if self.value == suboption[:len(self.value)]:
self.state = ACTIVE
else:
@@ -355,8 +366,10 @@ class RFC2217Serial(SerialBase):
9600, 19200, 38400, 57600, 115200)
def open(self):
- """Open port with current settings. This may throw a SerialException
- if the port cannot be opened."""
+ """\
+ Open port with current settings. This may throw a SerialException
+ if the port cannot be opened.
+ """
self.logger = None
self._ignore_set_control_answer = False
self._poll_modem_state = False
@@ -553,9 +566,11 @@ class RFC2217Serial(SerialBase):
return self._read_buffer.qsize()
def read(self, size=1):
- """Read size bytes from the serial port. If a timeout is set it may
+ """\
+ Read size bytes from the serial port. If a timeout is set it may
return less characters as requested. With no timeout it will block
- until the requested number of bytes is read."""
+ until the requested number of bytes is read.
+ """
if not self._isOpen: raise portNotOpenError
data = bytearray()
try:
@@ -568,9 +583,11 @@ class RFC2217Serial(SerialBase):
return bytes(data)
def write(self, data):
- """Output the given string over the serial port. Can block if the
+ """\
+ Output the given string over the serial port. Can block if the
connection is blocked. May raise SerialException if the connection is
- closed."""
+ closed.
+ """
if not self._isOpen: raise portNotOpenError
self._write_lock.acquire()
try:
@@ -591,8 +608,10 @@ class RFC2217Serial(SerialBase):
self._read_buffer.get(False)
def flushOutput(self):
- """Clear output buffer, aborting the current output and
- discarding all that is in the buffer."""
+ """\
+ Clear output buffer, aborting the current output and
+ discarding all that is in the buffer.
+ """
if not self._isOpen: raise portNotOpenError
self.rfc2217SendPurge(PURGE_TRANSMIT_BUFFER)
@@ -605,8 +624,10 @@ class RFC2217Serial(SerialBase):
self.setBreak(False)
def setBreak(self, level=True):
- """Set break: Controls TXD. When active, to transmitting is
- possible."""
+ """\
+ Set break: Controls TXD. When active, to transmitting is
+ possible.
+ """
if not self._isOpen: raise portNotOpenError
if self.logger:
self.logger.info('set BREAK to %s' % ('inactive', 'active')[bool(level)])
@@ -818,16 +839,20 @@ class RFC2217Serial(SerialBase):
item.wait(self._network_timeout) # wait for acknowledge from the server
def rfc2217FlowServerReady(self):
- """check if server is ready to receive data. block for some time when
- not."""
+ """\
+ check if server is ready to receive data. block for some time when
+ not.
+ """
#~ if self._remote_suspend_flow:
#~ wait---
def getModemState(self):
- """get last modem state (cached value. if value is "old", request a new
+ """\
+ get last modem state (cached value. if value is "old", request a new
one. this cache helps that we don't issue to many requests when e.g. all
status lines, one after the other is queried by te user (getCTS, getDSR
- etc.)"""
+ etc.)
+ """
# active modem state polling enabled? is the value fresh enough?
if self._poll_modem_state and self._modemstate_expires < time.time():
if self.logger:
@@ -875,9 +900,11 @@ else:
# The following is code that helps implementing an RFC 2217 server.
class PortManager(object):
- """This class manages the state of Telnet and RFC 2217. It needs a serial
+ """\
+ This class manages the state of Telnet and RFC 2217. It needs a serial
instance and a connection to work with. Connection is expected to implement
- a (thread safe) write function, that writes the string to the network."""
+ a (thread safe) write function, that writes the string to the network.
+ """
def __init__(self, serial_port, connection, logger=None):
self.serial = serial_port
@@ -915,10 +942,12 @@ class PortManager(object):
# issue 1st modem state notification
def _client_ok(self):
- """callback of telnet option. it gets called when option is activated.
+ """\
+ callback of telnet option. it gets called when option is activated.
this one here is used to detect when the client agrees on RFC 2217. a
flag is set so that other functions like check_modem_lines know if the
- client is ok."""
+ client is ok.
+ """
# The callback is used for we and they so if one party agrees, we're
# already happy. it seems not all servers do the negotiation correctly
# and i guess there are incorrect clients too.. so be happy if client
@@ -979,7 +1008,8 @@ class PortManager(object):
# - outgoing data escaping
def escape(self, data):
- """this generator function is for the user. all outgoing data has to be
+ """\
+ this generator function is for the user. all outgoing data has to be
properly escaped, so that no IAC character in the data stream messes up
the Telnet state machine in the server.
@@ -995,7 +1025,8 @@ class PortManager(object):
# - incoming data filter
def filter(self, data):
- """handle a bunch of incoming bytes. this is a generator. it will yield
+ """\
+ handle a bunch of incoming bytes. this is a generator. it will yield
all characters not of interest for Telnet/RFC 2217.
The idea is that the reader thread pushes data from the socket through
@@ -1086,38 +1117,44 @@ class PortManager(object):
if suboption[1:2] == SET_BAUDRATE:
backup = self.serial.baudrate
try:
- (self.serial.baudrate,) = struct.unpack("!I", suboption[2:6])
+ (baudrate,) = struct.unpack("!I", suboption[2:6])
+ if baudrate != 0:
+ self.serial.baudrate = baudrate
except ValueError, e:
if self.logger:
self.logger.error("failed to set baud rate: %s" % (e,))
self.serial.baudrate = backup
else:
if self.logger:
- self.logger.info("changed baud rate: %s" % (self.serial.baudrate,))
+ self.logger.info("%s baud rate: %s" % (baudrate and 'set' or 'get', self.serial.baudrate))
self.rfc2217SendSubnegotiation(SERVER_SET_BAUDRATE, struct.pack("!I", self.serial.baudrate))
elif suboption[1:2] == SET_DATASIZE:
backup = self.serial.bytesize
try:
- (self.serial.bytesize,) = struct.unpack("!B", suboption[2:3])
+ (datasize,) = struct.unpack("!B", suboption[2:3])
+ if datasize != 0:
+ self.serial.bytesize = datasize
except ValueError, e:
if self.logger:
self.logger.error("failed to set data size: %s" % (e,))
self.serial.bytesize = backup
else:
if self.logger:
- self.logger.info("changed data size: %s" % (self.serial.bytesize,))
+ self.logger.info("%s data size: %s" % (datasize and 'set' or 'get', self.serial.bytesize))
self.rfc2217SendSubnegotiation(SERVER_SET_DATASIZE, struct.pack("!B", self.serial.bytesize))
elif suboption[1:2] == SET_PARITY:
backup = self.serial.parity
try:
- self.serial.parity = RFC2217_REVERSE_PARITY_MAP[struct.unpack("!B", suboption[2:3])[0]]
+ parity = struct.unpack("!B", suboption[2:3])[0]
+ if parity != 0:
+ self.serial.parity = RFC2217_REVERSE_PARITY_MAP[parity]
except ValueError, e:
if self.logger:
self.logger.error("failed to set parity: %s" % (e,))
self.serial.parity = backup
else:
if self.logger:
- self.logger.info("changed parity: %s" % (self.serial.parity,))
+ self.logger.info("%s parity: %s" % (parity and 'set' or 'get', self.serial.parity))
self.rfc2217SendSubnegotiation(
SERVER_SET_PARITY,
struct.pack("!B", RFC2217_PARITY_MAP[self.serial.parity])
@@ -1125,14 +1162,16 @@ class PortManager(object):
elif suboption[1:2] == SET_STOPSIZE:
backup = self.serial.stopbits
try:
- self.serial.stopbits = RFC2217_REVERSE_STOPBIT_MAP[struct.unpack("!B", suboption[2:3])[0]]
+ stopbits = struct.unpack("!B", suboption[2:3])[0]
+ if stopbits != 0:
+ self.serial.stopbits = RFC2217_REVERSE_STOPBIT_MAP[stopbits]
except ValueError, e:
if self.logger:
self.logger.error("failed to set stop bits: %s" % (e,))
self.serial.stopbits = backup
else:
if self.logger:
- self.logger.info("changed stop bits: %s" % (self.serial.stopbits,))
+ self.logger.info("%s stop bits: %s" % (stopbits and 'set' or 'get', self.serial.stopbits))
self.rfc2217SendSubnegotiation(
SERVER_SET_STOPSIZE,
struct.pack("!B", RFC2217_STOPBIT_MAP[self.serial.stopbits])