Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
170 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
                if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) {
825
                        /*set open mode*/
826
                        QIODevice::open(mode);
827
 
828
                        /*configure port settings*/
829
                        tcgetattr(Posix_File->handle(), &Posix_CommConfig);
830
 
831
                        /*set up other port settings*/
832
                        Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
833
                        Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
834
                        Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
835
                        Posix_CommConfig.c_oflag&=(~OPOST);
836
                        Posix_CommConfig.c_cc[VMIN]=0;
837
                        Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE;
838
                        Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE;
839
                        Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE;
840
                        Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE;
841
                        Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE;
842
                        setBaudRate(Settings.BaudRate);
843
                        setDataBits(Settings.DataBits);
844
                        setParity(Settings.Parity);
845
                        setStopBits(Settings.StopBits);
846
                        setFlowControl(Settings.FlowControl);
847
                        setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
848
                        tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
849
                } else {
850
                }
851
        }
852
        UNLOCK_MUTEX();
853
        return isOpen();
854
}
855
 
856
/*!
857
                \fn void Posix_QextSerialPort::close()
858
                        Closes a serial port.  This function has no effect if the serial port associated with the class
859
                        is not currently open.
860
*/
861
void Posix_QextSerialPort::close()
862
{
863
        LOCK_MUTEX();
864
        Posix_File->close();
865
        QIODevice::close();
866
        UNLOCK_MUTEX();
867
}
868
 
869
/*!
870
                \fn void Posix_QextSerialPort::flush()
871
                        Flushes all pending I/O to the serial port.  This function has no effect if the serial port
872
                        associated with the class is not currently open.
873
*/
874
void Posix_QextSerialPort::flush()
875
{
876
        LOCK_MUTEX();
877
        if (isOpen()) {
878
                Posix_File->flush();
879
        }
880
        UNLOCK_MUTEX();
881
}
882
 
883
/*!
884
                \fn qint64 Posix_QextSerialPort::size() const
885
This function will return the number of bytes waiting in the receive queue of the serial port.
886
                It is included primarily to provide a complete QIODevice interface, and will not record errors
887
                in the lastErr member (because it is const).  This function is also not thread-safe - in
888
                multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead.
889
*/
890
qint64 Posix_QextSerialPort::size() const
891
{
892
        int numBytes;
893
        if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) {
894
                numBytes=0;
895
        }
896
        return (qint64)numBytes;
897
}
898
 
899
/*!
900
                \fn qint64 Posix_QextSerialPort::bytesAvailable()
901
                        Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
902
                        the port is not currently open, or -1 on error.  Error information can be retrieved by calling
903
                        Posix_QextSerialPort::getLastError().
904
*/
905
qint64 Posix_QextSerialPort::bytesAvailable()
906
{
907
        LOCK_MUTEX();
908
        if (isOpen()) {
909
                int bytesQueued;
910
                fd_set fileSet;
911
                FD_ZERO(&fileSet);
912
                FD_SET(Posix_File->handle(), &fileSet);
913
 
914
                /*on Linux systems the Posix_Timeout structure will be altered by the select() call.
915
                                Make sure we use the right timeout values*/
916
                //memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval));
917
                Posix_Timeout = Posix_Copy_Timeout;
918
                int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout);
919
                if (!n) {
920
                        lastErr=E_PORT_TIMEOUT;
921
                        UNLOCK_MUTEX();
922
                        return -1;
923
                }
924
                if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) {
925
                        translateError(errno);
926
                        UNLOCK_MUTEX();
927
                        return -1;
928
                }
929
                lastErr=E_NO_ERROR;
930
                UNLOCK_MUTEX();
931
                return bytesQueued + QIODevice::bytesAvailable();
932
        }
933
        UNLOCK_MUTEX();
934
        return 0;
935
}
936
 
937
/*!
938
                \fn void Posix_QextSerialPort::ungetChar(char)
939
                        This function is included to implement the full QIODevice interface, and currently has no
940
                        purpose within this class.  This function is meaningless on an unbuffered device and currently
941
                        only prints a warning message to that effect.
942
*/
943
void Posix_QextSerialPort::ungetChar(char)
944
{
945
        /*meaningless on unbuffered sequential device - return error and print a warning*/
946
        TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
947
}
948
 
949
/*!
950
                \fn void Posix_QextSerialPort::translateError(ulong error)
951
                        Translates a system-specific error code to a QextSerialPort error code.  Used internally.
952
*/
953
void Posix_QextSerialPort::translateError(ulong error)
954
{
955
        switch (error) {
956
                case EBADF:
957
                case ENOTTY:
958
                        lastErr=E_INVALID_FD;
959
                        break;
960
 
961
                case EINTR:
962
                        lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL;
963
                        break;
964
 
965
                case ENOMEM:
966
                        lastErr=E_NO_MEMORY;
967
                        break;
968
                }
969
}
970
 
971
/*!
972
                \fn void Posix_QextSerialPort::setDtr(bool set)
973
                        Sets DTR line to the requested state (high by default).  This function will have no effect if
974
                        the port associated with the class is not currently open.
975
*/
976
void Posix_QextSerialPort::setDtr(bool set)
977
{
978
        LOCK_MUTEX();
979
        if (isOpen()) {
980
                int status;
981
                ioctl(Posix_File->handle(), TIOCMGET, &status);
982
                if (set) {
983
                        status|=TIOCM_DTR;
984
                }
985
                else {
986
                        status&=~TIOCM_DTR;
987
                }
988
                ioctl(Posix_File->handle(), TIOCMSET, &status);
989
        }
990
        UNLOCK_MUTEX();
991
}
992
 
993
/*!
994
                \fn void Posix_QextSerialPort::setRts(bool set)
995
                        Sets RTS line to the requested state (high by default).  This function will have no effect if
996
                        the port associated with the class is not currently open.
997
*/
998
void Posix_QextSerialPort::setRts(bool set)
999
{
1000
        LOCK_MUTEX();
1001
        if (isOpen()) {
1002
                int status;
1003
                ioctl(Posix_File->handle(), TIOCMGET, &status);
1004
                if (set) {
1005
                        status|=TIOCM_RTS;
1006
                }
1007
                else {
1008
                        status&=~TIOCM_RTS;
1009
                }
1010
                ioctl(Posix_File->handle(), TIOCMSET, &status);
1011
        }
1012
        UNLOCK_MUTEX();
1013
}
1014
 
1015
/*!
1016
                \fn unsigned long Posix_QextSerialPort::lineStatus()
1017
                        returns the line status as stored by the port function.  This function will retrieve the states
1018
                        of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
1019
                        can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
1020
                        long with specific bits indicating which lines are high.  The following constants should be used
1021
                        to examine the states of individual lines:
1022
 
1023
\verbatim
1024
                Mask        Line
1025
                ------      ----
1026
                LS_CTS      CTS
1027
                LS_DSR      DSR
1028
                LS_DCD      DCD
1029
                LS_RI       RI
1030
                LS_RTS      RTS (POSIX only)
1031
                        LS_DTR      DTR (POSIX only)
1032
                                LS_ST       Secondary TXD (POSIX only)
1033
                                        LS_SR       Secondary RXD (POSIX only)
1034
                                                \endverbatim
1035
 
1036
This function will return 0 if the port associated with the class is not currently open.
1037
*/
1038
unsigned long Posix_QextSerialPort::lineStatus()
1039
{
1040
        unsigned long Status=0, Temp=0;
1041
        LOCK_MUTEX();
1042
        if (isOpen()) {
1043
                ioctl(Posix_File->handle(), TIOCMGET, &Temp);
1044
                if (Temp&TIOCM_CTS) {
1045
                        Status|=LS_CTS;
1046
                }
1047
                if (Temp&TIOCM_DSR) {
1048
                        Status|=LS_DSR;
1049
                }
1050
                if (Temp&TIOCM_RI) {
1051
                        Status|=LS_RI;
1052
                }
1053
                if (Temp&TIOCM_CD) {
1054
                        Status|=LS_DCD;
1055
                }
1056
                if (Temp&TIOCM_DTR) {
1057
                        Status|=LS_DTR;
1058
                }
1059
                if (Temp&TIOCM_RTS) {
1060
                        Status|=LS_RTS;
1061
                }
1062
                if (Temp&TIOCM_ST) {
1063
                        Status|=LS_ST;
1064
                }
1065
                if (Temp&TIOCM_SR) {
1066
                        Status|=LS_SR;
1067
                }
1068
        }
1069
        UNLOCK_MUTEX();
1070
        return Status;
1071
}
1072
 
1073
/*!
1074
                \fn qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1075
                        Reads a block of data from the serial port.  This function will read at most maxSize bytes from
1076
                        the serial port and place them in the buffer pointed to by data.  Return value is the number of
1077
                        bytes actually read, or -1 on error.
1078
 
1079
\warning before calling this function ensure that serial port associated with this class
1080
                is currently open (use isOpen() function to check if port is open).
1081
*/
1082
qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1083
{
1084
        LOCK_MUTEX();
1085
        int retVal=0;
1086
        retVal=Posix_File->read(data, maxSize);
1087
        if (retVal==-1)
1088
                lastErr=E_READ_FAILED;
1089
        UNLOCK_MUTEX();
1090
 
1091
        return retVal;
1092
}
1093
 
1094
/*!
1095
                \fn qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1096
                        Writes a block of data to the serial port.  This function will write maxSize bytes
1097
                        from the buffer pointed to by data to the serial port.  Return value is the number
1098
                        of bytes actually written, or -1 on error.
1099
 
1100
\warning before calling this function ensure that serial port associated with this class
1101
                is currently open (use isOpen() function to check if port is open).
1102
*/
1103
qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1104
{
1105
        LOCK_MUTEX();
1106
        int retVal=0;
1107
        retVal=Posix_File->write(data, maxSize);
1108
        if (retVal==-1)
1109
                lastErr=E_WRITE_FAILED;
1110
        UNLOCK_MUTEX();
1111
 
1112
        flush();
1113
        return retVal;
1114
}