|
qCNC 0.82-alpha
|
00001 00002 00003 #include <fcntl.h> 00004 #include <stdio.h> 00005 #include "qextserialport.h" 00006 #include <QMutexLocker> 00007 #include <QDebug> 00008 00009 void QextSerialPort::platformSpecificInit() 00010 { 00011 fd = 0; 00012 readNotifier = 0; 00013 } 00014 00018 void QextSerialPort::platformSpecificDestruct() 00019 {} 00020 00059 void QextSerialPort::setBaudRate(BaudRateType baudRate) 00060 { 00061 QMutexLocker lock(mutex); 00062 if (Settings.BaudRate!=baudRate) { 00063 switch (baudRate) { 00064 case BAUD14400: 00065 Settings.BaudRate=BAUD9600; 00066 break; 00067 00068 case BAUD56000: 00069 Settings.BaudRate=BAUD38400; 00070 break; 00071 00072 case BAUD76800: 00073 00074 #ifndef B76800 00075 Settings.BaudRate=BAUD57600; 00076 #else 00077 Settings.BaudRate=baudRate; 00078 #endif 00079 break; 00080 00081 case BAUD128000: 00082 case BAUD256000: 00083 Settings.BaudRate=BAUD115200; 00084 break; 00085 00086 default: 00087 Settings.BaudRate=baudRate; 00088 break; 00089 } 00090 } 00091 if (isOpen()) { 00092 switch (baudRate) { 00093 00094 /*50 baud*/ 00095 case BAUD50: 00096 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 50 baud operation."); 00097 #ifdef CBAUD 00098 Posix_CommConfig.c_cflag&=(~CBAUD); 00099 Posix_CommConfig.c_cflag|=B50; 00100 #else 00101 cfsetispeed(&Posix_CommConfig, B50); 00102 cfsetospeed(&Posix_CommConfig, B50); 00103 #endif 00104 break; 00105 00106 /*75 baud*/ 00107 case BAUD75: 00108 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 75 baud operation."); 00109 #ifdef CBAUD 00110 Posix_CommConfig.c_cflag&=(~CBAUD); 00111 Posix_CommConfig.c_cflag|=B75; 00112 #else 00113 cfsetispeed(&Posix_CommConfig, B75); 00114 cfsetospeed(&Posix_CommConfig, B75); 00115 #endif 00116 break; 00117 00118 /*110 baud*/ 00119 case BAUD110: 00120 #ifdef CBAUD 00121 Posix_CommConfig.c_cflag&=(~CBAUD); 00122 Posix_CommConfig.c_cflag|=B110; 00123 #else 00124 cfsetispeed(&Posix_CommConfig, B110); 00125 cfsetospeed(&Posix_CommConfig, B110); 00126 #endif 00127 break; 00128 00129 /*134.5 baud*/ 00130 case BAUD134: 00131 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 134.5 baud operation."); 00132 #ifdef CBAUD 00133 Posix_CommConfig.c_cflag&=(~CBAUD); 00134 Posix_CommConfig.c_cflag|=B134; 00135 #else 00136 cfsetispeed(&Posix_CommConfig, B134); 00137 cfsetospeed(&Posix_CommConfig, B134); 00138 #endif 00139 break; 00140 00141 /*150 baud*/ 00142 case BAUD150: 00143 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 150 baud operation."); 00144 #ifdef CBAUD 00145 Posix_CommConfig.c_cflag&=(~CBAUD); 00146 Posix_CommConfig.c_cflag|=B150; 00147 #else 00148 cfsetispeed(&Posix_CommConfig, B150); 00149 cfsetospeed(&Posix_CommConfig, B150); 00150 #endif 00151 break; 00152 00153 /*200 baud*/ 00154 case BAUD200: 00155 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 200 baud operation."); 00156 #ifdef CBAUD 00157 Posix_CommConfig.c_cflag&=(~CBAUD); 00158 Posix_CommConfig.c_cflag|=B200; 00159 #else 00160 cfsetispeed(&Posix_CommConfig, B200); 00161 cfsetospeed(&Posix_CommConfig, B200); 00162 #endif 00163 break; 00164 00165 /*300 baud*/ 00166 case BAUD300: 00167 #ifdef CBAUD 00168 Posix_CommConfig.c_cflag&=(~CBAUD); 00169 Posix_CommConfig.c_cflag|=B300; 00170 #else 00171 cfsetispeed(&Posix_CommConfig, B300); 00172 cfsetospeed(&Posix_CommConfig, B300); 00173 #endif 00174 break; 00175 00176 /*600 baud*/ 00177 case BAUD600: 00178 #ifdef CBAUD 00179 Posix_CommConfig.c_cflag&=(~CBAUD); 00180 Posix_CommConfig.c_cflag|=B600; 00181 #else 00182 cfsetispeed(&Posix_CommConfig, B600); 00183 cfsetospeed(&Posix_CommConfig, B600); 00184 #endif 00185 break; 00186 00187 /*1200 baud*/ 00188 case BAUD1200: 00189 #ifdef CBAUD 00190 Posix_CommConfig.c_cflag&=(~CBAUD); 00191 Posix_CommConfig.c_cflag|=B1200; 00192 #else 00193 cfsetispeed(&Posix_CommConfig, B1200); 00194 cfsetospeed(&Posix_CommConfig, B1200); 00195 #endif 00196 break; 00197 00198 /*1800 baud*/ 00199 case BAUD1800: 00200 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation."); 00201 #ifdef CBAUD 00202 Posix_CommConfig.c_cflag&=(~CBAUD); 00203 Posix_CommConfig.c_cflag|=B1800; 00204 #else 00205 cfsetispeed(&Posix_CommConfig, B1800); 00206 cfsetospeed(&Posix_CommConfig, B1800); 00207 #endif 00208 break; 00209 00210 /*2400 baud*/ 00211 case BAUD2400: 00212 #ifdef CBAUD 00213 Posix_CommConfig.c_cflag&=(~CBAUD); 00214 Posix_CommConfig.c_cflag|=B2400; 00215 #else 00216 cfsetispeed(&Posix_CommConfig, B2400); 00217 cfsetospeed(&Posix_CommConfig, B2400); 00218 #endif 00219 break; 00220 00221 /*4800 baud*/ 00222 case BAUD4800: 00223 #ifdef CBAUD 00224 Posix_CommConfig.c_cflag&=(~CBAUD); 00225 Posix_CommConfig.c_cflag|=B4800; 00226 #else 00227 cfsetispeed(&Posix_CommConfig, B4800); 00228 cfsetospeed(&Posix_CommConfig, B4800); 00229 #endif 00230 break; 00231 00232 /*9600 baud*/ 00233 case BAUD9600: 00234 #ifdef CBAUD 00235 Posix_CommConfig.c_cflag&=(~CBAUD); 00236 Posix_CommConfig.c_cflag|=B9600; 00237 #else 00238 cfsetispeed(&Posix_CommConfig, B9600); 00239 cfsetospeed(&Posix_CommConfig, B9600); 00240 #endif 00241 break; 00242 00243 /*14400 baud*/ 00244 case BAUD14400: 00245 TTY_WARNING("QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud."); 00246 #ifdef CBAUD 00247 Posix_CommConfig.c_cflag&=(~CBAUD); 00248 Posix_CommConfig.c_cflag|=B9600; 00249 #else 00250 cfsetispeed(&Posix_CommConfig, B9600); 00251 cfsetospeed(&Posix_CommConfig, B9600); 00252 #endif 00253 break; 00254 00255 /*19200 baud*/ 00256 case BAUD19200: 00257 #ifdef CBAUD 00258 Posix_CommConfig.c_cflag&=(~CBAUD); 00259 Posix_CommConfig.c_cflag|=B19200; 00260 #else 00261 cfsetispeed(&Posix_CommConfig, B19200); 00262 cfsetospeed(&Posix_CommConfig, B19200); 00263 #endif 00264 break; 00265 00266 /*38400 baud*/ 00267 case BAUD38400: 00268 #ifdef CBAUD 00269 Posix_CommConfig.c_cflag&=(~CBAUD); 00270 Posix_CommConfig.c_cflag|=B38400; 00271 #else 00272 cfsetispeed(&Posix_CommConfig, B38400); 00273 cfsetospeed(&Posix_CommConfig, B38400); 00274 #endif 00275 break; 00276 00277 /*56000 baud*/ 00278 case BAUD56000: 00279 TTY_WARNING("QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud."); 00280 #ifdef CBAUD 00281 Posix_CommConfig.c_cflag&=(~CBAUD); 00282 Posix_CommConfig.c_cflag|=B38400; 00283 #else 00284 cfsetispeed(&Posix_CommConfig, B38400); 00285 cfsetospeed(&Posix_CommConfig, B38400); 00286 #endif 00287 break; 00288 00289 /*57600 baud*/ 00290 case BAUD57600: 00291 #ifdef CBAUD 00292 Posix_CommConfig.c_cflag&=(~CBAUD); 00293 Posix_CommConfig.c_cflag|=B57600; 00294 #else 00295 cfsetispeed(&Posix_CommConfig, B57600); 00296 cfsetospeed(&Posix_CommConfig, B57600); 00297 #endif 00298 break; 00299 00300 /*76800 baud*/ 00301 case BAUD76800: 00302 TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation."); 00303 #ifdef CBAUD 00304 Posix_CommConfig.c_cflag&=(~CBAUD); 00305 00306 #ifdef B76800 00307 Posix_CommConfig.c_cflag|=B76800; 00308 #else 00309 TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); 00310 Posix_CommConfig.c_cflag|=B57600; 00311 #endif //B76800 00312 #else //CBAUD 00313 #ifdef B76800 00314 cfsetispeed(&Posix_CommConfig, B76800); 00315 cfsetospeed(&Posix_CommConfig, B76800); 00316 #else 00317 TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); 00318 cfsetispeed(&Posix_CommConfig, B57600); 00319 cfsetospeed(&Posix_CommConfig, B57600); 00320 #endif //B76800 00321 #endif //CBAUD 00322 break; 00323 00324 /*115200 baud*/ 00325 case BAUD115200: 00326 #ifdef CBAUD 00327 Posix_CommConfig.c_cflag&=(~CBAUD); 00328 Posix_CommConfig.c_cflag|=B115200; 00329 #else 00330 cfsetispeed(&Posix_CommConfig, B115200); 00331 cfsetospeed(&Posix_CommConfig, B115200); 00332 #endif 00333 break; 00334 00335 /*128000 baud*/ 00336 case BAUD128000: 00337 TTY_WARNING("QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud."); 00338 #ifdef CBAUD 00339 Posix_CommConfig.c_cflag&=(~CBAUD); 00340 Posix_CommConfig.c_cflag|=B115200; 00341 #else 00342 cfsetispeed(&Posix_CommConfig, B115200); 00343 cfsetospeed(&Posix_CommConfig, B115200); 00344 #endif 00345 break; 00346 00347 /*256000 baud*/ 00348 case BAUD256000: 00349 TTY_WARNING("QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud."); 00350 #ifdef CBAUD 00351 Posix_CommConfig.c_cflag&=(~CBAUD); 00352 Posix_CommConfig.c_cflag|=B115200; 00353 #else 00354 cfsetispeed(&Posix_CommConfig, B115200); 00355 cfsetospeed(&Posix_CommConfig, B115200); 00356 #endif 00357 break; 00358 } 00359 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00360 } 00361 } 00362 00379 void QextSerialPort::setDataBits(DataBitsType dataBits) 00380 { 00381 QMutexLocker lock(mutex); 00382 if (Settings.DataBits!=dataBits) { 00383 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || 00384 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) || 00385 (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) { 00386 } 00387 else { 00388 Settings.DataBits=dataBits; 00389 } 00390 } 00391 if (isOpen()) { 00392 switch(dataBits) { 00393 00394 /*5 data bits*/ 00395 case DATA_5: 00396 if (Settings.StopBits==STOP_2) { 00397 TTY_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); 00398 } 00399 else { 00400 Settings.DataBits=dataBits; 00401 Posix_CommConfig.c_cflag&=(~CSIZE); 00402 Posix_CommConfig.c_cflag|=CS5; 00403 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00404 } 00405 break; 00406 00407 /*6 data bits*/ 00408 case DATA_6: 00409 if (Settings.StopBits==STOP_1_5) { 00410 TTY_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); 00411 } 00412 else { 00413 Settings.DataBits=dataBits; 00414 Posix_CommConfig.c_cflag&=(~CSIZE); 00415 Posix_CommConfig.c_cflag|=CS6; 00416 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00417 } 00418 break; 00419 00420 /*7 data bits*/ 00421 case DATA_7: 00422 if (Settings.StopBits==STOP_1_5) { 00423 TTY_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); 00424 } 00425 else { 00426 Settings.DataBits=dataBits; 00427 Posix_CommConfig.c_cflag&=(~CSIZE); 00428 Posix_CommConfig.c_cflag|=CS7; 00429 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00430 } 00431 break; 00432 00433 /*8 data bits*/ 00434 case DATA_8: 00435 if (Settings.StopBits==STOP_1_5) { 00436 TTY_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); 00437 } 00438 else { 00439 Settings.DataBits=dataBits; 00440 Posix_CommConfig.c_cflag&=(~CSIZE); 00441 Posix_CommConfig.c_cflag|=CS8; 00442 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00443 } 00444 break; 00445 } 00446 } 00447 } 00448 00467 void QextSerialPort::setParity(ParityType parity) 00468 { 00469 QMutexLocker lock(mutex); 00470 if (Settings.Parity!=parity) { 00471 if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) { 00472 } 00473 else { 00474 Settings.Parity=parity; 00475 } 00476 } 00477 if (isOpen()) { 00478 switch (parity) { 00479 00480 /*space parity*/ 00481 case PAR_SPACE: 00482 if (Settings.DataBits==DATA_8) { 00483 TTY_PORTABILITY_WARNING("QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits"); 00484 } 00485 else { 00486 00487 /*space parity not directly supported - add an extra data bit to simulate it*/ 00488 Posix_CommConfig.c_cflag&=~(PARENB|CSIZE); 00489 switch(Settings.DataBits) { 00490 case DATA_5: 00491 Settings.DataBits=DATA_6; 00492 Posix_CommConfig.c_cflag|=CS6; 00493 break; 00494 00495 case DATA_6: 00496 Settings.DataBits=DATA_7; 00497 Posix_CommConfig.c_cflag|=CS7; 00498 break; 00499 00500 case DATA_7: 00501 Settings.DataBits=DATA_8; 00502 Posix_CommConfig.c_cflag|=CS8; 00503 break; 00504 00505 case DATA_8: 00506 break; 00507 } 00508 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00509 } 00510 break; 00511 00512 /*mark parity - WINDOWS ONLY*/ 00513 case PAR_MARK: 00514 TTY_WARNING("QextSerialPort: Mark parity is not supported by POSIX."); 00515 break; 00516 00517 /*no parity*/ 00518 case PAR_NONE: 00519 Posix_CommConfig.c_cflag&=(~PARENB); 00520 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00521 break; 00522 00523 /*even parity*/ 00524 case PAR_EVEN: 00525 Posix_CommConfig.c_cflag&=(~PARODD); 00526 Posix_CommConfig.c_cflag|=PARENB; 00527 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00528 break; 00529 00530 /*odd parity*/ 00531 case PAR_ODD: 00532 Posix_CommConfig.c_cflag|=(PARENB|PARODD); 00533 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00534 break; 00535 } 00536 } 00537 } 00538 00554 void QextSerialPort::setStopBits(StopBitsType stopBits) 00555 { 00556 QMutexLocker lock(mutex); 00557 if (Settings.StopBits!=stopBits) { 00558 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {} 00559 else { 00560 Settings.StopBits=stopBits; 00561 } 00562 } 00563 if (isOpen()) { 00564 switch (stopBits) { 00565 00566 /*one stop bit*/ 00567 case STOP_1: 00568 Settings.StopBits=stopBits; 00569 Posix_CommConfig.c_cflag&=(~CSTOPB); 00570 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00571 break; 00572 00573 /*1.5 stop bits*/ 00574 case STOP_1_5: 00575 TTY_WARNING("QextSerialPort: 1.5 stop bit operation is not supported by POSIX."); 00576 break; 00577 00578 /*two stop bits*/ 00579 case STOP_2: 00580 if (Settings.DataBits==DATA_5) { 00581 TTY_WARNING("QextSerialPort: 2 stop bits cannot be used with 5 data bits"); 00582 } 00583 else { 00584 Settings.StopBits=stopBits; 00585 Posix_CommConfig.c_cflag|=CSTOPB; 00586 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00587 } 00588 break; 00589 } 00590 } 00591 } 00592 00605 void QextSerialPort::setFlowControl(FlowType flow) 00606 { 00607 QMutexLocker lock(mutex); 00608 if (Settings.FlowControl!=flow) { 00609 Settings.FlowControl=flow; 00610 } 00611 if (isOpen()) { 00612 switch(flow) { 00613 00614 /*no flow control*/ 00615 case FLOW_OFF: 00616 Posix_CommConfig.c_cflag&=(~CRTSCTS); 00617 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); 00618 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00619 break; 00620 00621 /*software (XON/XOFF) flow control*/ 00622 case FLOW_XONXOFF: 00623 Posix_CommConfig.c_cflag&=(~CRTSCTS); 00624 Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY); 00625 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00626 break; 00627 00628 case FLOW_HARDWARE: 00629 Posix_CommConfig.c_cflag|=CRTSCTS; 00630 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); 00631 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00632 break; 00633 } 00634 } 00635 } 00636 00653 void QextSerialPort::setTimeout(long millisec) 00654 { 00655 QMutexLocker lock(mutex); 00656 Settings.Timeout_Millisec = millisec; 00657 Posix_Copy_Timeout.tv_sec = millisec / 1000; 00658 Posix_Copy_Timeout.tv_usec = millisec % 1000; 00659 if (isOpen()) { 00660 if (millisec == -1) 00661 fcntl(fd, F_SETFL, O_NDELAY); 00662 else 00663 //O_SYNC should enable blocking ::write() 00664 //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) 00665 fcntl(fd, F_SETFL, O_SYNC); 00666 tcgetattr(fd, & Posix_CommConfig); 00667 Posix_CommConfig.c_cc[VTIME] = millisec/100; 00668 tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig); 00669 } 00670 } 00671 00677 bool QextSerialPort::open(OpenMode mode) 00678 { 00679 QMutexLocker lock(mutex); 00680 if (mode == QIODevice::NotOpen) 00681 return isOpen(); 00682 if (!isOpen()) { 00683 qDebug() << "trying to open file" << port.toAscii(); 00684 //note: linux 2.6.21 seems to ignore O_NDELAY flag 00685 if ((fd = ::open(port.toAscii() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) { 00686 qDebug("file opened succesfully"); 00687 00688 setOpenMode(mode); // Flag the port as opened 00689 tcgetattr(fd, &old_termios); // Save the old termios 00690 Posix_CommConfig = old_termios; // Make a working copy 00691 cfmakeraw(&Posix_CommConfig); // Enable raw access 00692 00693 /*set up other port settings*/ 00694 Posix_CommConfig.c_cflag|=CREAD|CLOCAL; 00695 Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); 00696 Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); 00697 Posix_CommConfig.c_oflag&=(~OPOST); 00698 Posix_CommConfig.c_cc[VMIN]= 0; 00699 #ifdef _POSIX_VDISABLE // Is a disable character available on this system? 00700 // Some systems allow for per-device disable-characters, so get the 00701 // proper value for the configured device 00702 const long vdisable = fpathconf(fd, _PC_VDISABLE); 00703 Posix_CommConfig.c_cc[VINTR] = vdisable; 00704 Posix_CommConfig.c_cc[VQUIT] = vdisable; 00705 Posix_CommConfig.c_cc[VSTART] = vdisable; 00706 Posix_CommConfig.c_cc[VSTOP] = vdisable; 00707 Posix_CommConfig.c_cc[VSUSP] = vdisable; 00708 #endif //_POSIX_VDISABLE 00709 setBaudRate(Settings.BaudRate); 00710 setDataBits(Settings.DataBits); 00711 setParity(Settings.Parity); 00712 setStopBits(Settings.StopBits); 00713 setFlowControl(Settings.FlowControl); 00714 setTimeout(Settings.Timeout_Millisec); 00715 tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig); 00716 00717 if (queryMode() == QextSerialPort::EventDriven) { 00718 readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); 00719 connect(readNotifier, SIGNAL(activated(int)), this, SIGNAL(readyRead())); 00720 } 00721 } else { 00722 qDebug() << "could not open file:" << strerror(errno); 00723 lastErr = E_FILE_NOT_FOUND; 00724 } 00725 } 00726 return isOpen(); 00727 } 00728 00733 void QextSerialPort::close() 00734 { 00735 QMutexLocker lock(mutex); 00736 if( isOpen() ) 00737 { 00738 // Force a flush and then restore the original termios 00739 flush(); 00740 // Using both TCSAFLUSH and TCSANOW here discards any pending input 00741 tcsetattr(fd, TCSAFLUSH | TCSANOW, &old_termios); // Restore termios 00742 // Be a good QIODevice and call QIODevice::close() before POSIX close() 00743 // so the aboutToClose() signal is emitted at the proper time 00744 QIODevice::close(); // Flag the device as closed 00745 // QIODevice::close() doesn't actually close the port, so do that here 00746 ::close(fd); 00747 if(readNotifier) { 00748 delete readNotifier; 00749 readNotifier = 0; 00750 } 00751 } 00752 } 00753 00758 void QextSerialPort::flush() 00759 { 00760 QMutexLocker lock(mutex); 00761 if (isOpen()) 00762 tcflush(fd, TCIOFLUSH); 00763 } 00764 00771 qint64 QextSerialPort::size() const 00772 { 00773 int numBytes; 00774 if (ioctl(fd, FIONREAD, &numBytes)<0) { 00775 numBytes = 0; 00776 } 00777 return (qint64)numBytes; 00778 } 00779 00784 qint64 QextSerialPort::bytesAvailable() const 00785 { 00786 QMutexLocker lock(mutex); 00787 if (isOpen()) { 00788 int bytesQueued; 00789 if (ioctl(fd, FIONREAD, &bytesQueued) == -1) { 00790 return (qint64)-1; 00791 } 00792 return bytesQueued + QIODevice::bytesAvailable(); 00793 } 00794 return 0; 00795 } 00796 00802 void QextSerialPort::ungetChar(char) 00803 { 00804 /*meaningless on unbuffered sequential device - return error and print a warning*/ 00805 TTY_WARNING("QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); 00806 } 00807 00811 void QextSerialPort::translateError(ulong error) 00812 { 00813 switch (error) { 00814 case EBADF: 00815 case ENOTTY: 00816 lastErr=E_INVALID_FD; 00817 break; 00818 00819 case EINTR: 00820 lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL; 00821 break; 00822 00823 case ENOMEM: 00824 lastErr=E_NO_MEMORY; 00825 break; 00826 } 00827 } 00828 00833 void QextSerialPort::setDtr(bool set) 00834 { 00835 QMutexLocker lock(mutex); 00836 if (isOpen()) { 00837 int status; 00838 ioctl(fd, TIOCMGET, &status); 00839 if (set) { 00840 status|=TIOCM_DTR; 00841 } 00842 else { 00843 status&=~TIOCM_DTR; 00844 } 00845 ioctl(fd, TIOCMSET, &status); 00846 } 00847 } 00848 00853 void QextSerialPort::setRts(bool set) 00854 { 00855 QMutexLocker lock(mutex); 00856 if (isOpen()) { 00857 int status; 00858 ioctl(fd, TIOCMGET, &status); 00859 if (set) { 00860 status|=TIOCM_RTS; 00861 } 00862 else { 00863 status&=~TIOCM_RTS; 00864 } 00865 ioctl(fd, TIOCMSET, &status); 00866 } 00867 } 00868 00891 unsigned long QextSerialPort::lineStatus() 00892 { 00893 unsigned long Status=0, Temp=0; 00894 QMutexLocker lock(mutex); 00895 if (isOpen()) { 00896 ioctl(fd, TIOCMGET, &Temp); 00897 if (Temp&TIOCM_CTS) { 00898 Status|=LS_CTS; 00899 } 00900 if (Temp&TIOCM_DSR) { 00901 Status|=LS_DSR; 00902 } 00903 if (Temp&TIOCM_RI) { 00904 Status|=LS_RI; 00905 } 00906 if (Temp&TIOCM_CD) { 00907 Status|=LS_DCD; 00908 } 00909 if (Temp&TIOCM_DTR) { 00910 Status|=LS_DTR; 00911 } 00912 if (Temp&TIOCM_RTS) { 00913 Status|=LS_RTS; 00914 } 00915 if (Temp&TIOCM_ST) { 00916 Status|=LS_ST; 00917 } 00918 if (Temp&TIOCM_SR) { 00919 Status|=LS_SR; 00920 } 00921 } 00922 return Status; 00923 } 00924 00933 qint64 QextSerialPort::readData(char * data, qint64 maxSize) 00934 { 00935 QMutexLocker lock(mutex); 00936 int retVal = ::read(fd, data, maxSize); 00937 if (retVal == -1) 00938 lastErr = E_READ_FAILED; 00939 00940 return retVal; 00941 } 00942 00951 qint64 QextSerialPort::writeData(const char * data, qint64 maxSize) 00952 { 00953 QMutexLocker lock(mutex); 00954 int retVal = ::write(fd, data, maxSize); 00955 if (retVal == -1) 00956 lastErr = E_WRITE_FAILED; 00957 00958 return (qint64)retVal; 00959 }