root / trunk / twisted / internet / _win32serialport.py

Revision 14918, 4.3 kB (checked in by glyph, 4 years ago)

Moving twisted.internet.serialport up one level, removing sibling imports, as per JML's urging.

Line 
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, 'serialReadEvent')
57         self.reactor.addEvent(self._overlappedWrite.hEvent, self, 'serialWriteEvent')
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._overlappedRead, 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(comstat.cbInQue),
77                                              self._overlappedRead)
78                 n = win32file.GetOverlappedResult(self._serial.hComPort, self._overlappedRead, 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._overlappedWrite)
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._overlappedWrite)
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()
Note: See TracBrowser for help on using the browser.