source: ntrip/trunk/BNC/serial/posix_qextserialport.cpp@ 1317

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