source: ntrip/trunk/BNC/src/serial/posix_qextserialport.cpp@ 6668

Last change on this file since 6668 was 1406, checked in by mervart, 16 years ago

* empty log message *

File size: 36.0 KB
Line 
1
2/*!
3\class Posix_QextSerialPort
4\version 1.0.0
5\author Stefan Sander
6
7A cross-platform serial port class.
8This class encapsulates the POSIX portion of QextSerialPort. The user will be notified of errors
9and possible portability conflicts at run-time by default - this behavior can be turned off by
10defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability
11warnings) in the project. Note that _TTY_NOWARN_ will also turn off portability warnings.
12*/
13
14#ifdef sparc
15#include <sys/filio.h>
16#endif
17
18#include <stdio.h>
19#include "posix_qextserialport.h"
20
21/*!
22\fn Posix_QextSerialPort::Posix_QextSerialPort()
23Default constructor. Note that the name of the device used by a QextSerialPort constructed with
24this constructor will be determined by #defined constants, or lack thereof - the default behavior
25is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are:
26
27\verbatim
28
29Constant Used By Naming Convention
30---------- ------------- ------------------------
31_TTY_WIN_ Windows COM1, COM2
32_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
33_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
34_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
35_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
36_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
37_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
38<none> Linux /dev/ttyS0, /dev/ttyS1
39\endverbatim
40
41This constructor assigns the device name to the name of the first port on the specified system.
42See the other constructors if you need to open a different port.
43*/
44Posix_QextSerialPort::Posix_QextSerialPort()
45: QextSerialBase()
46{
47 Posix_File=new QFile();
48}
49
50/*!
51\fn Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort&)
52Copy constructor.
53*/
54Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort& s)
55 : QextSerialBase(s.port)
56{
57 setOpenMode(s.openMode());
58 port = s.port;
59 Settings.BaudRate=s.Settings.BaudRate;
60 Settings.DataBits=s.Settings.DataBits;
61 Settings.Parity=s.Settings.Parity;
62 Settings.StopBits=s.Settings.StopBits;
63 Settings.FlowControl=s.Settings.FlowControl;
64 lastErr=s.lastErr;
65
66 Posix_File=new QFile();
67 Posix_File=s.Posix_File;
68 memcpy(&Posix_Timeout, &s.Posix_Timeout, sizeof(struct timeval));
69 memcpy(&Posix_Copy_Timeout, &s.Posix_Copy_Timeout, sizeof(struct timeval));
70 memcpy(&Posix_CommConfig, &s.Posix_CommConfig, sizeof(struct termios));
71}
72
73/*!
74\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name)
75Constructs a serial port attached to the port specified by name.
76name is the name of the device, which is windowsystem-specific,
77e.g."COM1" or "/dev/ttyS0".
78*/
79Posix_QextSerialPort::Posix_QextSerialPort(const QString & name)
80 : QextSerialBase(name)
81{
82 Posix_File=new QFile();
83}
84
85/*!
86\fn Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings)
87Constructs a port with default name and specified settings.
88*/
89Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings)
90 : QextSerialBase()
91{
92 setBaudRate(settings.BaudRate);
93 setDataBits(settings.DataBits);
94 setParity(settings.Parity);
95 setStopBits(settings.StopBits);
96 setFlowControl(settings.FlowControl);
97
98 Posix_File=new QFile();
99 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
100}
101
102/*!
103\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings)
104Constructs a port with specified name and settings.
105*/
106Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings)
107 : QextSerialBase(name)
108{
109 setBaudRate(settings.BaudRate);
110 setDataBits(settings.DataBits);
111 setParity(settings.Parity);
112 setStopBits(settings.StopBits);
113 setFlowControl(settings.FlowControl);
114
115 Posix_File=new QFile();
116 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
117}
118
119/*!
120\fn Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
121Override the = operator.
122*/
123Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
124{
125 setOpenMode(s.openMode());
126 port = s.port;
127 Settings.BaudRate=s.Settings.BaudRate;
128 Settings.DataBits=s.Settings.DataBits;
129 Settings.Parity=s.Settings.Parity;
130 Settings.StopBits=s.Settings.StopBits;
131 Settings.FlowControl=s.Settings.FlowControl;
132 lastErr=s.lastErr;
133
134 Posix_File=s.Posix_File;
135 memcpy(&Posix_Timeout, &(s.Posix_Timeout), sizeof(struct timeval));
136 memcpy(&Posix_Copy_Timeout, &(s.Posix_Copy_Timeout), sizeof(struct timeval));
137 memcpy(&Posix_CommConfig, &(s.Posix_CommConfig), sizeof(struct termios));
138 return *this;
139}
140
141/*!
142\fn Posix_QextSerialPort::~Posix_QextSerialPort()
143Standard destructor.
144*/
145Posix_QextSerialPort::~Posix_QextSerialPort()
146{
147 if (isOpen()) {
148 close();
149 }
150 Posix_File->close();
151 delete Posix_File;
152}
153
154/*!
155\fn void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
156Sets the baud rate of the serial port. Note that not all rates are applicable on
157all platforms. The following table shows translations of the various baud rate
158constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
159are speeds that are usable on both Windows and POSIX.
160
161\note
162BAUD76800 may not be supported on all POSIX systems. SGI/IRIX systems do not support
163BAUD1800.
164
165\verbatim
166
167 RATE Windows Speed POSIX Speed
168 ----------- ------------- -----------
169 BAUD50 110 50
170 BAUD75 110 75
171 *BAUD110 110 110
172 BAUD134 110 134.5
173 BAUD150 110 150
174 BAUD200 110 200
175 *BAUD300 300 300
176 *BAUD600 600 600
177 *BAUD1200 1200 1200
178 BAUD1800 1200 1800
179 *BAUD2400 2400 2400
180 *BAUD4800 4800 4800
181 *BAUD9600 9600 9600
182 BAUD14400 14400 9600
183 *BAUD19200 19200 19200
184 *BAUD38400 38400 38400
185 BAUD56000 56000 38400
186 *BAUD57600 57600 57600
187 BAUD76800 57600 76800
188 *BAUD115200 115200 115200
189 BAUD128000 128000 115200
190 BAUD256000 256000 115200
191\endverbatim
192*/
193void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
194{
195 LOCK_MUTEX();
196 if (Settings.BaudRate!=baudRate) {
197 switch (baudRate) {
198 case BAUD14400:
199 Settings.BaudRate=BAUD9600;
200 break;
201
202 case BAUD56000:
203 Settings.BaudRate=BAUD38400;
204 break;
205
206 case BAUD76800:
207
208#ifndef B76800
209 Settings.BaudRate=BAUD57600;
210#else
211 Settings.BaudRate=baudRate;
212#endif
213 break;
214
215 case BAUD128000:
216 case BAUD256000:
217 Settings.BaudRate=BAUD115200;
218 break;
219
220 default:
221 Settings.BaudRate=baudRate;
222 break;
223 }
224 }
225 if (isOpen()) {
226 switch (baudRate) {
227
228 /*50 baud*/
229 case BAUD50:
230 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation.");
231#ifdef CBAUD
232 Posix_CommConfig.c_cflag&=(~CBAUD);
233 Posix_CommConfig.c_cflag|=B50;
234#else
235 cfsetispeed(&Posix_CommConfig, B50);
236 cfsetospeed(&Posix_CommConfig, B50);
237#endif
238 break;
239
240 /*75 baud*/
241 case BAUD75:
242 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation.");
243#ifdef CBAUD
244 Posix_CommConfig.c_cflag&=(~CBAUD);
245 Posix_CommConfig.c_cflag|=B75;
246#else
247 cfsetispeed(&Posix_CommConfig, B75);
248 cfsetospeed(&Posix_CommConfig, B75);
249#endif
250 break;
251
252 /*110 baud*/
253 case BAUD110:
254#ifdef CBAUD
255 Posix_CommConfig.c_cflag&=(~CBAUD);
256 Posix_CommConfig.c_cflag|=B110;
257#else
258 cfsetispeed(&Posix_CommConfig, B110);
259 cfsetospeed(&Posix_CommConfig, B110);
260#endif
261 break;
262
263 /*134.5 baud*/
264 case BAUD134:
265 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation.");
266#ifdef CBAUD
267 Posix_CommConfig.c_cflag&=(~CBAUD);
268 Posix_CommConfig.c_cflag|=B134;
269#else
270 cfsetispeed(&Posix_CommConfig, B134);
271 cfsetospeed(&Posix_CommConfig, B134);
272#endif
273 break;
274
275 /*150 baud*/
276 case BAUD150:
277 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation.");
278#ifdef CBAUD
279 Posix_CommConfig.c_cflag&=(~CBAUD);
280 Posix_CommConfig.c_cflag|=B150;
281#else
282 cfsetispeed(&Posix_CommConfig, B150);
283 cfsetospeed(&Posix_CommConfig, B150);
284#endif
285 break;
286
287 /*200 baud*/
288 case BAUD200:
289 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation.");
290#ifdef CBAUD
291 Posix_CommConfig.c_cflag&=(~CBAUD);
292 Posix_CommConfig.c_cflag|=B200;
293#else
294 cfsetispeed(&Posix_CommConfig, B200);
295 cfsetospeed(&Posix_CommConfig, B200);
296#endif
297 break;
298
299 /*300 baud*/
300 case BAUD300:
301#ifdef CBAUD
302 Posix_CommConfig.c_cflag&=(~CBAUD);
303 Posix_CommConfig.c_cflag|=B300;
304#else
305 cfsetispeed(&Posix_CommConfig, B300);
306 cfsetospeed(&Posix_CommConfig, B300);
307#endif
308 break;
309
310 /*600 baud*/
311 case BAUD600:
312#ifdef CBAUD
313 Posix_CommConfig.c_cflag&=(~CBAUD);
314 Posix_CommConfig.c_cflag|=B600;
315#else
316 cfsetispeed(&Posix_CommConfig, B600);
317 cfsetospeed(&Posix_CommConfig, B600);
318#endif
319 break;
320
321 /*1200 baud*/
322 case BAUD1200:
323#ifdef CBAUD
324 Posix_CommConfig.c_cflag&=(~CBAUD);
325 Posix_CommConfig.c_cflag|=B1200;
326#else
327 cfsetispeed(&Posix_CommConfig, B1200);
328 cfsetospeed(&Posix_CommConfig, B1200);
329#endif
330 break;
331
332 /*1800 baud*/
333 case BAUD1800:
334 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation.");
335#ifdef CBAUD
336 Posix_CommConfig.c_cflag&=(~CBAUD);
337 Posix_CommConfig.c_cflag|=B1800;
338#else
339 cfsetispeed(&Posix_CommConfig, B1800);
340 cfsetospeed(&Posix_CommConfig, B1800);
341#endif
342 break;
343
344 /*2400 baud*/
345 case BAUD2400:
346#ifdef CBAUD
347 Posix_CommConfig.c_cflag&=(~CBAUD);
348 Posix_CommConfig.c_cflag|=B2400;
349#else
350 cfsetispeed(&Posix_CommConfig, B2400);
351 cfsetospeed(&Posix_CommConfig, B2400);
352#endif
353 break;
354
355 /*4800 baud*/
356 case BAUD4800:
357#ifdef CBAUD
358 Posix_CommConfig.c_cflag&=(~CBAUD);
359 Posix_CommConfig.c_cflag|=B4800;
360#else
361 cfsetispeed(&Posix_CommConfig, B4800);
362 cfsetospeed(&Posix_CommConfig, B4800);
363#endif
364 break;
365
366 /*9600 baud*/
367 case BAUD9600:
368#ifdef CBAUD
369 Posix_CommConfig.c_cflag&=(~CBAUD);
370 Posix_CommConfig.c_cflag|=B9600;
371#else
372 cfsetispeed(&Posix_CommConfig, B9600);
373 cfsetospeed(&Posix_CommConfig, B9600);
374#endif
375 break;
376
377 /*14400 baud*/
378 case BAUD14400:
379 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud.");
380#ifdef CBAUD
381 Posix_CommConfig.c_cflag&=(~CBAUD);
382 Posix_CommConfig.c_cflag|=B9600;
383#else
384 cfsetispeed(&Posix_CommConfig, B9600);
385 cfsetospeed(&Posix_CommConfig, B9600);
386#endif
387 break;
388
389 /*19200 baud*/
390 case BAUD19200:
391#ifdef CBAUD
392 Posix_CommConfig.c_cflag&=(~CBAUD);
393 Posix_CommConfig.c_cflag|=B19200;
394#else
395 cfsetispeed(&Posix_CommConfig, B19200);
396 cfsetospeed(&Posix_CommConfig, B19200);
397#endif
398 break;
399
400 /*38400 baud*/
401 case BAUD38400:
402#ifdef CBAUD
403 Posix_CommConfig.c_cflag&=(~CBAUD);
404 Posix_CommConfig.c_cflag|=B38400;
405#else
406 cfsetispeed(&Posix_CommConfig, B38400);
407 cfsetospeed(&Posix_CommConfig, B38400);
408#endif
409 break;
410
411 /*56000 baud*/
412 case BAUD56000:
413 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud.");
414#ifdef CBAUD
415 Posix_CommConfig.c_cflag&=(~CBAUD);
416 Posix_CommConfig.c_cflag|=B38400;
417#else
418 cfsetispeed(&Posix_CommConfig, B38400);
419 cfsetospeed(&Posix_CommConfig, B38400);
420#endif
421 break;
422
423 /*57600 baud*/
424 case BAUD57600:
425#ifdef CBAUD
426 Posix_CommConfig.c_cflag&=(~CBAUD);
427 Posix_CommConfig.c_cflag|=B57600;
428#else
429 cfsetispeed(&Posix_CommConfig, B57600);
430 cfsetospeed(&Posix_CommConfig, B57600);
431#endif
432 break;
433
434 /*76800 baud*/
435 case BAUD76800:
436 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation.");
437#ifdef CBAUD
438 Posix_CommConfig.c_cflag&=(~CBAUD);
439
440#ifdef B76800
441 Posix_CommConfig.c_cflag|=B76800;
442#else
443 TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud.");
444 Posix_CommConfig.c_cflag|=B57600;
445#endif //B76800
446#else //CBAUD
447#ifdef B76800
448 cfsetispeed(&Posix_CommConfig, B76800);
449 cfsetospeed(&Posix_CommConfig, B76800);
450#else
451 TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud.");
452 cfsetispeed(&Posix_CommConfig, B57600);
453 cfsetospeed(&Posix_CommConfig, B57600);
454#endif //B76800
455#endif //CBAUD
456 break;
457
458 /*115200 baud*/
459 case BAUD115200:
460#ifdef CBAUD
461 Posix_CommConfig.c_cflag&=(~CBAUD);
462 Posix_CommConfig.c_cflag|=B115200;
463#else
464 cfsetispeed(&Posix_CommConfig, B115200);
465 cfsetospeed(&Posix_CommConfig, B115200);
466#endif
467 break;
468
469 /*128000 baud*/
470 case BAUD128000:
471 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud.");
472#ifdef CBAUD
473 Posix_CommConfig.c_cflag&=(~CBAUD);
474 Posix_CommConfig.c_cflag|=B115200;
475#else
476 cfsetispeed(&Posix_CommConfig, B115200);
477 cfsetospeed(&Posix_CommConfig, B115200);
478#endif
479 break;
480
481 /*256000 baud*/
482 case BAUD256000:
483 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud.");
484#ifdef CBAUD
485 Posix_CommConfig.c_cflag&=(~CBAUD);
486 Posix_CommConfig.c_cflag|=B115200;
487#else
488 cfsetispeed(&Posix_CommConfig, B115200);
489 cfsetospeed(&Posix_CommConfig, B115200);
490#endif
491 break;
492 }
493 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
494 }
495 UNLOCK_MUTEX();
496}
497
498/*!
499\fn void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
500Sets the number of data bits used by the serial port. Possible values of dataBits are:
501\verbatim
502 DATA_5 5 data bits
503 DATA_6 6 data bits
504 DATA_7 7 data bits
505 DATA_8 8 data bits
506\endverbatim
507
508\note
509This function is subject to the following restrictions:
510\par
511 5 data bits cannot be used with 2 stop bits.
512\par
513 8 data bits cannot be used with space parity on POSIX systems.
514
515*/
516void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
517{
518 LOCK_MUTEX();
519 if (Settings.DataBits!=dataBits) {
520 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
521 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) ||
522 (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) {
523 }
524 else {
525 Settings.DataBits=dataBits;
526 }
527 }
528 if (isOpen()) {
529 switch(dataBits) {
530
531 /*5 data bits*/
532 case DATA_5:
533 if (Settings.StopBits==STOP_2) {
534 TTY_WARNING("Posix_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
535 }
536 else {
537 Settings.DataBits=dataBits;
538 Posix_CommConfig.c_cflag&=(~CSIZE);
539 Posix_CommConfig.c_cflag|=CS5;
540 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
541 }
542 break;
543
544 /*6 data bits*/
545 case DATA_6:
546 if (Settings.StopBits==STOP_1_5) {
547 TTY_WARNING("Posix_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
548 }
549 else {
550 Settings.DataBits=dataBits;
551 Posix_CommConfig.c_cflag&=(~CSIZE);
552 Posix_CommConfig.c_cflag|=CS6;
553 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
554 }
555 break;
556
557 /*7 data bits*/
558 case DATA_7:
559 if (Settings.StopBits==STOP_1_5) {
560 TTY_WARNING("Posix_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
561 }
562 else {
563 Settings.DataBits=dataBits;
564 Posix_CommConfig.c_cflag&=(~CSIZE);
565 Posix_CommConfig.c_cflag|=CS7;
566 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
567 }
568 break;
569
570 /*8 data bits*/
571 case DATA_8:
572 if (Settings.StopBits==STOP_1_5) {
573 TTY_WARNING("Posix_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
574 }
575 else {
576 Settings.DataBits=dataBits;
577 Posix_CommConfig.c_cflag&=(~CSIZE);
578 Posix_CommConfig.c_cflag|=CS8;
579 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
580 }
581 break;
582 }
583 }
584 UNLOCK_MUTEX();
585}
586
587/*!
588\fn void Posix_QextSerialPort::setParity(ParityType parity)
589Sets the parity associated with the serial port. The possible values of parity are:
590\verbatim
591 PAR_SPACE Space Parity
592 PAR_MARK Mark Parity
593 PAR_NONE No Parity
594 PAR_EVEN Even Parity
595 PAR_ODD Odd Parity
596\endverbatim
597
598\note
599This function is subject to the following limitations:
600\par
601POSIX systems do not support mark parity.
602\par
603POSIX systems support space parity only if tricked into doing so, and only with
604 fewer than 8 data bits. Use space parity very carefully with POSIX systems.
605
606*/
607void Posix_QextSerialPort::setParity(ParityType parity)
608{
609 LOCK_MUTEX();
610 if (Settings.Parity!=parity) {
611 if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) {
612 }
613 else {
614 Settings.Parity=parity;
615 }
616 }
617 if (isOpen()) {
618 switch (parity) {
619
620 /*space parity*/
621 case PAR_SPACE:
622 if (Settings.DataBits==DATA_8) {
623 TTY_PORTABILITY_WARNING("Posix_QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits");
624 }
625 else {
626
627 /*space parity not directly supported - add an extra data bit to simulate it*/
628 Posix_CommConfig.c_cflag&=~(PARENB|CSIZE);
629 switch(Settings.DataBits) {
630 case DATA_5:
631 Settings.DataBits=DATA_6;
632 Posix_CommConfig.c_cflag|=CS6;
633 break;
634
635 case DATA_6:
636 Settings.DataBits=DATA_7;
637 Posix_CommConfig.c_cflag|=CS7;
638 break;
639
640 case DATA_7:
641 Settings.DataBits=DATA_8;
642 Posix_CommConfig.c_cflag|=CS8;
643 break;
644
645 case DATA_8:
646 break;
647 }
648 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
649 }
650 break;
651
652 /*mark parity - WINDOWS ONLY*/
653 case PAR_MARK:
654 TTY_WARNING("Posix_QextSerialPort: Mark parity is not supported by POSIX.");
655 break;
656
657 /*no parity*/
658 case PAR_NONE:
659 Posix_CommConfig.c_cflag&=(~PARENB);
660 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
661 break;
662
663 /*even parity*/
664 case PAR_EVEN:
665 Posix_CommConfig.c_cflag&=(~PARODD);
666 Posix_CommConfig.c_cflag|=PARENB;
667 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
668 break;
669
670 /*odd parity*/
671 case PAR_ODD:
672 Posix_CommConfig.c_cflag|=(PARENB|PARODD);
673 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
674 break;
675 }
676 }
677 UNLOCK_MUTEX();
678}
679
680/*!
681\fn void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
682Sets the number of stop bits used by the serial port. Possible values of stopBits are:
683\verbatim
684 STOP_1 1 stop bit
685 STOP_1_5 1.5 stop bits
686 STOP_2 2 stop bits
687\endverbatim
688\note
689This function is subject to the following restrictions:
690\par
691 2 stop bits cannot be used with 5 data bits.
692\par
693 POSIX does not support 1.5 stop bits.
694
695*/
696void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
697{
698 LOCK_MUTEX();
699 if (Settings.StopBits!=stopBits) {
700 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {}
701 else {
702 Settings.StopBits=stopBits;
703 }
704 }
705 if (isOpen()) {
706 switch (stopBits) {
707
708 /*one stop bit*/
709 case STOP_1:
710 Settings.StopBits=stopBits;
711 Posix_CommConfig.c_cflag&=(~CSTOPB);
712 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
713 break;
714
715 /*1.5 stop bits*/
716 case STOP_1_5:
717 TTY_WARNING("Posix_QextSerialPort: 1.5 stop bit operation is not supported by POSIX.");
718 break;
719
720 /*two stop bits*/
721 case STOP_2:
722 if (Settings.DataBits==DATA_5) {
723 TTY_WARNING("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
724 }
725 else {
726 Settings.StopBits=stopBits;
727 Posix_CommConfig.c_cflag|=CSTOPB;
728 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
729 }
730 break;
731 }
732 }
733 UNLOCK_MUTEX();
734}
735
736/*!
737\fn void Posix_QextSerialPort::setFlowControl(FlowType flow)
738Sets the flow control used by the port. Possible values of flow are:
739\verbatim
740 FLOW_OFF No flow control
741 FLOW_HARDWARE Hardware (RTS/CTS) flow control
742 FLOW_XONXOFF Software (XON/XOFF) flow control
743\endverbatim
744\note
745FLOW_HARDWARE may not be supported on all versions of UNIX. In cases where it is
746unsupported, FLOW_HARDWARE is the same as FLOW_OFF.
747
748*/
749void Posix_QextSerialPort::setFlowControl(FlowType flow)
750{
751 LOCK_MUTEX();
752 if (Settings.FlowControl!=flow) {
753 Settings.FlowControl=flow;
754 }
755 if (isOpen()) {
756 switch(flow) {
757
758 /*no flow control*/
759 case FLOW_OFF:
760 Posix_CommConfig.c_cflag&=(~CRTSCTS);
761 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
762 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
763 break;
764
765 /*software (XON/XOFF) flow control*/
766 case FLOW_XONXOFF:
767 Posix_CommConfig.c_cflag&=(~CRTSCTS);
768 Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY);
769 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
770 break;
771
772 case FLOW_HARDWARE:
773 Posix_CommConfig.c_cflag|=CRTSCTS;
774 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
775 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
776 break;
777 }
778 }
779 UNLOCK_MUTEX();
780}
781
782/*!
783\fn void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec);
784Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
785Note that this is a per-character timeout, i.e. the port will wait this long for each
786individual character, not for the whole read operation. This timeout also applies to the
787bytesWaiting() function.
788
789\note
790POSIX does not support millisecond-level control for I/O timeout values. Any
791timeout set using this function will be set to the next lowest tenth of a second for
792the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds
793will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
794writing the port. However millisecond-level control is allowed by the select() system call,
795so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
796the purpose of detecting available bytes in the read buffer.
797
798*/
799void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec)
800{
801 LOCK_MUTEX();
802 Settings.Timeout_Sec=sec;
803 Settings.Timeout_Millisec=millisec;
804 Posix_Copy_Timeout.tv_sec=sec;
805 Posix_Copy_Timeout.tv_usec=millisec;
806 if (isOpen()) {
807 tcgetattr(Posix_File->handle(), &Posix_CommConfig);
808 Posix_CommConfig.c_cc[VTIME]=sec*10+millisec/100;
809 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
810 }
811 UNLOCK_MUTEX();
812}
813
814/*!
815\fn bool Posix_QextSerialPort::open(OpenMode mode)
816Opens the serial port associated to this class.
817This function has no effect if the port associated with the class is already open.
818The port is also configured to the current settings, as stored in the Settings structure.
819*/
820bool Posix_QextSerialPort::open(OpenMode mode)
821{
822 LOCK_MUTEX();
823 if (mode == QIODevice::NotOpen)
824 return isOpen();
825 if (!isOpen()) {
826 /*open the port*/
827 Posix_File->setFileName(port);
828 //// qDebug("Trying to open File");
829 if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) {
830 /// qDebug("Opened File succesfully");
831 /*set open mode*/
832 QIODevice::open(mode);
833
834 /*configure port settings*/
835 tcgetattr(Posix_File->handle(), &Posix_CommConfig);
836
837 /*set up other port settings*/
838 Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
839 Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
840 Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
841 Posix_CommConfig.c_oflag&=(~OPOST);
842 Posix_CommConfig.c_cc[VMIN]=0;
843 Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE;
844 Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE;
845 Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE;
846 Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE;
847 Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE;
848 setBaudRate(Settings.BaudRate);
849 setDataBits(Settings.DataBits);
850 setParity(Settings.Parity);
851 setStopBits(Settings.StopBits);
852 setFlowControl(Settings.FlowControl);
853 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
854 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
855 } else {
856 qDebug("Could not open File! Error code : %d", Posix_File->error());
857 }
858 }
859 UNLOCK_MUTEX();
860 return isOpen();
861}
862
863/*!
864\fn void Posix_QextSerialPort::close()
865Closes a serial port. This function has no effect if the serial port associated with the class
866is not currently open.
867*/
868void Posix_QextSerialPort::close()
869{
870 LOCK_MUTEX();
871 Posix_File->close();
872 QIODevice::close();
873 UNLOCK_MUTEX();
874}
875
876/*!
877\fn void Posix_QextSerialPort::flush()
878Flushes all pending I/O to the serial port. This function has no effect if the serial port
879associated with the class is not currently open.
880*/
881void Posix_QextSerialPort::flush()
882{
883 LOCK_MUTEX();
884 if (isOpen()) {
885 Posix_File->flush();
886 }
887 UNLOCK_MUTEX();
888}
889
890/*!
891\fn qint64 Posix_QextSerialPort::size() const
892This function will return the number of bytes waiting in the receive queue of the serial port.
893It is included primarily to provide a complete QIODevice interface, and will not record errors
894in the lastErr member (because it is const). This function is also not thread-safe - in
895multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead.
896*/
897qint64 Posix_QextSerialPort::size() const
898{
899 int numBytes;
900 if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) {
901 numBytes=0;
902 }
903 return (qint64)numBytes;
904}
905
906/*!
907\fn qint64 Posix_QextSerialPort::bytesAvailable()
908Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
909the port is not currently open, or -1 on error. Error information can be retrieved by calling
910Posix_QextSerialPort::getLastError().
911*/
912qint64 Posix_QextSerialPort::bytesAvailable()
913{
914 LOCK_MUTEX();
915 if (isOpen()) {
916 int bytesQueued;
917 fd_set fileSet;
918 FD_ZERO(&fileSet);
919 FD_SET(Posix_File->handle(), &fileSet);
920
921 /*on Linux systems the Posix_Timeout structure will be altered by the select() call.
922 Make sure we use the right timeout values*/
923 //memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval));
924 Posix_Timeout = Posix_Copy_Timeout;
925 int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout);
926 if (!n) {
927 lastErr=E_PORT_TIMEOUT;
928 UNLOCK_MUTEX();
929 return -1;
930 }
931 if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) {
932 translateError(errno);
933 UNLOCK_MUTEX();
934 return -1;
935 }
936 lastErr=E_NO_ERROR;
937 UNLOCK_MUTEX();
938 return bytesQueued + QIODevice::bytesAvailable();
939 }
940 UNLOCK_MUTEX();
941 return 0;
942}
943
944/*!
945\fn void Posix_QextSerialPort::ungetChar(char)
946This function is included to implement the full QIODevice interface, and currently has no
947purpose within this class. This function is meaningless on an unbuffered device and currently
948only prints a warning message to that effect.
949*/
950void Posix_QextSerialPort::ungetChar(char)
951{
952 /*meaningless on unbuffered sequential device - return error and print a warning*/
953 TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
954}
955
956/*!
957\fn void Posix_QextSerialPort::translateError(ulong error)
958Translates a system-specific error code to a QextSerialPort error code. Used internally.
959*/
960void Posix_QextSerialPort::translateError(ulong error)
961{
962 switch (error) {
963 case EBADF:
964 case ENOTTY:
965 lastErr=E_INVALID_FD;
966 break;
967
968 case EINTR:
969 lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL;
970 break;
971
972 case ENOMEM:
973 lastErr=E_NO_MEMORY;
974 break;
975 }
976}
977
978/*!
979\fn void Posix_QextSerialPort::setDtr(bool set)
980Sets DTR line to the requested state (high by default). This function will have no effect if
981the port associated with the class is not currently open.
982*/
983void Posix_QextSerialPort::setDtr(bool set)
984{
985 LOCK_MUTEX();
986 if (isOpen()) {
987 int status;
988 ioctl(Posix_File->handle(), TIOCMGET, &status);
989 if (set) {
990 status|=TIOCM_DTR;
991 }
992 else {
993 status&=~TIOCM_DTR;
994 }
995 ioctl(Posix_File->handle(), TIOCMSET, &status);
996 }
997 UNLOCK_MUTEX();
998}
999
1000/*!
1001\fn void Posix_QextSerialPort::setRts(bool set)
1002Sets RTS line to the requested state (high by default). This function will have no effect if
1003the port associated with the class is not currently open.
1004*/
1005void Posix_QextSerialPort::setRts(bool set)
1006{
1007 LOCK_MUTEX();
1008 if (isOpen()) {
1009 int status;
1010 ioctl(Posix_File->handle(), TIOCMGET, &status);
1011 if (set) {
1012 status|=TIOCM_RTS;
1013 }
1014 else {
1015 status&=~TIOCM_RTS;
1016 }
1017 ioctl(Posix_File->handle(), TIOCMSET, &status);
1018 }
1019 UNLOCK_MUTEX();
1020}
1021
1022/*!
1023\fn unsigned long Posix_QextSerialPort::lineStatus()
1024returns the line status as stored by the port function. This function will retrieve the states
1025of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
1026can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
1027long with specific bits indicating which lines are high. The following constants should be used
1028to examine the states of individual lines:
1029
1030\verbatim
1031Mask Line
1032------ ----
1033LS_CTS CTS
1034LS_DSR DSR
1035LS_DCD DCD
1036LS_RI RI
1037LS_RTS RTS (POSIX only)
1038LS_DTR DTR (POSIX only)
1039LS_ST Secondary TXD (POSIX only)
1040LS_SR Secondary RXD (POSIX only)
1041\endverbatim
1042
1043This function will return 0 if the port associated with the class is not currently open.
1044*/
1045unsigned long Posix_QextSerialPort::lineStatus()
1046{
1047 unsigned long Status=0, Temp=0;
1048 LOCK_MUTEX();
1049 if (isOpen()) {
1050 ioctl(Posix_File->handle(), TIOCMGET, &Temp);
1051 if (Temp&TIOCM_CTS) {
1052 Status|=LS_CTS;
1053 }
1054 if (Temp&TIOCM_DSR) {
1055 Status|=LS_DSR;
1056 }
1057 if (Temp&TIOCM_RI) {
1058 Status|=LS_RI;
1059 }
1060 if (Temp&TIOCM_CD) {
1061 Status|=LS_DCD;
1062 }
1063 if (Temp&TIOCM_DTR) {
1064 Status|=LS_DTR;
1065 }
1066 if (Temp&TIOCM_RTS) {
1067 Status|=LS_RTS;
1068 }
1069 if (Temp&TIOCM_ST) {
1070 Status|=LS_ST;
1071 }
1072 if (Temp&TIOCM_SR) {
1073 Status|=LS_SR;
1074 }
1075 }
1076 UNLOCK_MUTEX();
1077 return Status;
1078}
1079
1080/*!
1081\fn qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1082Reads a block of data from the serial port. This function will read at most maxSize bytes from
1083the serial port and place them in the buffer pointed to by data. Return value is the number of
1084bytes actually read, or -1 on error.
1085
1086\warning before calling this function ensure that serial port associated with this class
1087is currently open (use isOpen() function to check if port is open).
1088*/
1089qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1090{
1091 LOCK_MUTEX();
1092 int retVal=0;
1093 retVal=Posix_File->read(data, maxSize);
1094 if (retVal==-1)
1095 lastErr=E_READ_FAILED;
1096 UNLOCK_MUTEX();
1097
1098 return retVal;
1099}
1100
1101/*!
1102\fn qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1103Writes a block of data to the serial port. This function will write maxSize bytes
1104from the buffer pointed to by data to the serial port. Return value is the number
1105of bytes actually written, or -1 on error.
1106
1107\warning before calling this function ensure that serial port associated with this class
1108is currently open (use isOpen() function to check if port is open).
1109*/
1110qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1111{
1112 LOCK_MUTEX();
1113 int retVal=0;
1114 retVal=Posix_File->write(data, maxSize);
1115 if (retVal==-1)
1116 lastErr=E_WRITE_FAILED;
1117 UNLOCK_MUTEX();
1118
1119 flush();
1120 return retVal;
1121}
Note: See TracBrowser for help on using the repository browser.