qCNC 0.82-alpha
/home/trilog/Desktop/project/gui/Final/src/lib/qextserialport/posix_qextserialport.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines