comparison deps/Platinum/ThirdParty/Neptune/Source/System/Win32/NptWin32SerialPort.cpp @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
1 /*****************************************************************
2 |
3 | Neptune - Serial Ports :: Win32 Implementation
4 |
5 | (c) 2001-2007 Gilles Boccon-Gibod
6 | Author: Gilles Boccon-Gibod (bok@bok.net)
7 |
8 ****************************************************************/
9
10 /*----------------------------------------------------------------------
11 | includes
12 +---------------------------------------------------------------------*/
13 #include <windows.h>
14
15 #include "NptUtils.h"
16 #include "NptSerialPort.h"
17 #include "NptStrings.h"
18 #include "NptLogging.h"
19
20 /*----------------------------------------------------------------------
21 | NPT_Win32HandletWrapper
22 +---------------------------------------------------------------------*/
23 class NPT_Win32HandleWrapper
24 {
25 public:
26 // constructors and destructor
27 NPT_Win32HandleWrapper(HANDLE handle) : m_Handle(handle) {}
28 ~NPT_Win32HandleWrapper() {
29 CloseHandle(m_Handle);
30 }
31
32 // methods
33 HANDLE GetHandle() { return m_Handle; }
34
35 private:
36 // members
37 HANDLE m_Handle;
38 };
39
40 typedef NPT_Reference<NPT_Win32HandleWrapper> NPT_Win32HandleReference;
41
42 /*----------------------------------------------------------------------
43 | NPT_Win32SerialPortStream
44 +---------------------------------------------------------------------*/
45 class NPT_Win32SerialPortStream
46 {
47 public:
48 // constructors and destructor
49 NPT_Win32SerialPortStream(NPT_Win32HandleReference handle) :
50 m_HandleReference(handle) {}
51
52 protected:
53 // constructors and destructors
54 virtual ~NPT_Win32SerialPortStream() {}
55
56 // members
57 NPT_Win32HandleReference m_HandleReference;
58 };
59
60 /*----------------------------------------------------------------------
61 | NPT_Win32SerialPortInputStream
62 +---------------------------------------------------------------------*/
63 class NPT_Win32SerialPortInputStream : public NPT_InputStream,
64 private NPT_Win32SerialPortStream
65
66 {
67 public:
68 // constructors and destructor
69 NPT_Win32SerialPortInputStream(NPT_Win32HandleReference& handle) :
70 NPT_Win32SerialPortStream(handle) {}
71
72 // NPT_InputStream methods
73 NPT_Result Read(void* buffer,
74 NPT_Size bytes_to_read,
75 NPT_Size* bytes_read);
76 NPT_Result Seek(NPT_Position /* offset */) {
77 return NPT_ERROR_NOT_SUPPORTED;
78 }
79 NPT_Result Tell(NPT_Position& /* offset */) {
80 return NPT_ERROR_NOT_SUPPORTED;
81 }
82 NPT_Result GetSize(NPT_LargeSize& /* size */) {
83 return NPT_ERROR_NOT_SUPPORTED;
84 }
85 NPT_Result GetAvailable(NPT_LargeSize& /* available */) {
86 return NPT_ERROR_NOT_SUPPORTED;
87 }
88 };
89
90 /*----------------------------------------------------------------------
91 | NPT_Win32SerialPortInputStream::Read
92 +---------------------------------------------------------------------*/
93 NPT_Result
94 NPT_Win32SerialPortInputStream::Read(void* buffer,
95 NPT_Size bytes_to_read,
96 NPT_Size* bytes_read)
97 {
98 DWORD nb_read = 0;
99 BOOL result = ReadFile(m_HandleReference->GetHandle(),
100 buffer,
101 bytes_to_read,
102 &nb_read,
103 NULL);
104 if (result == TRUE) {
105 if (bytes_read) *bytes_read = nb_read;
106 return NPT_SUCCESS;
107 } else {
108 if (bytes_read) *bytes_read = 0;
109 return NPT_FAILURE;
110 }
111 }
112
113 /*----------------------------------------------------------------------
114 | NPT_Win32SerialPortOutputStream
115 +---------------------------------------------------------------------*/
116 class NPT_Win32SerialPortOutputStream : public NPT_OutputStream,
117 private NPT_Win32SerialPortStream
118 {
119 public:
120 // constructors and destructor
121 NPT_Win32SerialPortOutputStream(NPT_Win32HandleReference& handle) :
122 NPT_Win32SerialPortStream(handle) {}
123
124 // NPT_InputStream methods
125 NPT_Result Write(const void* buffer,
126 NPT_Size bytes_to_write,
127 NPT_Size* bytes_written);
128 NPT_Result Seek(NPT_Position /* offset */) {
129 return NPT_ERROR_NOT_SUPPORTED;
130 }
131 NPT_Result Tell(NPT_Position& /* offset */) {
132 return NPT_ERROR_NOT_SUPPORTED;
133 }
134 };
135
136 /*----------------------------------------------------------------------
137 | NPT_Win32SerialPortOutputStream::Write
138 +---------------------------------------------------------------------*/
139 NPT_Result
140 NPT_Win32SerialPortOutputStream::Write(const void* buffer,
141 NPT_Size bytes_to_write,
142 NPT_Size* bytes_written)
143 {
144 DWORD nb_written = 0;
145
146 BOOL result = WriteFile(m_HandleReference->GetHandle(),
147 buffer,
148 bytes_to_write,
149 &nb_written,
150 NULL);
151 if (result == TRUE) {
152 if (bytes_written) *bytes_written = nb_written;
153 return NPT_SUCCESS;
154 } else {
155 if (bytes_written) *bytes_written = 0;
156 return NPT_FAILURE;
157 }
158 }
159
160 /*----------------------------------------------------------------------
161 | NPT_Win32SerialPort
162 +---------------------------------------------------------------------*/
163 class NPT_Win32SerialPort: public NPT_SerialPortInterface
164 {
165 public:
166 // constructors and destructor
167 NPT_Win32SerialPort(const char* name);
168 ~NPT_Win32SerialPort();
169
170 // NPT_SerialPortInterface methods
171 NPT_Result Open(unsigned int speed,
172 NPT_SerialPortStopBits stop_bits = NPT_SERIAL_PORT_STOP_BITS_1,
173 NPT_SerialPortFlowControl flow_control = NPT_SERIAL_PORT_FLOW_CONTROL_NONE,
174 NPT_SerialPortParity parity = NPT_SERIAL_PORT_PARITY_NONE);
175 NPT_Result Close();
176 NPT_Result GetInputStream(NPT_InputStreamReference& stream);
177 NPT_Result GetOutputStream(NPT_OutputStreamReference& stream);
178
179 private:
180 // members
181 NPT_String m_Name;
182 NPT_Win32HandleReference m_HandleReference;
183 };
184
185 /*----------------------------------------------------------------------
186 | NPT_Win32SerialPort::NPT_Win32SerialPort
187 +---------------------------------------------------------------------*/
188 NPT_Win32SerialPort::NPT_Win32SerialPort(const char* name) :
189 m_Name(name)
190 {
191 }
192
193 /*----------------------------------------------------------------------
194 | NPT_Win32SerialPort::~NPT_Win32SerialPort
195 +---------------------------------------------------------------------*/
196 NPT_Win32SerialPort::~NPT_Win32SerialPort()
197 {
198 Close();
199 }
200
201 /*----------------------------------------------------------------------
202 | NPT_Win32SerialPort::Open
203 +---------------------------------------------------------------------*/
204 NPT_Result
205 NPT_Win32SerialPort::Open(unsigned int speed,
206 NPT_SerialPortStopBits stop_bits,
207 NPT_SerialPortFlowControl flow_control,
208 NPT_SerialPortParity parity)
209 {
210 // check if we're already open
211 if (!m_HandleReference.IsNull()) {
212 return NPT_ERROR_SERIAL_PORT_ALREADY_OPEN;
213 }
214
215 HANDLE handle = CreateFile(m_Name,
216 GENERIC_READ | GENERIC_WRITE,
217 0,
218 0,
219 OPEN_EXISTING,
220 0,
221 0);
222 if (handle == INVALID_HANDLE_VALUE) {
223 return NPT_ERROR_NO_SUCH_SERIAL_PORT;
224 }
225
226 // set the parameters
227 DCB dcb;
228 NPT_SetMemory(&dcb, 0, sizeof(dcb));
229 dcb.DCBlength = sizeof(DCB);
230 if (!GetCommState(handle, &dcb)) {
231 CloseHandle(handle);
232 return NPT_FAILURE;
233 }
234 dcb.fBinary = TRUE;
235 dcb.BaudRate = speed;
236 switch (stop_bits) {
237 case NPT_SERIAL_PORT_STOP_BITS_1: dcb.StopBits = ONESTOPBIT; break;
238 case NPT_SERIAL_PORT_STOP_BITS_1_5: dcb.StopBits = ONE5STOPBITS; break;
239 case NPT_SERIAL_PORT_STOP_BITS_2: dcb.StopBits = TWOSTOPBITS; break;
240 }
241 switch (flow_control) {
242 case NPT_SERIAL_PORT_FLOW_CONTROL_NONE:
243 dcb.fOutX = dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = FALSE;
244 dcb.fInX = dcb.fDsrSensitivity = FALSE;
245 dcb.fRtsControl = RTS_CONTROL_DISABLE;
246 dcb.fDtrControl = DTR_CONTROL_DISABLE;
247 break;
248
249 case NPT_SERIAL_PORT_FLOW_CONTROL_HARDWARE:
250 dcb.fOutX = dcb.fOutxDsrFlow = FALSE;
251 dcb.fOutxCtsFlow = TRUE;
252 dcb.fInX = dcb.fDsrSensitivity = FALSE;
253 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
254 dcb.fDtrControl = DTR_CONTROL_DISABLE;
255 break;
256
257 case NPT_SERIAL_PORT_FLOW_CONTROL_XON_XOFF:
258 dcb.fOutX = TRUE;
259 dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = FALSE;
260 dcb.fInX = TRUE;
261 dcb.fDsrSensitivity = FALSE;
262 dcb.fRtsControl = RTS_CONTROL_DISABLE;
263 dcb.fDtrControl = DTR_CONTROL_DISABLE;
264 break;
265 }
266 switch (parity) {
267 case NPT_SERIAL_PORT_PARITY_NONE: dcb.fParity = FALSE; dcb.Parity = NOPARITY; break;
268 case NPT_SERIAL_PORT_PARITY_EVEN: dcb.fParity = TRUE; dcb.Parity = EVENPARITY; break;
269 case NPT_SERIAL_PORT_PARITY_ODD: dcb.fParity = TRUE; dcb.Parity = ODDPARITY; break;
270 case NPT_SERIAL_PORT_PARITY_MARK: dcb.fParity = TRUE; dcb.Parity = MARKPARITY; break;
271 }
272 if (!SetCommState(handle, &dcb)) {
273 CloseHandle(handle);
274 return NPT_FAILURE;
275 }
276
277 // create a reference to the FILE object
278 m_HandleReference = new NPT_Win32HandleWrapper(handle);
279
280 return NPT_SUCCESS;
281 }
282
283 /*----------------------------------------------------------------------
284 | NPT_Win32SerialPort::Close
285 +---------------------------------------------------------------------*/
286 NPT_Result
287 NPT_Win32SerialPort::Close()
288 {
289 // release the file reference
290 m_HandleReference = NULL;
291
292 return NPT_SUCCESS;
293 }
294
295 /*----------------------------------------------------------------------
296 | NPT_Win32SerialPort::GetInputStream
297 +---------------------------------------------------------------------*/
298 NPT_Result
299 NPT_Win32SerialPort::GetInputStream(NPT_InputStreamReference& stream)
300 {
301 // default value
302 stream = NULL;
303
304 // check that the file is open
305 if (m_HandleReference.IsNull()) return NPT_ERROR_SERIAL_PORT_NOT_OPEN;
306
307 // create a stream
308 stream = new NPT_Win32SerialPortInputStream(m_HandleReference);
309
310 return NPT_SUCCESS;
311 }
312
313 /*----------------------------------------------------------------------
314 | NPT_Win32SerialPort::GetOutputStream
315 +---------------------------------------------------------------------*/
316 NPT_Result
317 NPT_Win32SerialPort::GetOutputStream(NPT_OutputStreamReference& stream)
318 {
319 // default value
320 stream = NULL;
321
322 // check that the file is open
323 if (m_HandleReference.IsNull()) return NPT_ERROR_SERIAL_PORT_NOT_OPEN;
324
325 // create a stream
326 stream = new NPT_Win32SerialPortOutputStream(m_HandleReference);
327
328 return NPT_SUCCESS;
329 }
330
331 /*----------------------------------------------------------------------
332 | NPT_SerialPort::NPT_SerialPort
333 +---------------------------------------------------------------------*/
334 NPT_SerialPort::NPT_SerialPort(const char* name)
335 {
336 m_Delegate = new NPT_Win32SerialPort(name);
337 }