source: ntrip/trunk/BNC/src/serial/win_qextserialport.cpp@ 10943

Last change on this file since 10943 was 10939, checked in by stuerze, 2 months ago

bug fix to open com ports with higher numbers, e.g. COM11 or COM17

File size: 28.9 KB
Line 
1/*!
2\class Win_QextSerialPort
3\version 1.0.0
4\author Stefan Sander
5
6A cross-platform serial port class.
7This class encapsulates the Windows portion of QextSerialPort. The user will be notified of
8errors and possible portability conflicts at run-time by default - this behavior can be turned
9off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off
10portability warnings) in the project. Note that defining _TTY_NOWARN_ also defines
11_TTY_NOWARN_PORT_.
12
13\note
14On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may
15select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
16make no guarantees as to the quality of POSIX support under NT/2000 however.
17
18*/
19
20#include <stdio.h>
21#include "win_qextserialport.h"
22
23/*!
24\fn Win_QextSerialPort::Win_QextSerialPort()
25Default constructor. Note that the name of the device used by a Win_QextSerialPort constructed
26with this constructor will be determined by defined constants, or lack thereof - the default
27behavior is the same as _TTY_LINUX_. Possible naming conventions and their associated constants
28are:
29
30\verbatim
31
32Constant Used By Naming Convention
33---------- ------------- ------------------------
34_TTY_WIN_ Windows COM1, COM2
35_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
36_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
37_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
38_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
39_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
40_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
41<none> Linux /dev/ttyS0, /dev/ttyS1
42\endverbatim
43
44This constructor associates the object with the first port on the system, e.g. COM1 for Windows
45platforms. See the other constructor if you need a port other than the first.
46*/
47Win_QextSerialPort::Win_QextSerialPort():QextSerialBase() {
48 Win_Handle=INVALID_HANDLE_VALUE;
49}
50
51/*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&)
52Copy constructor.
53*/
54Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort& s):QextSerialBase(s.port) {
55 Win_Handle=INVALID_HANDLE_VALUE;
56 setOpenMode(s.openMode());
57 lastErr=s.lastErr;
58 port = s.port;
59 Settings.FlowControl=s.Settings.FlowControl;
60 Settings.Parity=s.Settings.Parity;
61 Settings.DataBits=s.Settings.DataBits;
62 Settings.StopBits=s.Settings.StopBits;
63 Settings.BaudRate=s.Settings.BaudRate;
64 Win_Handle=s.Win_Handle;
65 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
66 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
67}
68
69/*!
70\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name)
71Constructs a serial port attached to the port specified by devName.
72devName is the name of the device, which is windowsystem-specific,
73e.g."COM2" or "/dev/ttyS0".
74*/
75Win_QextSerialPort::Win_QextSerialPort(const QString & name):QextSerialBase(name) {
76 Win_Handle=INVALID_HANDLE_VALUE;
77}
78
79/*!
80\fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings)
81Constructs a port with default name and specified settings.
82*/
83Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) {
84 Win_Handle=INVALID_HANDLE_VALUE;
85 setBaudRate(settings.BaudRate);
86 setDataBits(settings.DataBits);
87 setStopBits(settings.StopBits);
88 setParity(settings.Parity);
89 setFlowControl(settings.FlowControl);
90 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
91}
92
93/*!
94\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings)
95Constructs a port with specified name and settings.
96*/
97Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) {
98 Win_Handle=INVALID_HANDLE_VALUE;
99 setPortName(name);
100 setBaudRate(settings.BaudRate);
101 setDataBits(settings.DataBits);
102 setStopBits(settings.StopBits);
103 setParity(settings.Parity);
104 setFlowControl(settings.FlowControl);
105 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
106}
107
108/*!
109\fn Win_QextSerialPort::~Win_QextSerialPort()
110Standard destructor.
111*/
112Win_QextSerialPort::~Win_QextSerialPort() {
113 if (isOpen()) {
114 close();
115 }
116}
117
118/*!
119\fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s)
120overrides the = operator
121*/
122Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) {
123 setOpenMode(s.openMode());
124 lastErr=s.lastErr;
125 port = s.port;
126 Settings.FlowControl=s.Settings.FlowControl;
127 Settings.Parity=s.Settings.Parity;
128 Settings.DataBits=s.Settings.DataBits;
129 Settings.StopBits=s.Settings.StopBits;
130 Settings.BaudRate=s.Settings.BaudRate;
131 Win_Handle=s.Win_Handle;
132 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
133 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
134 return *this;
135}
136
137/*!
138\fn bool Win_QextSerialPort::open(OpenMode mode)
139Opens a serial port. Note that this function does not specify which device to open. If you need
140to open a device by name, see Win_QextSerialPort::open(const char*). This function has no effect
141if the port associated with the class is already open. The port is also configured to the current
142settings, as stored in the Settings structure.
143*/
144bool Win_QextSerialPort::open(OpenMode mode) {
145 unsigned long confSize = sizeof(COMMCONFIG);
146 Win_CommConfig.dwSize = confSize;
147
148 LOCK_MUTEX();
149 if (mode == QIODevice::NotOpen)
150 return isOpen();
151 if (!isOpen()) {
152 /*open the port*/
153 /* the \\.\ prefix is required for COM10 and above, see Microsoft KB115831 */
154 QString devName = "\\\\.\\" + port;
155 Win_Handle=CreateFileA(devName.toLatin1(), GENERIC_READ|GENERIC_WRITE,
156 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
157 if (Win_Handle!=INVALID_HANDLE_VALUE) {
158 /*set open mode*/
159 QIODevice::open(mode);
160
161 /*configure port settings*/
162 GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
163 GetCommState(Win_Handle, &(Win_CommConfig.dcb));
164
165 /*set up parameters*/
166 Win_CommConfig.dcb.fBinary=TRUE;
167 Win_CommConfig.dcb.fInX=FALSE;
168 Win_CommConfig.dcb.fOutX=FALSE;
169 Win_CommConfig.dcb.fAbortOnError=FALSE;
170 Win_CommConfig.dcb.fNull=FALSE;
171 setBaudRate(Settings.BaudRate);
172 setDataBits(Settings.DataBits);
173 setStopBits(Settings.StopBits);
174 setParity(Settings.Parity);
175 setFlowControl(Settings.FlowControl);
176 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
177 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
178 }
179 }
180 UNLOCK_MUTEX();
181 return isOpen();
182}
183
184/*!
185\fn void Win_QextSerialPort::close()
186Closes a serial port. This function has no effect if the serial port associated with the class
187is not currently open.
188*/
189void Win_QextSerialPort::close() {
190 LOCK_MUTEX();
191 CloseHandle(Win_Handle);
192 QIODevice::close();
193 UNLOCK_MUTEX();
194}
195
196/*!
197\fn void Win_QextSerialPort::flush()
198Flushes all pending I/O to the serial port. This function has no effect if the serial port
199associated with the class is not currently open.
200*/
201void Win_QextSerialPort::flush() {
202 LOCK_MUTEX();
203 if (isOpen()) {
204 FlushFileBuffers(Win_Handle);
205 }
206 UNLOCK_MUTEX();
207}
208
209/*!
210\fn qint64 Win_QextSerialPort::size() const
211This function will return the number of bytes waiting in the receive queue of the serial port.
212It is included primarily to provide a complete QIODevice interface, and will not record errors
213in the lastErr member (because it is const). This function is also not thread-safe - in
214multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
215*/
216qint64 Win_QextSerialPort::size() const {
217 int availBytes;
218 COMSTAT Win_ComStat;
219 DWORD Win_ErrorMask=0;
220 ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
221 availBytes = Win_ComStat.cbInQue;
222 return (qint64)availBytes;
223}
224
225/*!
226\fn qint64 Win_QextSerialPort::bytesAvailable()
227Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
228the port is not currently open, or -1 on error. Error information can be retrieved by calling
229Win_QextSerialPort::getLastError().
230*/
231qint64 Win_QextSerialPort::bytesAvailable() {
232 LOCK_MUTEX();
233 if (isOpen()) {
234 DWORD Errors;
235 COMSTAT Status;
236 bool success=ClearCommError(Win_Handle, &Errors, &Status);
237 translateError(Errors);
238 if (success) {
239 lastErr=E_NO_ERROR;
240 UNLOCK_MUTEX();
241 return Status.cbInQue + QIODevice::bytesAvailable();
242 }
243 UNLOCK_MUTEX();
244 return (unsigned int)-1;
245 }
246 UNLOCK_MUTEX();
247 return 0;
248}
249
250/*!
251\fn void Win_QextSerialPort::translateError(ulong error)
252Translates a system-specific error code to a QextSerialPort error code. Used internally.
253*/
254void Win_QextSerialPort::translateError(ulong error) {
255 if (error&CE_BREAK) {
256 lastErr=E_BREAK_CONDITION;
257 }
258 else if (error&CE_FRAME) {
259 lastErr=E_FRAMING_ERROR;
260 }
261 else if (error&CE_IOE) {
262 lastErr=E_IO_ERROR;
263 }
264 else if (error&CE_MODE) {
265 lastErr=E_INVALID_FD;
266 }
267 else if (error&CE_OVERRUN) {
268 lastErr=E_BUFFER_OVERRUN;
269 }
270 else if (error&CE_RXPARITY) {
271 lastErr=E_RECEIVE_PARITY_ERROR;
272 }
273 else if (error&CE_RXOVER) {
274 lastErr=E_RECEIVE_OVERFLOW;
275 }
276 else if (error&CE_TXFULL) {
277 lastErr=E_TRANSMIT_OVERFLOW;
278 }
279}
280
281/*!
282\fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
283Reads a block of data from the serial port. This function will read at most maxlen bytes from
284the serial port and place them in the buffer pointed to by data. Return value is the number of
285bytes actually read, or -1 on error.
286
287\warning before calling this function ensure that serial port associated with this class
288is currently open (use isOpen() function to check if port is open).
289*/
290qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
291{
292 LOCK_MUTEX();
293 int retVal=0;
294 COMSTAT Win_ComStat;
295 DWORD Win_BytesRead=0;
296 DWORD Win_ErrorMask=0;
297 ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
298 if (Win_ComStat.cbInQue &&
299 (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesRead, NULL)
300 || Win_BytesRead==0)) {
301 lastErr=E_READ_FAILED;
302 retVal=-1;
303 }
304 else {
305 retVal=((int)Win_BytesRead);
306 }
307 UNLOCK_MUTEX();
308
309 return retVal;
310}
311
312/*!
313\fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
314Writes a block of data to the serial port. This function will write len bytes
315from the buffer pointed to by data to the serial port. Return value is the number
316of bytes actually written, or -1 on error.
317
318\warning before calling this function ensure that serial port associated with this class
319is currently open (use isOpen() function to check if port is open).
320*/
321qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
322{
323 LOCK_MUTEX();
324 int retVal=0;
325 DWORD Win_BytesWritten;
326 if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesWritten, NULL)) {
327 lastErr=E_WRITE_FAILED;
328 retVal=-1;
329 }
330 else {
331 retVal=((int)Win_BytesWritten);
332 }
333 UNLOCK_MUTEX();
334
335 flush();
336 return retVal;
337}
338
339/*!
340\fn void Win_QextSerialPort::ungetChar(char c)
341This function is included to implement the full QIODevice interface, and currently has no
342purpose within this class. This function is meaningless on an unbuffered device and currently
343only prints a warning message to that effect.
344*/
345void Win_QextSerialPort::ungetChar(char c) {
346
347 /*meaningless on unbuffered sequential device - return error and print a warning*/
348 TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
349}
350
351/*!
352\fn void Win_QextSerialPort::setFlowControl(FlowType flow)
353Sets the flow control used by the port. Possible values of flow are:
354\verbatim
355 FLOW_OFF No flow control
356 FLOW_HARDWARE Hardware (RTS/CTS) flow control
357 FLOW_XONXOFF Software (XON/XOFF) flow control
358\endverbatim
359*/
360void Win_QextSerialPort::setFlowControl(FlowType flow) {
361 LOCK_MUTEX();
362 if (Settings.FlowControl!=flow) {
363 Settings.FlowControl=flow;
364 }
365 if (isOpen()) {
366 switch(flow) {
367
368 /*no flow control*/
369 case FLOW_OFF:
370 Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
371 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
372 Win_CommConfig.dcb.fInX=FALSE;
373 Win_CommConfig.dcb.fOutX=FALSE;
374 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
375 break;
376
377 /*software (XON/XOFF) flow control*/
378 case FLOW_XONXOFF:
379 Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
380 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
381 Win_CommConfig.dcb.fInX=TRUE;
382 Win_CommConfig.dcb.fOutX=TRUE;
383 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
384 break;
385
386 case FLOW_HARDWARE:
387 Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
388 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
389 Win_CommConfig.dcb.fInX=FALSE;
390 Win_CommConfig.dcb.fOutX=FALSE;
391 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
392 break;
393 }
394 }
395 UNLOCK_MUTEX();
396}
397
398/*!
399\fn void Win_QextSerialPort::setParity(ParityType parity)
400Sets the parity associated with the serial port. The possible values of parity are:
401\verbatim
402 PAR_SPACE Space Parity
403 PAR_MARK Mark Parity
404 PAR_NONE No Parity
405 PAR_EVEN Even Parity
406 PAR_ODD Odd Parity
407\endverbatim
408*/
409void Win_QextSerialPort::setParity(ParityType parity) {
410 LOCK_MUTEX();
411 if (Settings.Parity!=parity) {
412 Settings.Parity=parity;
413 }
414 if (isOpen()) {
415 Win_CommConfig.dcb.Parity=(unsigned char)parity;
416 switch (parity) {
417
418 /*space parity*/
419 case PAR_SPACE:
420 if (Settings.DataBits==DATA_8) {
421 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
422 }
423 Win_CommConfig.dcb.fParity=TRUE;
424 break;
425
426 /*mark parity - WINDOWS ONLY*/
427 case PAR_MARK:
428 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems");
429 Win_CommConfig.dcb.fParity=TRUE;
430 break;
431
432 /*no parity*/
433 case PAR_NONE:
434 Win_CommConfig.dcb.fParity=FALSE;
435 break;
436
437 /*even parity*/
438 case PAR_EVEN:
439 Win_CommConfig.dcb.fParity=TRUE;
440 break;
441
442 /*odd parity*/
443 case PAR_ODD:
444 Win_CommConfig.dcb.fParity=TRUE;
445 break;
446 }
447 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
448 }
449 UNLOCK_MUTEX();
450}
451
452/*!
453\fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
454Sets the number of data bits used by the serial port. Possible values of dataBits are:
455\verbatim
456 DATA_5 5 data bits
457 DATA_6 6 data bits
458 DATA_7 7 data bits
459 DATA_8 8 data bits
460\endverbatim
461
462\note
463This function is subject to the following restrictions:
464\par
465 5 data bits cannot be used with 2 stop bits.
466\par
467 1.5 stop bits can only be used with 5 data bits.
468\par
469 8 data bits cannot be used with space parity on POSIX systems.
470
471*/
472void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
473 LOCK_MUTEX();
474 if (Settings.DataBits!=dataBits) {
475 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
476 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {
477 }
478 else {
479 Settings.DataBits=dataBits;
480 }
481 }
482 if (isOpen()) {
483 switch(dataBits) {
484
485 /*5 data bits*/
486 case DATA_5:
487 if (Settings.StopBits==STOP_2) {
488 TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
489 }
490 else {
491 Win_CommConfig.dcb.ByteSize=5;
492 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
493 }
494 break;
495
496 /*6 data bits*/
497 case DATA_6:
498 if (Settings.StopBits==STOP_1_5) {
499 TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
500 }
501 else {
502 Win_CommConfig.dcb.ByteSize=6;
503 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
504 }
505 break;
506
507 /*7 data bits*/
508 case DATA_7:
509 if (Settings.StopBits==STOP_1_5) {
510 TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
511 }
512 else {
513 Win_CommConfig.dcb.ByteSize=7;
514 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
515 }
516 break;
517
518 /*8 data bits*/
519 case DATA_8:
520 if (Settings.StopBits==STOP_1_5) {
521 TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
522 }
523 else {
524 Win_CommConfig.dcb.ByteSize=8;
525 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
526 }
527 break;
528 }
529 }
530 UNLOCK_MUTEX();
531}
532
533/*!
534\fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
535Sets the number of stop bits used by the serial port. Possible values of stopBits are:
536\verbatim
537 STOP_1 1 stop bit
538 STOP_1_5 1.5 stop bits
539 STOP_2 2 stop bits
540\endverbatim
541
542\note
543This function is subject to the following restrictions:
544\par
545 2 stop bits cannot be used with 5 data bits.
546\par
547 1.5 stop bits cannot be used with 6 or more data bits.
548\par
549 POSIX does not support 1.5 stop bits.
550*/
551void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
552 LOCK_MUTEX();
553 if (Settings.StopBits!=stopBits) {
554 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||
555 (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {
556 }
557 else {
558 Settings.StopBits=stopBits;
559 }
560 }
561 if (isOpen()) {
562 switch (stopBits) {
563
564 /*one stop bit*/
565 case STOP_1:
566 Win_CommConfig.dcb.StopBits=ONESTOPBIT;
567 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
568 break;
569
570 /*1.5 stop bits*/
571 case STOP_1_5:
572 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
573 if (Settings.DataBits!=DATA_5) {
574 TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
575 }
576 else {
577 Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
578 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
579 }
580 break;
581
582 /*two stop bits*/
583 case STOP_2:
584 if (Settings.DataBits==DATA_5) {
585 TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
586 }
587 else {
588 Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
589 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
590 }
591 break;
592 }
593 }
594 UNLOCK_MUTEX();
595}
596
597/*!
598\fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
599Sets the baud rate of the serial port. Note that not all rates are applicable on
600all platforms. The following table shows translations of the various baud rate
601constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
602are speeds that are usable on both Windows and POSIX.
603\verbatim
604
605 RATE Windows Speed POSIX Speed
606 ----------- ------------- -----------
607 BAUD50 110 50
608 BAUD75 110 75
609 *BAUD110 110 110
610 BAUD134 110 134.5
611 BAUD150 110 150
612 BAUD200 110 200
613 *BAUD300 300 300
614 *BAUD600 600 600
615 *BAUD1200 1200 1200
616 BAUD1800 1200 1800
617 *BAUD2400 2400 2400
618 *BAUD4800 4800 4800
619 *BAUD9600 9600 9600
620 BAUD14400 14400 9600
621 *BAUD19200 19200 19200
622 *BAUD38400 38400 38400
623 BAUD56000 56000 38400
624 *BAUD57600 57600 57600
625 BAUD76800 57600 76800
626 *BAUD115200 115200 115200
627 BAUD128000 128000 115200
628 BAUD256000 256000 115200
629\endverbatim
630*/
631void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
632 LOCK_MUTEX();
633 if (Settings.BaudRate!=baudRate) {
634 switch (baudRate) {
635 case BAUD50:
636 case BAUD75:
637 case BAUD134:
638 case BAUD150:
639 case BAUD200:
640 Settings.BaudRate=BAUD110;
641 break;
642
643 case BAUD1800:
644 Settings.BaudRate=BAUD1200;
645 break;
646
647 case BAUD76800:
648 Settings.BaudRate=BAUD57600;
649 break;
650
651 default:
652 Settings.BaudRate=baudRate;
653 break;
654 }
655 }
656 if (isOpen()) {
657 switch (baudRate) {
658
659 /*50 baud*/
660 case BAUD50:
661 TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud.");
662 Win_CommConfig.dcb.BaudRate=CBR_110;
663 break;
664
665 /*75 baud*/
666 case BAUD75:
667 TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud.");
668 Win_CommConfig.dcb.BaudRate=CBR_110;
669 break;
670
671 /*110 baud*/
672 case BAUD110:
673 Win_CommConfig.dcb.BaudRate=CBR_110;
674 break;
675
676 /*134.5 baud*/
677 case BAUD134:
678 TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud.");
679 Win_CommConfig.dcb.BaudRate=CBR_110;
680 break;
681
682 /*150 baud*/
683 case BAUD150:
684 TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud.");
685 Win_CommConfig.dcb.BaudRate=CBR_110;
686 break;
687
688 /*200 baud*/
689 case BAUD200:
690 TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud.");
691 Win_CommConfig.dcb.BaudRate=CBR_110;
692 break;
693
694 /*300 baud*/
695 case BAUD300:
696 Win_CommConfig.dcb.BaudRate=CBR_300;
697 break;
698
699 /*600 baud*/
700 case BAUD600:
701 Win_CommConfig.dcb.BaudRate=CBR_600;
702 break;
703
704 /*1200 baud*/
705 case BAUD1200:
706 Win_CommConfig.dcb.BaudRate=CBR_1200;
707 break;
708
709 /*1800 baud*/
710 case BAUD1800:
711 TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud.");
712 Win_CommConfig.dcb.BaudRate=CBR_1200;
713 break;
714
715 /*2400 baud*/
716 case BAUD2400:
717 Win_CommConfig.dcb.BaudRate=CBR_2400;
718 break;
719
720 /*4800 baud*/
721 case BAUD4800:
722 Win_CommConfig.dcb.BaudRate=CBR_4800;
723 break;
724
725 /*9600 baud*/
726 case BAUD9600:
727 Win_CommConfig.dcb.BaudRate=CBR_9600;
728 break;
729
730 /*14400 baud*/
731 case BAUD14400:
732 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
733 Win_CommConfig.dcb.BaudRate=CBR_14400;
734 break;
735
736 /*19200 baud*/
737 case BAUD19200:
738 Win_CommConfig.dcb.BaudRate=CBR_19200;
739 break;
740
741 /*38400 baud*/
742 case BAUD38400:
743 Win_CommConfig.dcb.BaudRate=CBR_38400;
744 break;
745
746 /*56000 baud*/
747 case BAUD56000:
748 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
749 Win_CommConfig.dcb.BaudRate=CBR_56000;
750 break;
751
752 /*57600 baud*/
753 case BAUD57600:
754 Win_CommConfig.dcb.BaudRate=CBR_57600;
755 break;
756
757 /*76800 baud*/
758 case BAUD76800:
759 TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud.");
760 Win_CommConfig.dcb.BaudRate=CBR_57600;
761 break;
762
763 /*115200 baud*/
764 case BAUD115200:
765 Win_CommConfig.dcb.BaudRate=CBR_115200;
766 break;
767
768 /*128000 baud*/
769 case BAUD128000:
770 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");
771 Win_CommConfig.dcb.BaudRate=CBR_128000;
772 break;
773
774 /*256000 baud*/
775 case BAUD256000:
776 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");
777 Win_CommConfig.dcb.BaudRate=CBR_256000;
778 break;
779 }
780 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
781 }
782 UNLOCK_MUTEX();
783}
784
785/*!
786\fn void Win_QextSerialPort::setDtr(bool set)
787Sets DTR line to the requested state (high by default). This function will have no effect if
788the port associated with the class is not currently open.
789*/
790void Win_QextSerialPort::setDtr(bool set) {
791 LOCK_MUTEX();
792 if (isOpen()) {
793 if (set) {
794 EscapeCommFunction(Win_Handle, SETDTR);
795 }
796 else {
797 EscapeCommFunction(Win_Handle, CLRDTR);
798 }
799 }
800 UNLOCK_MUTEX();
801}
802
803/*!
804\fn void Win_QextSerialPort::setRts(bool set)
805Sets RTS line to the requested state (high by default). This function will have no effect if
806the port associated with the class is not currently open.
807*/
808void Win_QextSerialPort::setRts(bool set) {
809 LOCK_MUTEX();
810 if (isOpen()) {
811 if (set) {
812 EscapeCommFunction(Win_Handle, SETRTS);
813 }
814 else {
815 EscapeCommFunction(Win_Handle, CLRRTS);
816 }
817 }
818 UNLOCK_MUTEX();
819}
820
821/*!
822\fn ulong Win_QextSerialPort::lineStatus(void)
823returns the line status as stored by the port function. This function will retrieve the states
824of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
825can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
826long with specific bits indicating which lines are high. The following constants should be used
827to examine the states of individual lines:
828
829\verbatim
830Mask Line
831------ ----
832LS_CTS CTS
833LS_DSR DSR
834LS_DCD DCD
835LS_RI RI
836\endverbatim
837
838This function will return 0 if the port associated with the class is not currently open.
839*/
840ulong Win_QextSerialPort::lineStatus(void) {
841 unsigned long Status=0, Temp=0;
842 LOCK_MUTEX();
843 if (isOpen()) {
844 GetCommModemStatus(Win_Handle, &Temp);
845 if (Temp&MS_CTS_ON) {
846 Status|=LS_CTS;
847 }
848 if (Temp&MS_DSR_ON) {
849 Status|=LS_DSR;
850 }
851 if (Temp&MS_RING_ON) {
852 Status|=LS_RI;
853 }
854 if (Temp&MS_RLSD_ON) {
855 Status|=LS_DCD;
856 }
857 }
858 UNLOCK_MUTEX();
859 return Status;
860}
861
862/*!
863\fn void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec);
864Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
865*/
866void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec) {
867 LOCK_MUTEX();
868 Settings.Timeout_Sec=sec;
869 Settings.Timeout_Millisec=millisec;
870 if(isOpen()) {
871 Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec;
872 Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec;
873 Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
874 Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec;
875 Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
876 SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
877 }
878 UNLOCK_MUTEX();
879}
Note: See TracBrowser for help on using the repository browser.