| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 | |
| 5 """ | |
| 6 Serial port support for Windows. | |
| 7 | |
| 8 Requires PySerial and win32all, and needs to be used with win32event | |
| 9 reactor. | |
| 10 """ | |
| 11 | |
| 12 # system imports | |
| 13 import os | |
| 14 import serial | |
| 15 from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD | |
| 16 from serial import STOPBITS_ONE, STOPBITS_TWO | |
| 17 from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS | |
| 18 import win32file, win32event | |
| 19 | |
| 20 # twisted imports | |
| 21 from twisted.protocols import basic | |
| 22 from twisted.internet import abstract | |
| 23 from twisted.python import log | |
| 24 | |
| 25 # sibling imports | |
| 26 from serialport import BaseSerialPort | |
| 27 | |
| 28 | |
| 29 class SerialPort(BaseSerialPort, abstract.FileDescriptor): | |
| 30 """A select()able serial device, acting as a transport.""" | |
| 31 | |
| 32 connected = 1 | |
| 33 | |
| 34 def __init__(self, protocol, deviceNameOrPortNumber, reactor, | |
| 35 baudrate = 9600, bytesize = EIGHTBITS, parity = PARITY_NONE, | |
| 36 stopbits = STOPBITS_ONE, xonxoff = 0, rtscts = 0): | |
| 37 self._serial = serial.Serial(deviceNameOrPortNumber, baudrate=baudrate, | |
| 38 bytesize=bytesize, parity=parity, | |
| 39 stopbits=stopbits, timeout=None, | |
| 40 xonxoff=xonxoff, rtscts=rtscts) | |
| 41 self.flushInput() | |
| 42 self.flushOutput() | |
| 43 self.reactor = reactor | |
| 44 self.protocol = protocol | |
| 45 self.outQueue = [] | |
| 46 self.closed = 0 | |
| 47 self.closedNotifies = 0 | |
| 48 self.writeInProgress = 0 | |
| 49 | |
| 50 self.protocol = protocol | |
| 51 self._overlappedRead = win32file.OVERLAPPED() | |
| 52 self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None) | |
| 53 self._overlappedWrite = win32file.OVERLAPPED() | |
| 54 self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None) | |
| 55 | |
| 56 self.reactor.addEvent(self._overlappedRead.hEvent, self, 'serialReadEven
t') | |
| 57 self.reactor.addEvent(self._overlappedWrite.hEvent, self, 'serialWriteEv
ent') | |
| 58 | |
| 59 self.protocol.makeConnection(self) | |
| 60 | |
| 61 flags, comstat = win32file.ClearCommError(self._serial.hComPort) | |
| 62 rc, self.read_buf = win32file.ReadFile(self._serial.hComPort, | |
| 63 win32file.AllocateReadBuffer(1), | |
| 64 self._overlappedRead) | |
| 65 | |
| 66 def serialReadEvent(self): | |
| 67 #get that character we set up | |
| 68 n = win32file.GetOverlappedResult(self._serial.hComPort, self._overlappe
dRead, 0) | |
| 69 if n: | |
| 70 first = str(self.read_buf[:n]) | |
| 71 #now we should get everything that is already in the buffer | |
| 72 flags, comstat = win32file.ClearCommError(self._serial.hComPort) | |
| 73 if comstat.cbInQue: | |
| 74 win32event.ResetEvent(self._overlappedRead.hEvent) | |
| 75 rc, buf = win32file.ReadFile(self._serial.hComPort, | |
| 76 win32file.AllocateReadBuffer(comsta
t.cbInQue), | |
| 77 self._overlappedRead) | |
| 78 n = win32file.GetOverlappedResult(self._serial.hComPort, self._o
verlappedRead, 1) | |
| 79 #handle all the received data: | |
| 80 self.protocol.dataReceived(first + str(buf[:n])) | |
| 81 else: | |
| 82 #handle all the received data: | |
| 83 self.protocol.dataReceived(first) | |
| 84 | |
| 85 #set up next one | |
| 86 win32event.ResetEvent(self._overlappedRead.hEvent) | |
| 87 rc, self.read_buf = win32file.ReadFile(self._serial.hComPort, | |
| 88 win32file.AllocateReadBuffer(1), | |
| 89 self._overlappedRead) | |
| 90 | |
| 91 def write(self, data): | |
| 92 if data: | |
| 93 if self.writeInProgress: | |
| 94 self.outQueue.append(data) | |
| 95 else: | |
| 96 self.writeInProgress = 1 | |
| 97 win32file.WriteFile(self._serial.hComPort, data, self._overlappe
dWrite) | |
| 98 | |
| 99 def serialWriteEvent(self): | |
| 100 try: | |
| 101 dataToWrite = self.outQueue.pop(0) | |
| 102 except IndexError: | |
| 103 self.writeInProgress = 0 | |
| 104 return | |
| 105 else: | |
| 106 win32file.WriteFile(self._serial.hComPort, dataToWrite, self._overla
ppedWrite) | |
| 107 | |
| 108 def connectionLost(self, reason): | |
| 109 self.reactor.removeEvent(self._overlappedRead.hEvent) | |
| 110 self.reactor.removeEvent(self._overlappedWrite.hEvent) | |
| 111 abstract.FileDescriptor.connectionLost(self, reason) | |
| 112 self._serial.close() | |
| OLD | NEW |