~ubuntu-branches/ubuntu/quantal/marble/quantal

« back to all changes in this revision

Viewing changes to src/plugins/render/aprs/posix_qextserialport.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Philip Muškovac
  • Date: 2011-07-11 15:43:02 UTC
  • Revision ID: james.westby@ubuntu.com-20110711154302-lq69ftcx125g1jx5
Tags: upstream-4.6.90+repack
Import upstream version 4.6.90+repack

Show diffs side-by-side

added added

removed removed

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