Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
157 KeyOz 1
 
2
/*!
3
\class Posix_QextSerialPort
4
\version 1.0.0
5
\author Stefan Sander
6
 
7
A cross-platform serial port class.
8
This class encapsulates the POSIX portion of QextSerialPort.  The user will be notified of errors
9
and possible portability conflicts at run-time by default - this behavior can be turned off by
10
defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability
11
warnings) 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()
19
Default constructor.  Note that the name of the device used by a QextSerialPort constructed with
20
this constructor will be determined by #defined constants, or lack thereof - the default behavior
21
is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants are:
22
 
23
\verbatim
24
 
25
Constant         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
 
37
This constructor assigns the device name to the name of the first port on the specified system.
38
See the other constructors if you need to open a different port.
39
*/
40
Posix_QextSerialPort::Posix_QextSerialPort()
41
: QextSerialBase()
42
{
43
    Posix_File=new QFile();
44
}
45
 
46
/*!
47
\fn Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort&)
48
Copy constructor.
49
*/
50
Posix_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)
71
Constructs a serial port attached to the port specified by name.
72
name is the name of the device, which is windowsystem-specific,
73
e.g."COM1" or "/dev/ttyS0".
74
*/
75
Posix_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)
83
Constructs a port with default name and specified settings.
84
*/
85
Posix_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)
100
Constructs a port with specified name and settings.
101
*/
102
Posix_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)
117
Override the = operator.
118
*/
119
Posix_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()
139
Standard destructor.
140
*/
141
Posix_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)
152
Sets the baud rate of the serial port.  Note that not all rates are applicable on
153
all platforms.  The following table shows translations of the various baud rate
154
constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
155
are speeds that are usable on both Windows and POSIX.
156
 
157
\note
158
BAUD76800 may not be supported on all POSIX systems.  SGI/IRIX systems do not support
159
BAUD1800.
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
*/
189
void 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)
496
Sets 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
505
This 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
*/
512
void 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)
585
Sets 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
595
This function is subject to the following limitations:
596
\par
597
POSIX systems do not support mark parity.
598
\par
599
POSIX 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
*/
603
void 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)
678
Sets 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
685
This 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
*/
692
void 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)
734
Sets 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
741
FLOW_HARDWARE may not be supported on all versions of UNIX.  In cases where it is
742
unsupported, FLOW_HARDWARE is the same as FLOW_OFF.
743
 
744
*/
745
void 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);
780
Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
781
Note that this is a per-character timeout, i.e. the port will wait this long for each
782
individual character, not for the whole read operation.  This timeout also applies to the
783
bytesWaiting() function.
784
 
785
\note
786
POSIX does not support millisecond-level control for I/O timeout values.  Any
787
timeout set using this function will be set to the next lowest tenth of a second for
788
the purposes of detecting read or write timeouts.  For example a timeout of 550 milliseconds
789
will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
790
writing the port.  However millisecond-level control is allowed by the select() system call,
791
so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
792
the purpose of detecting available bytes in the read buffer.
793
 
794
*/
795
void 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)
812
Opens the serial port associated to this class.
813
This function has no effect if the port associated with the class is already open.
814
The port is also configured to the current settings, as stored in the Settings structure.
815
*/
816
bool 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()
861
Closes a serial port.  This function has no effect if the serial port associated with the class
862
is not currently open.
863
*/
864
void 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()
874
Flushes all pending I/O to the serial port.  This function has no effect if the serial port
875
associated with the class is not currently open.
876
*/
877
void 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
888
This function will return the number of bytes waiting in the receive queue of the serial port.
889
It is included primarily to provide a complete QIODevice interface, and will not record errors
890
in the lastErr member (because it is const).  This function is also not thread-safe - in
891
multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead.
892
*/
893
qint64 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()
904
Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
905
the port is not currently open, or -1 on error.  Error information can be retrieved by calling
906
Posix_QextSerialPort::getLastError().
907
*/
908
qint64 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)
942
This function is included to implement the full QIODevice interface, and currently has no
943
purpose within this class.  This function is meaningless on an unbuffered device and currently
944
only prints a warning message to that effect.
945
*/
946
void 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)
954
Translates a system-specific error code to a QextSerialPort error code.  Used internally.
955
*/
956
void 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)
976
Sets DTR line to the requested state (high by default).  This function will have no effect if
977
the port associated with the class is not currently open.
978
*/
979
void 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)
998
Sets RTS line to the requested state (high by default).  This function will have no effect if
999
the port associated with the class is not currently open.
1000
*/
1001
void 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()
1020
returns the line status as stored by the port function.  This function will retrieve the states
1021
of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
1022
can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
1023
long with specific bits indicating which lines are high.  The following constants should be used
1024
to examine the states of individual lines:
1025
 
1026
\verbatim
1027
Mask        Line
1028
------      ----
1029
LS_CTS      CTS
1030
LS_DSR      DSR
1031
LS_DCD      DCD
1032
LS_RI       RI
1033
LS_RTS      RTS (POSIX only)
1034
LS_DTR      DTR (POSIX only)
1035
LS_ST       Secondary TXD (POSIX only)
1036
LS_SR       Secondary RXD (POSIX only)
1037
\endverbatim
1038
 
1039
This function will return 0 if the port associated with the class is not currently open.
1040
*/
1041
unsigned 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)
1078
Reads a block of data from the serial port.  This function will read at most maxSize bytes from
1079
the serial port and place them in the buffer pointed to by data.  Return value is the number of
1080
bytes actually read, or -1 on error.
1081
 
1082
\warning before calling this function ensure that serial port associated with this class
1083
is currently open (use isOpen() function to check if port is open).
1084
*/
1085
qint64 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)
1099
Writes a block of data to the serial port.  This function will write maxSize bytes
1100
from the buffer pointed to by data to the serial port.  Return value is the number
1101
of bytes actually written, or -1 on error.
1102
 
1103
\warning before calling this function ensure that serial port associated with this class
1104
is currently open (use isOpen() function to check if port is open).
1105
*/
1106
qint64 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
}