QlightRead package | ESS final project 1.22-beta
|
00001 00014 #include <stdio.h> 00015 #include "posix_qextserialport.h" 00016 00040 Posix_QextSerialPort::Posix_QextSerialPort() 00041 : QextSerialBase() 00042 { 00043 Posix_File=new QFile(); 00044 } 00045 00050 Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort& s) 00051 : QextSerialBase(s.port) 00052 { 00053 setOpenMode(s.openMode()); 00054 port = s.port; 00055 Settings.BaudRate=s.Settings.BaudRate; 00056 Settings.DataBits=s.Settings.DataBits; 00057 Settings.Parity=s.Settings.Parity; 00058 Settings.StopBits=s.Settings.StopBits; 00059 Settings.FlowControl=s.Settings.FlowControl; 00060 lastErr=s.lastErr; 00061 00062 Posix_File=new QFile(); 00063 Posix_File=s.Posix_File; 00064 memcpy(&Posix_Timeout, &s.Posix_Timeout, sizeof(struct timeval)); 00065 memcpy(&Posix_Copy_Timeout, &s.Posix_Copy_Timeout, sizeof(struct timeval)); 00066 memcpy(&Posix_CommConfig, &s.Posix_CommConfig, sizeof(struct termios)); 00067 } 00068 00075 Posix_QextSerialPort::Posix_QextSerialPort(const QString & name) 00076 : QextSerialBase(name) 00077 { 00078 Posix_File=new QFile(); 00079 } 00080 00085 Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings) 00086 : QextSerialBase() 00087 { 00088 setBaudRate(settings.BaudRate); 00089 setDataBits(settings.DataBits); 00090 setParity(settings.Parity); 00091 setStopBits(settings.StopBits); 00092 setFlowControl(settings.FlowControl); 00093 00094 Posix_File=new QFile(); 00095 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); 00096 } 00097 00102 Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings) 00103 : QextSerialBase(name) 00104 { 00105 setBaudRate(settings.BaudRate); 00106 setDataBits(settings.DataBits); 00107 setParity(settings.Parity); 00108 setStopBits(settings.StopBits); 00109 setFlowControl(settings.FlowControl); 00110 00111 Posix_File=new QFile(); 00112 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); 00113 } 00114 00119 Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s) 00120 { 00121 setOpenMode(s.openMode()); 00122 port = s.port; 00123 Settings.BaudRate=s.Settings.BaudRate; 00124 Settings.DataBits=s.Settings.DataBits; 00125 Settings.Parity=s.Settings.Parity; 00126 Settings.StopBits=s.Settings.StopBits; 00127 Settings.FlowControl=s.Settings.FlowControl; 00128 lastErr=s.lastErr; 00129 00130 Posix_File=s.Posix_File; 00131 memcpy(&Posix_Timeout, &(s.Posix_Timeout), sizeof(struct timeval)); 00132 memcpy(&Posix_Copy_Timeout, &(s.Posix_Copy_Timeout), sizeof(struct timeval)); 00133 memcpy(&Posix_CommConfig, &(s.Posix_CommConfig), sizeof(struct termios)); 00134 return *this; 00135 } 00136 00141 Posix_QextSerialPort::~Posix_QextSerialPort() 00142 { 00143 if (isOpen()) { 00144 close(); 00145 } 00146 Posix_File->close(); 00147 delete Posix_File; 00148 } 00149 00189 void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate) 00190 { 00191 LOCK_MUTEX(); 00192 if (Settings.BaudRate!=baudRate) { 00193 switch (baudRate) { 00194 case BAUD14400: 00195 Settings.BaudRate=BAUD9600; 00196 break; 00197 00198 case BAUD56000: 00199 Settings.BaudRate=BAUD38400; 00200 break; 00201 00202 case BAUD76800: 00203 00204 #ifndef B76800 00205 Settings.BaudRate=BAUD57600; 00206 #else 00207 Settings.BaudRate=baudRate; 00208 #endif 00209 break; 00210 00211 case BAUD128000: 00212 case BAUD256000: 00213 Settings.BaudRate=BAUD115200; 00214 break; 00215 00216 default: 00217 Settings.BaudRate=baudRate; 00218 break; 00219 } 00220 } 00221 if (isOpen()) { 00222 switch (baudRate) { 00223 00224 /*50 baud*/ 00225 case BAUD50: 00226 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation."); 00227 #ifdef CBAUD 00228 Posix_CommConfig.c_cflag&=(~CBAUD); 00229 Posix_CommConfig.c_cflag|=B50; 00230 #else 00231 cfsetispeed(&Posix_CommConfig, B50); 00232 cfsetospeed(&Posix_CommConfig, B50); 00233 #endif 00234 break; 00235 00236 /*75 baud*/ 00237 case BAUD75: 00238 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation."); 00239 #ifdef CBAUD 00240 Posix_CommConfig.c_cflag&=(~CBAUD); 00241 Posix_CommConfig.c_cflag|=B75; 00242 #else 00243 cfsetispeed(&Posix_CommConfig, B75); 00244 cfsetospeed(&Posix_CommConfig, B75); 00245 #endif 00246 break; 00247 00248 /*110 baud*/ 00249 case BAUD110: 00250 #ifdef CBAUD 00251 Posix_CommConfig.c_cflag&=(~CBAUD); 00252 Posix_CommConfig.c_cflag|=B110; 00253 #else 00254 cfsetispeed(&Posix_CommConfig, B110); 00255 cfsetospeed(&Posix_CommConfig, B110); 00256 #endif 00257 break; 00258 00259 /*134.5 baud*/ 00260 case BAUD134: 00261 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation."); 00262 #ifdef CBAUD 00263 Posix_CommConfig.c_cflag&=(~CBAUD); 00264 Posix_CommConfig.c_cflag|=B134; 00265 #else 00266 cfsetispeed(&Posix_CommConfig, B134); 00267 cfsetospeed(&Posix_CommConfig, B134); 00268 #endif 00269 break; 00270 00271 /*150 baud*/ 00272 case BAUD150: 00273 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation."); 00274 #ifdef CBAUD 00275 Posix_CommConfig.c_cflag&=(~CBAUD); 00276 Posix_CommConfig.c_cflag|=B150; 00277 #else 00278 cfsetispeed(&Posix_CommConfig, B150); 00279 cfsetospeed(&Posix_CommConfig, B150); 00280 #endif 00281 break; 00282 00283 /*200 baud*/ 00284 case BAUD200: 00285 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation."); 00286 #ifdef CBAUD 00287 Posix_CommConfig.c_cflag&=(~CBAUD); 00288 Posix_CommConfig.c_cflag|=B200; 00289 #else 00290 cfsetispeed(&Posix_CommConfig, B200); 00291 cfsetospeed(&Posix_CommConfig, B200); 00292 #endif 00293 break; 00294 00295 /*300 baud*/ 00296 case BAUD300: 00297 #ifdef CBAUD 00298 Posix_CommConfig.c_cflag&=(~CBAUD); 00299 Posix_CommConfig.c_cflag|=B300; 00300 #else 00301 cfsetispeed(&Posix_CommConfig, B300); 00302 cfsetospeed(&Posix_CommConfig, B300); 00303 #endif 00304 break; 00305 00306 /*600 baud*/ 00307 case BAUD600: 00308 #ifdef CBAUD 00309 Posix_CommConfig.c_cflag&=(~CBAUD); 00310 Posix_CommConfig.c_cflag|=B600; 00311 #else 00312 cfsetispeed(&Posix_CommConfig, B600); 00313 cfsetospeed(&Posix_CommConfig, B600); 00314 #endif 00315 break; 00316 00317 /*1200 baud*/ 00318 case BAUD1200: 00319 #ifdef CBAUD 00320 Posix_CommConfig.c_cflag&=(~CBAUD); 00321 Posix_CommConfig.c_cflag|=B1200; 00322 #else 00323 cfsetispeed(&Posix_CommConfig, B1200); 00324 cfsetospeed(&Posix_CommConfig, B1200); 00325 #endif 00326 break; 00327 00328 /*1800 baud*/ 00329 case BAUD1800: 00330 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation."); 00331 #ifdef CBAUD 00332 Posix_CommConfig.c_cflag&=(~CBAUD); 00333 Posix_CommConfig.c_cflag|=B1800; 00334 #else 00335 cfsetispeed(&Posix_CommConfig, B1800); 00336 cfsetospeed(&Posix_CommConfig, B1800); 00337 #endif 00338 break; 00339 00340 /*2400 baud*/ 00341 case BAUD2400: 00342 #ifdef CBAUD 00343 Posix_CommConfig.c_cflag&=(~CBAUD); 00344 Posix_CommConfig.c_cflag|=B2400; 00345 #else 00346 cfsetispeed(&Posix_CommConfig, B2400); 00347 cfsetospeed(&Posix_CommConfig, B2400); 00348 #endif 00349 break; 00350 00351 /*4800 baud*/ 00352 case BAUD4800: 00353 #ifdef CBAUD 00354 Posix_CommConfig.c_cflag&=(~CBAUD); 00355 Posix_CommConfig.c_cflag|=B4800; 00356 #else 00357 cfsetispeed(&Posix_CommConfig, B4800); 00358 cfsetospeed(&Posix_CommConfig, B4800); 00359 #endif 00360 break; 00361 00362 /*9600 baud*/ 00363 case BAUD9600: 00364 #ifdef CBAUD 00365 Posix_CommConfig.c_cflag&=(~CBAUD); 00366 Posix_CommConfig.c_cflag|=B9600; 00367 #else 00368 cfsetispeed(&Posix_CommConfig, B9600); 00369 cfsetospeed(&Posix_CommConfig, B9600); 00370 #endif 00371 break; 00372 00373 /*14400 baud*/ 00374 case BAUD14400: 00375 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud."); 00376 #ifdef CBAUD 00377 Posix_CommConfig.c_cflag&=(~CBAUD); 00378 Posix_CommConfig.c_cflag|=B9600; 00379 #else 00380 cfsetispeed(&Posix_CommConfig, B9600); 00381 cfsetospeed(&Posix_CommConfig, B9600); 00382 #endif 00383 break; 00384 00385 /*19200 baud*/ 00386 case BAUD19200: 00387 #ifdef CBAUD 00388 Posix_CommConfig.c_cflag&=(~CBAUD); 00389 Posix_CommConfig.c_cflag|=B19200; 00390 #else 00391 cfsetispeed(&Posix_CommConfig, B19200); 00392 cfsetospeed(&Posix_CommConfig, B19200); 00393 #endif 00394 break; 00395 00396 /*38400 baud*/ 00397 case BAUD38400: 00398 #ifdef CBAUD 00399 Posix_CommConfig.c_cflag&=(~CBAUD); 00400 Posix_CommConfig.c_cflag|=B38400; 00401 #else 00402 cfsetispeed(&Posix_CommConfig, B38400); 00403 cfsetospeed(&Posix_CommConfig, B38400); 00404 #endif 00405 break; 00406 00407 /*56000 baud*/ 00408 case BAUD56000: 00409 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud."); 00410 #ifdef CBAUD 00411 Posix_CommConfig.c_cflag&=(~CBAUD); 00412 Posix_CommConfig.c_cflag|=B38400; 00413 #else 00414 cfsetispeed(&Posix_CommConfig, B38400); 00415 cfsetospeed(&Posix_CommConfig, B38400); 00416 #endif 00417 break; 00418 00419 /*57600 baud*/ 00420 case BAUD57600: 00421 #ifdef CBAUD 00422 Posix_CommConfig.c_cflag&=(~CBAUD); 00423 Posix_CommConfig.c_cflag|=B57600; 00424 #else 00425 cfsetispeed(&Posix_CommConfig, B57600); 00426 cfsetospeed(&Posix_CommConfig, B57600); 00427 #endif 00428 break; 00429 00430 /*76800 baud*/ 00431 case BAUD76800: 00432 TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation."); 00433 #ifdef CBAUD 00434 Posix_CommConfig.c_cflag&=(~CBAUD); 00435 00436 #ifdef B76800 00437 Posix_CommConfig.c_cflag|=B76800; 00438 #else 00439 TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); 00440 Posix_CommConfig.c_cflag|=B57600; 00441 #endif //B76800 00442 #else //CBAUD 00443 #ifdef B76800 00444 cfsetispeed(&Posix_CommConfig, B76800); 00445 cfsetospeed(&Posix_CommConfig, B76800); 00446 #else 00447 TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); 00448 cfsetispeed(&Posix_CommConfig, B57600); 00449 cfsetospeed(&Posix_CommConfig, B57600); 00450 #endif //B76800 00451 #endif //CBAUD 00452 break; 00453 00454 /*115200 baud*/ 00455 case BAUD115200: 00456 #ifdef CBAUD 00457 Posix_CommConfig.c_cflag&=(~CBAUD); 00458 Posix_CommConfig.c_cflag|=B115200; 00459 #else 00460 cfsetispeed(&Posix_CommConfig, B115200); 00461 cfsetospeed(&Posix_CommConfig, B115200); 00462 #endif 00463 break; 00464 00465 /*128000 baud*/ 00466 case BAUD128000: 00467 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud."); 00468 #ifdef CBAUD 00469 Posix_CommConfig.c_cflag&=(~CBAUD); 00470 Posix_CommConfig.c_cflag|=B115200; 00471 #else 00472 cfsetispeed(&Posix_CommConfig, B115200); 00473 cfsetospeed(&Posix_CommConfig, B115200); 00474 #endif 00475 break; 00476 00477 /*256000 baud*/ 00478 case BAUD256000: 00479 TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud."); 00480 #ifdef CBAUD 00481 Posix_CommConfig.c_cflag&=(~CBAUD); 00482 Posix_CommConfig.c_cflag|=B115200; 00483 #else 00484 cfsetispeed(&Posix_CommConfig, B115200); 00485 cfsetospeed(&Posix_CommConfig, B115200); 00486 #endif 00487 break; 00488 } 00489 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00490 } 00491 UNLOCK_MUTEX(); 00492 } 00493 00512 void Posix_QextSerialPort::setDataBits(DataBitsType dataBits) 00513 { 00514 LOCK_MUTEX(); 00515 if (Settings.DataBits!=dataBits) { 00516 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || 00517 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) || 00518 (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) { 00519 } 00520 else { 00521 Settings.DataBits=dataBits; 00522 } 00523 } 00524 if (isOpen()) { 00525 switch(dataBits) { 00526 00527 /*5 data bits*/ 00528 case DATA_5: 00529 if (Settings.StopBits==STOP_2) { 00530 TTY_WARNING("Posix_QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); 00531 } 00532 else { 00533 Settings.DataBits=dataBits; 00534 Posix_CommConfig.c_cflag&=(~CSIZE); 00535 Posix_CommConfig.c_cflag|=CS5; 00536 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00537 } 00538 break; 00539 00540 /*6 data bits*/ 00541 case DATA_6: 00542 if (Settings.StopBits==STOP_1_5) { 00543 TTY_WARNING("Posix_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); 00544 } 00545 else { 00546 Settings.DataBits=dataBits; 00547 Posix_CommConfig.c_cflag&=(~CSIZE); 00548 Posix_CommConfig.c_cflag|=CS6; 00549 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00550 } 00551 break; 00552 00553 /*7 data bits*/ 00554 case DATA_7: 00555 if (Settings.StopBits==STOP_1_5) { 00556 TTY_WARNING("Posix_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); 00557 } 00558 else { 00559 Settings.DataBits=dataBits; 00560 Posix_CommConfig.c_cflag&=(~CSIZE); 00561 Posix_CommConfig.c_cflag|=CS7; 00562 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00563 } 00564 break; 00565 00566 /*8 data bits*/ 00567 case DATA_8: 00568 if (Settings.StopBits==STOP_1_5) { 00569 TTY_WARNING("Posix_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); 00570 } 00571 else { 00572 Settings.DataBits=dataBits; 00573 Posix_CommConfig.c_cflag&=(~CSIZE); 00574 Posix_CommConfig.c_cflag|=CS8; 00575 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00576 } 00577 break; 00578 } 00579 } 00580 UNLOCK_MUTEX(); 00581 } 00582 00603 void Posix_QextSerialPort::setParity(ParityType parity) 00604 { 00605 LOCK_MUTEX(); 00606 if (Settings.Parity!=parity) { 00607 if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) { 00608 } 00609 else { 00610 Settings.Parity=parity; 00611 } 00612 } 00613 if (isOpen()) { 00614 switch (parity) { 00615 00616 /*space parity*/ 00617 case PAR_SPACE: 00618 if (Settings.DataBits==DATA_8) { 00619 TTY_PORTABILITY_WARNING("Posix_QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits"); 00620 } 00621 else { 00622 00623 /*space parity not directly supported - add an extra data bit to simulate it*/ 00624 Posix_CommConfig.c_cflag&=~(PARENB|CSIZE); 00625 switch(Settings.DataBits) { 00626 case DATA_5: 00627 Settings.DataBits=DATA_6; 00628 Posix_CommConfig.c_cflag|=CS6; 00629 break; 00630 00631 case DATA_6: 00632 Settings.DataBits=DATA_7; 00633 Posix_CommConfig.c_cflag|=CS7; 00634 break; 00635 00636 case DATA_7: 00637 Settings.DataBits=DATA_8; 00638 Posix_CommConfig.c_cflag|=CS8; 00639 break; 00640 00641 case DATA_8: 00642 break; 00643 } 00644 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00645 } 00646 break; 00647 00648 /*mark parity - WINDOWS ONLY*/ 00649 case PAR_MARK: 00650 TTY_WARNING("Posix_QextSerialPort: Mark parity is not supported by POSIX."); 00651 break; 00652 00653 /*no parity*/ 00654 case PAR_NONE: 00655 Posix_CommConfig.c_cflag&=(~PARENB); 00656 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00657 break; 00658 00659 /*even parity*/ 00660 case PAR_EVEN: 00661 Posix_CommConfig.c_cflag&=(~PARODD); 00662 Posix_CommConfig.c_cflag|=PARENB; 00663 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00664 break; 00665 00666 /*odd parity*/ 00667 case PAR_ODD: 00668 Posix_CommConfig.c_cflag|=(PARENB|PARODD); 00669 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00670 break; 00671 } 00672 } 00673 UNLOCK_MUTEX(); 00674 } 00675 00692 void Posix_QextSerialPort::setStopBits(StopBitsType stopBits) 00693 { 00694 LOCK_MUTEX(); 00695 if (Settings.StopBits!=stopBits) { 00696 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {} 00697 else { 00698 Settings.StopBits=stopBits; 00699 } 00700 } 00701 if (isOpen()) { 00702 switch (stopBits) { 00703 00704 /*one stop bit*/ 00705 case STOP_1: 00706 Settings.StopBits=stopBits; 00707 Posix_CommConfig.c_cflag&=(~CSTOPB); 00708 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00709 break; 00710 00711 /*1.5 stop bits*/ 00712 case STOP_1_5: 00713 TTY_WARNING("Posix_QextSerialPort: 1.5 stop bit operation is not supported by POSIX."); 00714 break; 00715 00716 /*two stop bits*/ 00717 case STOP_2: 00718 if (Settings.DataBits==DATA_5) { 00719 TTY_WARNING("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits"); 00720 } 00721 else { 00722 Settings.StopBits=stopBits; 00723 Posix_CommConfig.c_cflag|=CSTOPB; 00724 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00725 } 00726 break; 00727 } 00728 } 00729 UNLOCK_MUTEX(); 00730 } 00731 00745 void Posix_QextSerialPort::setFlowControl(FlowType flow) 00746 { 00747 LOCK_MUTEX(); 00748 if (Settings.FlowControl!=flow) { 00749 Settings.FlowControl=flow; 00750 } 00751 if (isOpen()) { 00752 switch(flow) { 00753 00754 /*no flow control*/ 00755 case FLOW_OFF: 00756 Posix_CommConfig.c_cflag&=(~CRTSCTS); 00757 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); 00758 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00759 break; 00760 00761 /*software (XON/XOFF) flow control*/ 00762 case FLOW_XONXOFF: 00763 Posix_CommConfig.c_cflag&=(~CRTSCTS); 00764 Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY); 00765 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00766 break; 00767 00768 case FLOW_HARDWARE: 00769 Posix_CommConfig.c_cflag|=CRTSCTS; 00770 Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); 00771 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00772 break; 00773 } 00774 } 00775 UNLOCK_MUTEX(); 00776 } 00777 00795 void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec) 00796 { 00797 LOCK_MUTEX(); 00798 Settings.Timeout_Sec=sec; 00799 Settings.Timeout_Millisec=millisec; 00800 Posix_Copy_Timeout.tv_sec=sec; 00801 Posix_Copy_Timeout.tv_usec=millisec; 00802 if (isOpen()) { 00803 tcgetattr(Posix_File->handle(), &Posix_CommConfig); 00804 Posix_CommConfig.c_cc[VTIME]=sec*10+millisec/100; 00805 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00806 } 00807 UNLOCK_MUTEX(); 00808 } 00809 00816 bool Posix_QextSerialPort::open(OpenMode mode) 00817 { 00818 LOCK_MUTEX(); 00819 if (mode == QIODevice::NotOpen) 00820 return isOpen(); 00821 if (!isOpen()) { 00822 /*open the port*/ 00823 Posix_File->setFileName(port); 00824 qDebug("Trying to open File"); 00825 if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { 00826 qDebug("Opened File succesfully"); 00827 /*set open mode*/ 00828 QIODevice::open(mode); 00829 00830 /*configure port settings*/ 00831 tcgetattr(Posix_File->handle(), &Posix_CommConfig); 00832 00833 /*set up other port settings*/ 00834 Posix_CommConfig.c_cflag|=CREAD|CLOCAL; 00835 Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); 00836 Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); 00837 Posix_CommConfig.c_oflag&=(~OPOST); 00838 Posix_CommConfig.c_cc[VMIN]=0; 00839 Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE; 00840 Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE; 00841 Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE; 00842 Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE; 00843 Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE; 00844 setBaudRate(Settings.BaudRate); 00845 setDataBits(Settings.DataBits); 00846 setParity(Settings.Parity); 00847 setStopBits(Settings.StopBits); 00848 setFlowControl(Settings.FlowControl); 00849 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec); 00850 tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); 00851 } else { 00852 qDebug("Could not open File! Error code : %d", Posix_File->error()); 00853 } 00854 } 00855 UNLOCK_MUTEX(); 00856 return isOpen(); 00857 } 00858 00864 void Posix_QextSerialPort::close() 00865 { 00866 LOCK_MUTEX(); 00867 Posix_File->close(); 00868 QIODevice::close(); 00869 UNLOCK_MUTEX(); 00870 } 00871 00877 void Posix_QextSerialPort::flush() 00878 { 00879 LOCK_MUTEX(); 00880 if (isOpen()) { 00881 Posix_File->flush(); 00882 } 00883 UNLOCK_MUTEX(); 00884 } 00885 00893 qint64 Posix_QextSerialPort::size() const 00894 { 00895 int numBytes; 00896 if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) { 00897 numBytes=0; 00898 } 00899 return (qint64)numBytes; 00900 } 00901 00908 qint64 Posix_QextSerialPort::bytesAvailable() 00909 { 00910 LOCK_MUTEX(); 00911 if (isOpen()) { 00912 int bytesQueued; 00913 fd_set fileSet; 00914 FD_ZERO(&fileSet); 00915 FD_SET(Posix_File->handle(), &fileSet); 00916 00917 /*on Linux systems the Posix_Timeout structure will be altered by the select() call. 00918 Make sure we use the right timeout values*/ 00919 //memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval)); 00920 Posix_Timeout = Posix_Copy_Timeout; 00921 int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout); 00922 if (!n) { 00923 lastErr=E_PORT_TIMEOUT; 00924 UNLOCK_MUTEX(); 00925 return -1; 00926 } 00927 if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) { 00928 translateError(errno); 00929 UNLOCK_MUTEX(); 00930 return -1; 00931 } 00932 lastErr=E_NO_ERROR; 00933 UNLOCK_MUTEX(); 00934 return bytesQueued + QIODevice::bytesAvailable(); 00935 } 00936 UNLOCK_MUTEX(); 00937 return 0; 00938 } 00939 00946 void Posix_QextSerialPort::ungetChar(char) 00947 { 00948 /*meaningless on unbuffered sequential device - return error and print a warning*/ 00949 TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); 00950 } 00951 00956 void Posix_QextSerialPort::translateError(ulong error) 00957 { 00958 switch (error) { 00959 case EBADF: 00960 case ENOTTY: 00961 lastErr=E_INVALID_FD; 00962 break; 00963 00964 case EINTR: 00965 lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL; 00966 break; 00967 00968 case ENOMEM: 00969 lastErr=E_NO_MEMORY; 00970 break; 00971 } 00972 } 00973 00979 void Posix_QextSerialPort::setDtr(bool set) 00980 { 00981 LOCK_MUTEX(); 00982 if (isOpen()) { 00983 int status; 00984 ioctl(Posix_File->handle(), TIOCMGET, &status); 00985 if (set) { 00986 status|=TIOCM_DTR; 00987 } 00988 else { 00989 status&=~TIOCM_DTR; 00990 } 00991 ioctl(Posix_File->handle(), TIOCMSET, &status); 00992 } 00993 UNLOCK_MUTEX(); 00994 } 00995 01001 void Posix_QextSerialPort::setRts(bool set) 01002 { 01003 LOCK_MUTEX(); 01004 if (isOpen()) { 01005 int status; 01006 ioctl(Posix_File->handle(), TIOCMGET, &status); 01007 if (set) { 01008 status|=TIOCM_RTS; 01009 } 01010 else { 01011 status&=~TIOCM_RTS; 01012 } 01013 ioctl(Posix_File->handle(), TIOCMSET, &status); 01014 } 01015 UNLOCK_MUTEX(); 01016 } 01017 01041 unsigned long Posix_QextSerialPort::lineStatus() 01042 { 01043 unsigned long Status=0, Temp=0; 01044 LOCK_MUTEX(); 01045 if (isOpen()) { 01046 ioctl(Posix_File->handle(), TIOCMGET, &Temp); 01047 if (Temp&TIOCM_CTS) { 01048 Status|=LS_CTS; 01049 } 01050 if (Temp&TIOCM_DSR) { 01051 Status|=LS_DSR; 01052 } 01053 if (Temp&TIOCM_RI) { 01054 Status|=LS_RI; 01055 } 01056 if (Temp&TIOCM_CD) { 01057 Status|=LS_DCD; 01058 } 01059 if (Temp&TIOCM_DTR) { 01060 Status|=LS_DTR; 01061 } 01062 if (Temp&TIOCM_RTS) { 01063 Status|=LS_RTS; 01064 } 01065 if (Temp&TIOCM_ST) { 01066 Status|=LS_ST; 01067 } 01068 if (Temp&TIOCM_SR) { 01069 Status|=LS_SR; 01070 } 01071 } 01072 UNLOCK_MUTEX(); 01073 return Status; 01074 } 01075 01085 qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize) 01086 { 01087 LOCK_MUTEX(); 01088 int retVal=0; 01089 retVal=Posix_File->read(data, maxSize); 01090 if (retVal==-1) 01091 lastErr=E_READ_FAILED; 01092 UNLOCK_MUTEX(); 01093 01094 return retVal; 01095 } 01096 01106 qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize) 01107 { 01108 LOCK_MUTEX(); 01109 int retVal=0; 01110 retVal=Posix_File->write(data, maxSize); 01111 if (retVal==-1) 01112 lastErr=E_WRITE_FAILED; 01113 UNLOCK_MUTEX(); 01114 01115 flush(); 01116 return retVal; 01117 }