Qt实现串口编程

34 篇文章 0 订阅

作者:zgrjkflmkyc

转自:http://blog.csdn.net/zgrjkflmkyc/article/details/17206417


windows下Qt实现串口编程的例子,仅作参考(Qt 5.1.1环境下编译运行通过):

工程所需文件如图

所有文件源代码

  1. /************mainwindow.h*************/  
  2.   
  3. #ifndef MAINWINDOW_H  
  4. #define MAINWINDOW_H  
  5.   
  6. #include <QMainWindow>  
  7. #include <QTextBrowser>  
  8. #include <QLabel>  
  9. #include "win_qextserialport.h"  
  10.   
  11. class MainWindow : public QMainWindow  
  12. {  
  13.     Q_OBJECT  
  14.   
  15. public:  
  16.     MainWindow(QWidget *parent = 0);  
  17.     ~MainWindow();  
  18.     Win_QextSerialPort *myCom;  
  19.     QTextBrowser *text;  
  20. public slots:  
  21.     void readMyCom();  
  22. };  
  23.   
  24. #endif // MAINWINDOW_H  

  1. /*************qextserialbase.h*************/  
  2.   
  3. #ifndef _QEXTSERIALBASE_H_  
  4. #define _QEXTSERIALBASE_H_  
  5.   
  6. #include <QIODevice>  
  7. #include <QFile>  
  8. #include <QThread>  
  9. #include <QMutex>  
  10.   
  11. /*if all warning messages are turned off, flag portability warnings to be turned off as well*/  
  12. #ifdef _TTY_NOWARN_  
  13. #define _TTY_NOWARN_PORT_  
  14. #endif  
  15.   
  16. /*macros for thread support*/  
  17. #define LOCK_MUTEX() mutex->lock()  
  18. #define UNLOCK_MUTEX() mutex->unlock()  
  19.   
  20. /*macros for warning and debug messages*/  
  21. #ifdef _TTY_NOWARN_PORT_  
  22. #define TTY_PORTABILITY_WARNING(s)  
  23. #else  
  24. #define TTY_PORTABILITY_WARNING(s) qWarning(s)  
  25. #endif /*_TTY_NOWARN_PORT_*/  
  26. #ifdef _TTY_NOWARN_  
  27. #define TTY_WARNING(s)  
  28. #else  
  29. #define TTY_WARNING(s) qWarning(s)  
  30. #endif /*_TTY_NOWARN_*/  
  31.   
  32.   
  33. /*line status constants*/  
  34. #define LS_CTS  0x01  
  35. #define LS_DSR  0x02  
  36. #define LS_DCD  0x04  
  37. #define LS_RI   0x08  
  38. #define LS_RTS  0x10  
  39. #define LS_DTR  0x20  
  40. #define LS_ST   0x40  
  41. #define LS_SR   0x80  
  42.   
  43. /*error constants*/  
  44. #define E_NO_ERROR                   0  
  45. #define E_INVALID_FD                 1  
  46. #define E_NO_MEMORY                  2  
  47. #define E_CAUGHT_NON_BLOCKED_SIGNAL  3  
  48. #define E_PORT_TIMEOUT               4  
  49. #define E_INVALID_DEVICE             5  
  50. #define E_BREAK_CONDITION            6  
  51. #define E_FRAMING_ERROR              7  
  52. #define E_IO_ERROR                   8  
  53. #define E_BUFFER_OVERRUN             9  
  54. #define E_RECEIVE_OVERFLOW          10  
  55. #define E_RECEIVE_PARITY_ERROR      11  
  56. #define E_TRANSMIT_OVERFLOW         12  
  57. #define E_READ_FAILED               13  
  58. #define E_WRITE_FAILED              14  
  59.   
  60. /*! 
  61.  * Enums for port settings. 
  62.  */  
  63. enum NamingConvention   
  64. {  
  65.     WIN_NAMES,  
  66.     IRIX_NAMES,  
  67.     HPUX_NAMES,  
  68.     SUN_NAMES,  
  69.     DIGITAL_NAMES,  
  70.     FREEBSD_NAMES,  
  71.     LINUX_NAMES  
  72. };  
  73.   
  74. enum BaudRateType   
  75. {  
  76.     BAUD50,                //POSIX ONLY  
  77.     BAUD75,                //POSIX ONLY  
  78.     BAUD110,  
  79.     BAUD134,               //POSIX ONLY  
  80.     BAUD150,               //POSIX ONLY  
  81.     BAUD200,               //POSIX ONLY  
  82.     BAUD300,  
  83.     BAUD600,  
  84.     BAUD1200,  
  85.     BAUD1800,              //POSIX ONLY  
  86.     BAUD2400,  
  87.     BAUD4800,  
  88.     BAUD9600,  
  89.     BAUD14400,             //WINDOWS ONLY  
  90.     BAUD19200,  
  91.     BAUD38400,  
  92.     BAUD56000,             //WINDOWS ONLY  
  93.     BAUD57600,  
  94.     BAUD76800,             //POSIX ONLY  
  95.     BAUD115200,  
  96.     BAUD128000,            //WINDOWS ONLY  
  97.     BAUD256000             //WINDOWS ONLY  
  98. };  
  99.   
  100. enum DataBitsType   
  101. {  
  102.     DATA_5,  
  103.     DATA_6,  
  104.     DATA_7,  
  105.     DATA_8  
  106. };  
  107.   
  108. enum ParityType   
  109. {  
  110.     PAR_NONE,  
  111.     PAR_ODD,  
  112.     PAR_EVEN,  
  113.     PAR_MARK,               //WINDOWS ONLY  
  114.     PAR_SPACE  
  115. };  
  116.   
  117. enum StopBitsType   
  118. {  
  119.     STOP_1,  
  120.     STOP_1_5,               //WINDOWS ONLY  
  121.     STOP_2  
  122. };  
  123.   
  124. enum FlowType   
  125. {  
  126.     FLOW_OFF,  
  127.     FLOW_HARDWARE,  
  128.     FLOW_XONXOFF  
  129. };  
  130.   
  131. /** 
  132.  * structure to contain port settings 
  133.  */  
  134. struct PortSettings   
  135. {  
  136.     BaudRateType BaudRate;  
  137.     DataBitsType DataBits;  
  138.     ParityType Parity;  
  139.     StopBitsType StopBits;  
  140.     FlowType FlowControl;  
  141.     long Timeout_Millisec;  
  142. };  
  143.   
  144. /*! 
  145.  * \author Stefan Sander 
  146.  * \author Michal Policht 
  147.  *  
  148.  * A common base class for Win_QextSerialBase, Posix_QextSerialBase and QextSerialPort. 
  149.  */  
  150. class QextSerialBase : public QIODevice   
  151. {  
  152.     Q_OBJECT  
  153.   
  154.     public:  
  155.         enum QueryMode {  
  156.             Polling,  
  157.             EventDriven  
  158.         };  
  159.   
  160.     protected:  
  161.         QMutex* mutex;  
  162.         QString port;  
  163.         PortSettings Settings;  
  164.         ulong lastErr;  
  165.         QextSerialBase::QueryMode _queryMode;  
  166.   
  167.         virtual qint64 readData(char * data, qint64 maxSize)=0;  
  168.         virtual qint64 writeData(const char * data, qint64 maxSize)=0;  
  169.   
  170.     public:  
  171.         QextSerialBase();  
  172.         QextSerialBase(const QString & name);  
  173.         virtual ~QextSerialBase();  
  174.         virtual void construct();  
  175.         virtual void setPortName(const QString & name);  
  176.         virtual QString portName() const;  
  177.           
  178.         /**! 
  179.          * Get query mode. 
  180.          *  \return query mode. 
  181.          */  
  182.         inline QextSerialBase::QueryMode queryMode() const { return _queryMode; };  
  183.   
  184.         /*! 
  185.          * Set desired serial communication handling style. You may choose from polling  
  186.          * or event driven approach. This function does nothing when port is open; to  
  187.          * apply changes port must be reopened. 
  188.          *  
  189.          * In event driven approach read() and write() functions are acting 
  190.          * asynchronously. They return immediately and the operation is performed in  
  191.          * the background, so they doesn't freeze the calling thread. 
  192.          * To determine when operation is finished, QextSerialPort runs separate thread  
  193.          * and monitors serial port events. Whenever the event occurs, adequate signal  
  194.          * is emitted. 
  195.          *  
  196.          * When polling is set, read() and write() are acting synchronously. Signals are 
  197.          * not working in this mode and some functions may not be available. The advantage 
  198.          * of polling is that it generates less overhead due to lack of signals emissions 
  199.          * and it doesn't start separate thread to monitor events. 
  200.          *  
  201.          * Generally event driven approach is more capable and friendly, although some  
  202.          * applications may need as low overhead as possible and then polling comes. 
  203.          *  
  204.          * \param mode query mode. 
  205.          */  
  206.         virtual void setQueryMode(QueryMode mode);  
  207.   
  208. //      virtual void setBlockingRead(bool block) = 0; ///< @todo implement.  
  209.   
  210.         virtual void setBaudRate(BaudRateType)=0;  
  211.         virtual BaudRateType baudRate() const;  
  212.         virtual void setDataBits(DataBitsType)=0;  
  213.         virtual DataBitsType dataBits() const;  
  214.         virtual void setParity(ParityType)=0;  
  215.         virtual ParityType parity() const;  
  216.         virtual void setStopBits(StopBitsType)=0;  
  217.         virtual StopBitsType stopBits() const;  
  218.         virtual void setFlowControl(FlowType)=0;  
  219.         virtual FlowType flowControl() const;  
  220.         virtual void setTimeout(long)=0;  
  221.       
  222.         virtual bool open(OpenMode mode)=0;  
  223.         virtual bool isSequential() const;  
  224.         virtual void close()=0;  
  225.         virtual void flush()=0;  
  226.       
  227.         virtual qint64 size() const=0;  
  228.         virtual qint64 bytesAvailable()=0;  
  229.         virtual bool atEnd() const;  
  230.       
  231.         virtual void ungetChar(char c)=0;  
  232.         virtual qint64 readLine(char * data, qint64 maxSize);  
  233.       
  234.         virtual ulong lastError() const;  
  235.         virtual void translateError(ulong error)=0;  
  236.       
  237.         virtual void setDtr(bool set=true)=0;  
  238.         virtual void setRts(bool set=true)=0;  
  239.         virtual ulong lineStatus()=0;  
  240.   
  241.     signals:  
  242.         /** 
  243.          * This signal is emitted whenever port settings are updated. 
  244.          *  \param valid \p true if settings are valid, \p false otherwise. 
  245.          *  
  246.          *  @todo implement. 
  247.          */  
  248. //      void validSettings(bool valid);  
  249.   
  250.         /*! 
  251.          * This signal is emitted whenever dsr line has changed its state. You may 
  252.          * use this signal to check if device is connected. 
  253.          *  \param status \p true when DSR signal is on, \p false otherwise. 
  254.          *  
  255.          *  \see lineStatus(). 
  256.          */  
  257.         void dsrChanged(bool status);  
  258. };  
  259.   
  260. #endif  

  1. /*************qextserialport.h**************/  
  2.   
  3. #ifndef _QEXTSERIALPORT_H_  
  4. #define _QEXTSERIALPORT_H_  
  5.   
  6. /*POSIX CODE*/  
  7. #ifdef _TTY_POSIX_  
  8. #include "posix_qextserialport.h"  
  9. #define QextBaseType Posix_QextSerialPort  
  10.   
  11. /*MS WINDOWS CODE*/  
  12. #else  
  13. #include "win_qextserialport.h"  
  14. #define QextBaseType Win_QextSerialPort  
  15. #endif  
  16.   
  17. class QextSerialPort: public QextBaseType   
  18. {  
  19.     Q_OBJECT  
  20.       
  21.     public:  
  22.         typedef QextSerialBase::QueryMode QueryMode;  
  23.   
  24.         QextSerialPort();  
  25.         QextSerialPort(const QString & name, QueryMode mode = QextSerialPort::Polling);  
  26.         QextSerialPort(PortSettings const& s, QueryMode mode = QextSerialPort::Polling);  
  27.         QextSerialPort(const QString & name, PortSettings const& s, QueryMode mode = QextSerialPort::Polling);  
  28.         QextSerialPort(const QextSerialPort& s);  
  29.         QextSerialPort& operator=(const QextSerialPort&);  
  30.         virtual ~QextSerialPort();  
  31.   
  32. };  
  33.   
  34. #endif  

  1. /************win_qextserialport.h************/  
  2.   
  3. #ifndef _WIN_QEXTSERIALPORT_H_  
  4. #define _WIN_QEXTSERIALPORT_H_  
  5.   
  6. #include "qextserialbase.h"  
  7. #include <windows.h>  
  8. #include <QThread>  
  9.   
  10.   
  11. /*if all warning messages are turned off, flag portability warnings to be turned off as well*/  
  12. #ifdef _TTY_NOWARN_  
  13. #define _TTY_NOWARN_PORT_  
  14. #endif  
  15.   
  16. class QReadWriteLock;  
  17. class Win_QextSerialThread;  
  18.   
  19.   
  20. /*! 
  21. \author Stefan Sander 
  22. \author Michal Policht 
  23.  
  24. A cross-platform serial port class. 
  25. This class encapsulates the Windows portion of QextSerialPort.  The user will be notified of 
  26. errors and possible portability conflicts at run-time by default - this behavior can be turned 
  27. off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off 
  28. portability warnings) in the project.  Note that defining _TTY_NOWARN_ also defines 
  29. _TTY_NOWARN_PORT_. 
  30.  
  31. \note 
  32. On Windows NT/2000/XP this class uses Win32 serial port functions by default.  The user may 
  33. select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can 
  34. make no guarantees as to the quality of POSIX support under NT/2000 however. 
  35.  
  36. \todo remove copy constructor and assign operator. 
  37. */  
  38. class Win_QextSerialPort: public QextSerialBase   
  39. {  
  40.     Q_OBJECT  
  41.     friend class Win_QextSerialThread;  
  42.       
  43.     private:  
  44.         /*! 
  45.          * This method is a part of constructor. 
  46.          */  
  47.         void init();  
  48.           
  49.     protected:  
  50.         HANDLE Win_Handle;  
  51.         HANDLE threadStartEvent;  
  52.         HANDLE threadTerminateEvent;  
  53.         OVERLAPPED overlap;  
  54.         OVERLAPPED overlapWrite;  
  55.         COMMCONFIG Win_CommConfig;  
  56.         COMMTIMEOUTS Win_CommTimeouts;  
  57.         QReadWriteLock * bytesToWriteLock;  ///< @todo maybe move to QextSerialBase.  
  58.         qint64 _bytesToWrite;       ///< @todo maybe move to QextSerialBase (and implement in POSIX).  
  59.         Win_QextSerialThread * overlapThread; ///< @todo maybe move to QextSerialBase (and implement in POSIX).  
  60.               
  61.         void monitorCommEvent();  
  62.         void terminateCommWait();  
  63.         virtual qint64 readData(char *data, qint64 maxSize);  
  64.         virtual qint64 writeData(const char *data, qint64 maxSize);  
  65.   
  66.     public:  
  67.         Win_QextSerialPort();  
  68.         Win_QextSerialPort(Win_QextSerialPort const& s);  
  69.         Win_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode = QextSerialBase::Polling);  
  70.         Win_QextSerialPort(const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);  
  71.         Win_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);  
  72.         Win_QextSerialPort& operator=(const Win_QextSerialPort& s);  
  73.         virtual ~Win_QextSerialPort();  
  74.         virtual bool open(OpenMode mode);  
  75.         virtual void close();  
  76.         virtual void flush();  
  77.         virtual qint64 size() const;  
  78.         virtual void ungetChar(char c);  
  79.         virtual void setFlowControl(FlowType);  
  80.         virtual void setParity(ParityType);  
  81.         virtual void setDataBits(DataBitsType);  
  82.         virtual void setStopBits(StopBitsType);  
  83.         virtual void setBaudRate(BaudRateType);  
  84.         virtual void setDtr(bool set=true);  
  85.         virtual void setRts(bool set=true);  
  86.         virtual ulong lineStatus(void);  
  87.         virtual qint64 bytesAvailable();  
  88.         virtual void translateError(ulong);  
  89.         virtual void setTimeout(long);  
  90.           
  91.         /*! 
  92.          * Return number of bytes waiting in the buffer. Currently this shows number  
  93.          * of bytes queued within write() and before the TX_EMPTY event occured. TX_EMPTY 
  94.          * event is created whenever last character in the system buffer was sent. 
  95.          *  
  96.          * \return number of bytes queued within write(), before the first TX_EMPTY  
  97.          * event occur. 
  98.          *  
  99.          * \warning this function may not give you expected results since TX_EMPTY may occur  
  100.          * while writing data to the buffer. Eventually some TX_EMPTY events may not be 
  101.          * catched. 
  102.          *  
  103.          * \note this function always returns 0 in polling mode. 
  104.          *  
  105.          * \see flush(). 
  106.          */  
  107.         virtual qint64 bytesToWrite() const;  
  108.           
  109.         virtual bool waitForReadyRead(int msecs);   ///< @todo implement.  
  110. };  
  111.   
  112. /*! 
  113.  * This thread monitors communication events. 
  114.  */  
  115. class Win_QextSerialThread: public QThread  
  116. {  
  117.     Win_QextSerialPort * qesp;  
  118.     bool terminate;  
  119.   
  120.     public:  
  121.         /*! 
  122.          * Constructor. 
  123.          *  
  124.          * \param qesp valid serial port object. 
  125.          */  
  126.         Win_QextSerialThread(Win_QextSerialPort * qesp);  
  127.           
  128.         /*! 
  129.          * Stop the thread. 
  130.          */  
  131.         void stop();  
  132.       
  133.     protected:  
  134.         //overriden  
  135.         virtual void run();  
  136.       
  137. };  
  138.   
  139. #endif  

  1. /***********main.cpp*************/  
  2.   
  3. #include "mainwindow.h"  
  4. #include <QApplication>  
  5.   
  6. int main(int argc, char *argv[])  
  7. {  
  8.     QApplication a(argc, argv);  
  9.     MainWindow w;  
  10.     w.show();  
  11.   
  12.     return a.exec();  
  13. }  

  1. /*************mainwindow.cpp************/  
  2.   
  3. #include "mainwindow.h"  
  4. #include <iostream>  
  5.   
  6. MainWindow::MainWindow(QWidget *parent)  
  7.     : QMainWindow(parent)  
  8. {  
  9.     this->setGeometry(200,200,300,300);  
  10.   
  11.     QLabel *ql=new QLabel("Qt串口编程测试:",this);  
  12.     ql->setGeometry(20,20,250,50);  
  13.   
  14.     text=new QTextBrowser(this);  
  15.     text->setGeometry(20,80,250,160);  
  16.   
  17.     struct PortSettings myComSetting = {BAUD2400,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,0};  
  18.     myCom=new Win_QextSerialPort("com5",myComSetting,QextSerialBase::EventDriven);  
  19.     myCom->open(QIODevice::ReadWrite);  
  20.     myCom->setBaudRate(BAUD2400);  //一定要在这儿添上这句,否则可能发生无法解释的异常。  
  21.     connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));  
  22. }  
  23.   
  24. MainWindow::~MainWindow()  
  25. {  
  26.   
  27. }  
  28.   
  29. void MainWindow::readMyCom(){  
  30.     QByteArray temp=myCom->readAll();  
  31.     if(temp.size()>=1){  
  32.     text->insertPlainText("收到:");  
  33.     text->insertPlainText(temp);  
  34.     }  
  35. }  

  1. /************qextserialbase.cpp***************/  
  2.   
  3. #include "qextserialbase.h"  
  4.   
  5. /*! 
  6. \fn QextSerialBase::QextSerialBase() 
  7. Default constructor. 
  8. */  
  9. QextSerialBase::QextSerialBase()  
  10.  : QIODevice()  
  11. {  
  12.   
  13. #ifdef _TTY_WIN_  
  14.     setPortName("COM1");  
  15.   
  16. #elif defined(_TTY_IRIX_)  
  17.     setPortName("/dev/ttyf1");  
  18.   
  19. #elif defined(_TTY_HPUX_)  
  20.     setPortName("/dev/tty1p0");  
  21.   
  22. #elif defined(_TTY_SUN_)  
  23.     setPortName("/dev/ttya");  
  24.   
  25. #elif defined(_TTY_DIGITAL_)  
  26.     setPortName("/dev/tty01");  
  27.   
  28. #elif defined(_TTY_FREEBSD_)  
  29.     setPortName("/dev/ttyd1");  
  30.   
  31. #else  
  32.     setPortName("/dev/ttyS0");  
  33. #endif  
  34.   
  35.     construct();  
  36. }  
  37.   
  38. /*! 
  39. \fn QextSerialBase::QextSerialBase(const QString & name) 
  40. Construct a port and assign it to the device specified by the name parameter. 
  41. */  
  42. QextSerialBase::QextSerialBase(const QString & name)  
  43.  : QIODevice()  
  44. {  
  45.     setPortName(name);  
  46.     construct();  
  47. }  
  48.   
  49. /*! 
  50. \fn QextSerialBase::~QextSerialBase() 
  51. Standard destructor. 
  52. */  
  53. QextSerialBase::~QextSerialBase()  
  54. {  
  55.     delete mutex;  
  56. }  
  57.   
  58. /*! 
  59. \fn void QextSerialBase::construct() 
  60. Common constructor function for setting up default port settings. 
  61. (115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout). 
  62. */  
  63. void QextSerialBase::construct()  
  64. {  
  65.     Settings.BaudRate=BAUD115200;  
  66.     Settings.DataBits=DATA_8;  
  67.     Settings.Parity=PAR_NONE;  
  68.     Settings.StopBits=STOP_1;  
  69.     Settings.FlowControl=FLOW_HARDWARE;  
  70.     Settings.Timeout_Millisec=500;  
  71.     mutex = new QMutex( QMutex::Recursive );  
  72.     setOpenMode(QIODevice::NotOpen);  
  73. }  
  74.   
  75. void QextSerialBase::setQueryMode(QueryMode mechanism)  
  76. {  
  77.     _queryMode = mechanism;  
  78. }  
  79.   
  80. /*! 
  81. \fn void QextSerialBase::setPortName(const QString & name) 
  82. Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0". 
  83. */  
  84. void QextSerialBase::setPortName(const QString & name)  
  85. {  
  86.     port = name;  
  87. }  
  88.   
  89. /*! 
  90. \fn QString QextSerialBase::portName() const 
  91. Returns the name set by setPortName(). 
  92. */  
  93. QString QextSerialBase::portName() const  
  94. {  
  95.     return port;  
  96. }  
  97.   
  98. /*! 
  99. \fn BaudRateType QextSerialBase::baudRate(void) const 
  100. Returns the baud rate of the serial port.  For a list of possible return values see 
  101. the definition of the enum BaudRateType. 
  102. */  
  103. BaudRateType QextSerialBase::baudRate(voidconst  
  104. {  
  105.     return Settings.BaudRate;  
  106. }  
  107.   
  108. /*! 
  109. \fn DataBitsType QextSerialBase::dataBits() const 
  110. Returns the number of data bits used by the port.  For a list of possible values returned by 
  111. this function, see the definition of the enum DataBitsType. 
  112. */  
  113. DataBitsType QextSerialBase::dataBits() const  
  114. {  
  115.     return Settings.DataBits;  
  116. }  
  117.   
  118. /*! 
  119. \fn ParityType QextSerialBase::parity() const 
  120. Returns the type of parity used by the port.  For a list of possible values returned by 
  121. this function, see the definition of the enum ParityType. 
  122. */  
  123. ParityType QextSerialBase::parity() const  
  124. {  
  125.     return Settings.Parity;  
  126. }  
  127.   
  128. /*! 
  129. \fn StopBitsType QextSerialBase::stopBits() const 
  130. Returns the number of stop bits used by the port.  For a list of possible return values, see 
  131. the definition of the enum StopBitsType. 
  132. */  
  133. StopBitsType QextSerialBase::stopBits() const  
  134. {  
  135.     return Settings.StopBits;  
  136. }  
  137.   
  138. /*! 
  139. \fn FlowType QextSerialBase::flowControl() const 
  140. Returns the type of flow control used by the port.  For a list of possible values returned 
  141. by this function, see the definition of the enum FlowType. 
  142. */  
  143. FlowType QextSerialBase::flowControl() const  
  144. {  
  145.     return Settings.FlowControl;  
  146. }  
  147.   
  148. /*! 
  149. \fn bool QextSerialBase::isSequential() const 
  150. Returns true if device is sequential, otherwise returns false. Serial port is sequential device 
  151. so this function always returns true. Check QIODevice::isSequential() documentation for more  
  152. information. 
  153. */  
  154. bool QextSerialBase::isSequential() const  
  155. {  
  156.     return true;  
  157. }  
  158.   
  159. /*! 
  160. \fn bool QextSerialBase::atEnd() const 
  161. This function will return true if the input buffer is empty (or on error), and false otherwise. 
  162. Call QextSerialBase::lastError() for error information. 
  163. */  
  164. bool QextSerialBase::atEnd() const  
  165. {  
  166.     if (size()) {  
  167.         return true;  
  168.     }  
  169.     return false;  
  170. }  
  171.   
  172. /*! 
  173. \fn qint64 QextSerialBase::readLine(char * data, qint64 maxSize) 
  174. This function will read a line of buffered input from the port, stopping when either maxSize bytes 
  175. have been read, the port has no more data available, or a newline is encountered. 
  176. The value returned is the length of the string that was read. 
  177. */  
  178. qint64 QextSerialBase::readLine(char * data, qint64 maxSize)  
  179. {  
  180.     qint64 numBytes = bytesAvailable();  
  181.     char* pData = data;  
  182.   
  183.     if (maxSize < 2) //maxSize must be larger than 1  
  184.         return -1;  
  185.   
  186.     /*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/  
  187.     while (pData<(data+numBytes) && --maxSize) {  
  188.         readData(pData, 1);  
  189.         if (*pData++ == '\n') {  
  190.             break;  
  191.         }  
  192.     }  
  193.     *pData='\0';  
  194.   
  195.     /*return size of data read*/  
  196.     return (pData-data);  
  197. }  
  198.   
  199. /*! 
  200. \fn ulong QextSerialBase::lastError() const 
  201. Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port 
  202. operation was successful.  Possible error codes are: 
  203.  
  204. \verbatim 
  205. Error                           Explanation 
  206. ---------------------------     ------------------------------------------------------------- 
  207. E_NO_ERROR                      No Error has occured 
  208. E_INVALID_FD                    Invalid file descriptor (port was not opened correctly) 
  209. E_NO_MEMORY                     Unable to allocate memory tables (POSIX) 
  210. E_CAUGHT_NON_BLOCKED_SIGNAL     Caught a non-blocked signal (POSIX) 
  211. E_PORT_TIMEOUT                  Operation timed out (POSIX) 
  212. E_INVALID_DEVICE                The file opened by the port is not a character device (POSIX) 
  213. E_BREAK_CONDITION               The port detected a break condition 
  214. E_FRAMING_ERROR                 The port detected a framing error 
  215.                                 (usually caused by incorrect baud rate settings) 
  216. E_IO_ERROR                      There was an I/O error while communicating with the port 
  217. E_BUFFER_OVERRUN                Character buffer overrun 
  218. E_RECEIVE_OVERFLOW              Receive buffer overflow 
  219. E_RECEIVE_PARITY_ERROR          The port detected a parity error in the received data 
  220. E_TRANSMIT_OVERFLOW             Transmit buffer overflow 
  221. E_READ_FAILED                   General read operation failure 
  222. E_WRITE_FAILED                  General write operation failure 
  223. \endverbatim 
  224. */  
  225. ulong QextSerialBase::lastError() const  
  226. {  
  227.     return lastErr;  
  228. }  

  1. /*****************qextserialport.cpp***************/  
  2.   
  3. /*! 
  4. \class QextSerialPort 
  5. \author Stefan Sander 
  6. \author Michal Policht 
  7.  
  8. A cross-platform serial port class. 
  9. This class encapsulates a serial port on both POSIX and Windows systems.  The user will be 
  10. notified of errors and possible portability conflicts at run-time by default - this behavior can 
  11. be turned off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn 
  12. off portability warnings) in the project. 
  13.  
  14. You may choose from polling or event driven API. For details check setQueryMode() documentation. 
  15.  
  16. \note 
  17. On Windows NT/2000/XP this class uses Win32 serial port functions by default.  The user may 
  18. select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can 
  19. make no guarantees as to the quality of POSIX support under NT/2000 however. 
  20.  
  21. */  
  22.   
  23. #include <stdio.h>  
  24. #include "qextserialport.h"  
  25.   
  26. /*! 
  27. Default constructor.  Note that the naming convention used by a QextSerialPort constructed with 
  28. this constructor will be determined by #defined constants, or lack thereof - the default behavior 
  29. is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants are: 
  30.  
  31. \verbatim 
  32.  
  33. Constant         Used By         Naming Convention 
  34. ----------       -------------   ------------------------ 
  35. _TTY_WIN_        Windows         COM1, COM2 
  36. _TTY_IRIX_       SGI/IRIX        /dev/ttyf1, /dev/ttyf2 
  37. _TTY_HPUX_       HP-UX           /dev/tty1p0, /dev/tty2p0 
  38. _TTY_SUN_        SunOS/Solaris   /dev/ttya, /dev/ttyb 
  39. _TTY_DIGITAL_    Digital UNIX    /dev/tty01, /dev/tty02 
  40. _TTY_FREEBSD_    FreeBSD         /dev/ttyd0, /dev/ttyd1 
  41. _TTY_LINUX_      Linux           /dev/ttyS0, /dev/ttyS1 
  42. <none>           Linux           /dev/ttyS0, /dev/ttyS1 
  43. \endverbatim 
  44.  
  45. The object will be associated with the first port in the system, e.g. COM1 on Windows systems. 
  46. See the other constructors if you need to use a port other than the first. 
  47. */  
  48. QextSerialPort::QextSerialPort()  
  49.  : QextBaseType()  
  50. {}  
  51.   
  52. /*! 
  53. Constructs a serial port attached to the port specified by name. 
  54. name is the name of the device, which is windowsystem-specific, 
  55. e.g."COM1" or "/dev/ttyS0". 
  56.  
  57. \see setQueryMode(). 
  58. */  
  59. QextSerialPort::QextSerialPort(const QString & name, QueryMode mode)  
  60.  : QextBaseType(name, mode)  
  61. {  
  62. }  
  63.   
  64. /*! 
  65. Constructs a port with default name and settings specified by the settings parameter. 
  66.  
  67. \see setQueryMode(). 
  68. */  
  69. QextSerialPort::QextSerialPort(PortSettings const& settings, QueryMode mode)  
  70.  : QextBaseType(settings, mode)  
  71. {}  
  72.   
  73. /*! 
  74. Constructs a port with the name and settings specified. 
  75.  
  76. \see setQueryMode(). 
  77. */  
  78. QextSerialPort::QextSerialPort(const QString & name, PortSettings const& settings, QueryMode mode)  
  79.  : QextBaseType(name, settings, mode)  
  80. {}  
  81.   
  82. /*! 
  83. Copy constructor. 
  84.  
  85. \deprecated 
  86. */  
  87. QextSerialPort::QextSerialPort(const QextSerialPort& s)  
  88.  : QextBaseType(s)  
  89. {}  
  90.   
  91. /*! 
  92. \fn QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s) 
  93. Overrides the = operator. 
  94.  
  95. \deprecated 
  96. */  
  97. QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s)  
  98. {  
  99.     return (QextSerialPort&)QextBaseType::operator=(s);  
  100. }  
  101.   
  102. /*! 
  103. \fn QextSerialPort::~QextSerialPort() 
  104. Standard destructor. 
  105. */  
  106. QextSerialPort::~QextSerialPort()  
  107. {}  

  1. /***************win_qextserialport.cpp***************/  
  2.   
  3. #include <QReadWriteLock>  
  4. #include "win_qextserialport.h"  
  5.   
  6.   
  7. /*! 
  8. \fn Win_QextSerialPort::Win_QextSerialPort() 
  9. Default constructor.  Note that the name of the device used by a Win_QextSerialPort constructed 
  10. with this constructor will be determined by #defined constants, or lack thereof - the default 
  11. behavior is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants 
  12. are: 
  13.  
  14. \verbatim 
  15.  
  16. Constant         Used By         Naming Convention 
  17. ----------       -------------   ------------------------ 
  18. _TTY_WIN_        Windows         COM1, COM2 
  19. _TTY_IRIX_       SGI/IRIX        /dev/ttyf1, /dev/ttyf2 
  20. _TTY_HPUX_       HP-UX           /dev/tty1p0, /dev/tty2p0 
  21. _TTY_SUN_        SunOS/Solaris   /dev/ttya, /dev/ttyb 
  22. _TTY_DIGITAL_    Digital UNIX    /dev/tty01, /dev/tty02 
  23. _TTY_FREEBSD_    FreeBSD         /dev/ttyd0, /dev/ttyd1 
  24. _TTY_LINUX_      Linux           /dev/ttyS0, /dev/ttyS1 
  25. <none>           Linux           /dev/ttyS0, /dev/ttyS1 
  26. \endverbatim 
  27.  
  28. This constructor associates the object with the first port on the system, e.g. COM1 for Windows 
  29. platforms.  See the other constructor if you need a port other than the first. 
  30. */  
  31. Win_QextSerialPort::Win_QextSerialPort():  
  32.     QextSerialBase()   
  33. {  
  34.     Win_Handle=INVALID_HANDLE_VALUE;  
  35.     init();  
  36. }  
  37.   
  38. /*! 
  39. \fn Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&) 
  40. Copy constructor. 
  41. */  
  42. Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort& s):  
  43.     QextSerialBase(s.port)   
  44. {  
  45.     Win_Handle=INVALID_HANDLE_VALUE;  
  46.     _queryMode = s._queryMode;  
  47.     _bytesToWrite = s._bytesToWrite;  
  48.     bytesToWriteLock = new QReadWriteLock;  
  49.     overlapThread = new Win_QextSerialThread(this);  
  50.     memcpy(& overlap, & s.overlap, sizeof(OVERLAPPED));  
  51.     memcpy(& overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED));  
  52.     setOpenMode(s.openMode());  
  53.     lastErr=s.lastErr;  
  54.     port = s.port;  
  55.     Settings.FlowControl=s.Settings.FlowControl;  
  56.     Settings.Parity=s.Settings.Parity;  
  57.     Settings.DataBits=s.Settings.DataBits;  
  58.     Settings.StopBits=s.Settings.StopBits;  
  59.     Settings.BaudRate=s.Settings.BaudRate;  
  60.     Win_Handle=s.Win_Handle;  
  61.     memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));  
  62.     memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));  
  63.     if (s.overlapThread->isRunning())  
  64.         overlapThread->start();  
  65. }  
  66.   
  67. /*! 
  68. \fn Win_QextSerialPort::Win_QextSerialPort(const QString & name) 
  69. Constructs a serial port attached to the port specified by devName. 
  70. devName is the name of the device, which is windowsystem-specific, 
  71. e.g."COM2" or "/dev/ttyS0". 
  72. */  
  73. Win_QextSerialPort::Win_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode):  
  74.     QextSerialBase(name)   
  75. {  
  76.     Win_Handle=INVALID_HANDLE_VALUE;  
  77.     setQueryMode(mode);  
  78.     init();  
  79. }  
  80.   
  81. /*! 
  82. \fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) 
  83. Constructs a port with default name and specified settings. 
  84. */  
  85. Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings, QextSerialBase::QueryMode mode) {  
  86.     Win_Handle=INVALID_HANDLE_VALUE;  
  87.     setBaudRate(settings.BaudRate);  
  88.     setDataBits(settings.DataBits);  
  89.     setStopBits(settings.StopBits);  
  90.     setParity(settings.Parity);  
  91.     setFlowControl(settings.FlowControl);  
  92.     setTimeout(settings.Timeout_Millisec);  
  93.     setQueryMode(mode);  
  94.     init();  
  95. }  
  96.   
  97. /*! 
  98. \fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) 
  99. Constructs a port with specified name and settings. 
  100. */  
  101. Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode) {  
  102.     Win_Handle=INVALID_HANDLE_VALUE;  
  103.     setPortName(name);  
  104.     setBaudRate(settings.BaudRate);  
  105.     setDataBits(settings.DataBits);  
  106.     setStopBits(settings.StopBits);  
  107.     setParity(settings.Parity);  
  108.     setFlowControl(settings.FlowControl);  
  109.     setTimeout(settings.Timeout_Millisec);  
  110.     setQueryMode(mode);  
  111.     init();  
  112. }  
  113.   
  114. void Win_QextSerialPort::init()  
  115. {  
  116.     _bytesToWrite = 0;  
  117.     overlap.Internal = 0;  
  118.     overlap.InternalHigh = 0;  
  119.     overlap.Offset = 0;  
  120.     overlap.OffsetHigh = 0;  
  121.     overlap.hEvent = CreateEvent(NULL, truefalse, NULL);  
  122.     overlapThread = new Win_QextSerialThread(this);  
  123.     bytesToWriteLock = new QReadWriteLock;  
  124. }  
  125.   
  126. /*! 
  127. \fn Win_QextSerialPort::~Win_QextSerialPort() 
  128. Standard destructor. 
  129. */  
  130. Win_QextSerialPort::~Win_QextSerialPort() {  
  131.     if (isOpen()) {  
  132.         close();  
  133.     }  
  134.     CloseHandle(overlap.hEvent);  
  135.     delete overlapThread;  
  136.     delete bytesToWriteLock;   
  137. }  
  138.   
  139. /*! 
  140. \fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) 
  141. overrides the = operator 
  142. */  
  143. Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) {  
  144.     setOpenMode(s.openMode());  
  145.     _queryMode = s._queryMode;  
  146.     _bytesToWrite = s._bytesToWrite;  
  147.     bytesToWriteLock = new QReadWriteLock;  
  148.     overlapThread = new Win_QextSerialThread(this);  
  149.     memcpy(& overlap, & s.overlap, sizeof(OVERLAPPED));  
  150.     memcpy(& overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED));  
  151.     lastErr=s.lastErr;  
  152.     port = s.port;  
  153.     Settings.FlowControl=s.Settings.FlowControl;  
  154.     Settings.Parity=s.Settings.Parity;  
  155.     Settings.DataBits=s.Settings.DataBits;  
  156.     Settings.StopBits=s.Settings.StopBits;  
  157.     Settings.BaudRate=s.Settings.BaudRate;  
  158.     Win_Handle=s.Win_Handle;  
  159.     memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));  
  160.     memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));  
  161.     if (s.overlapThread->isRunning())  
  162.         overlapThread->start();  
  163.     return *this;  
  164. }  
  165.   
  166.   
  167. /*! 
  168. \fn bool Win_QextSerialPort::open(OpenMode mode) 
  169. Opens a serial port.  Note that this function does not specify which device to open.  If you need 
  170. to open a device by name, see Win_QextSerialPort::open(const char*).  This function has no effect 
  171. if the port associated with the class is already open.  The port is also configured to the current 
  172. settings, as stored in the Settings structure. 
  173. */  
  174. bool Win_QextSerialPort::open(OpenMode mode) {  
  175.     unsigned long confSize = sizeof(COMMCONFIG);  
  176.     Win_CommConfig.dwSize = confSize;  
  177.     DWORD dwFlagsAndAttributes = 0;  
  178.     if (queryMode() == QextSerialBase::EventDriven)  
  179.         dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;  
  180.   
  181.     LOCK_MUTEX();  
  182.     if (mode == QIODevice::NotOpen)  
  183.         return isOpen();  
  184.     if (!isOpen()) {  
  185.         /*open the port*/  
  186.         Win_Handle=CreateFileA(port.toLatin1(), GENERIC_READ|GENERIC_WRITE,  
  187.                               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);  
  188.         if (Win_Handle!=INVALID_HANDLE_VALUE) {  
  189.             /*configure port settings*/  
  190.             GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);  
  191.             GetCommState(Win_Handle, &(Win_CommConfig.dcb));  
  192.   
  193.             /*set up parameters*/  
  194.             Win_CommConfig.dcb.fBinary=TRUE;  
  195.             Win_CommConfig.dcb.fInX=FALSE;  
  196.             Win_CommConfig.dcb.fOutX=FALSE;  
  197.             Win_CommConfig.dcb.fAbortOnError=FALSE;  
  198.             Win_CommConfig.dcb.fNull=FALSE;  
  199.             setBaudRate(Settings.BaudRate);  
  200.             setDataBits(Settings.DataBits);  
  201.             setStopBits(Settings.StopBits);  
  202.             setParity(Settings.Parity);  
  203.             setFlowControl(Settings.FlowControl);  
  204.             setTimeout(Settings.Timeout_Millisec);  
  205.             SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  206.   
  207.             //init event driven approach  
  208.             if (queryMode() == QextSerialBase::EventDriven) {  
  209.                 Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
  210.                 Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
  211.                 Win_CommTimeouts.ReadTotalTimeoutConstant = 0;  
  212.                 Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;  
  213.                 Win_CommTimeouts.WriteTotalTimeoutConstant = 0;  
  214.                 SetCommTimeouts(Win_Handle, &Win_CommTimeouts);  
  215.                 if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {  
  216.                     qWarning("Failed to set Comm Mask. Error code: %ld", GetLastError());  
  217.                     UNLOCK_MUTEX();  
  218.                     return false;  
  219.                 }  
  220.                 overlapThread->start();  
  221.             }  
  222.             QIODevice::open(mode);  
  223.         }  
  224.     } else {  
  225.         UNLOCK_MUTEX();  
  226.         return false;  
  227.     }  
  228.     UNLOCK_MUTEX();  
  229.     return isOpen();  
  230. }  
  231.   
  232. /*! 
  233. \fn void Win_QextSerialPort::close() 
  234. Closes a serial port.  This function has no effect if the serial port associated with the class 
  235. is not currently open. 
  236. */  
  237. void Win_QextSerialPort::close()   
  238. {  
  239.     LOCK_MUTEX();  
  240.   
  241.     if (isOpen()) {  
  242.         flush();  
  243.         if (overlapThread->isRunning()) {  
  244.             overlapThread->stop();  
  245.             if (QThread::currentThread() != overlapThread)  
  246.                 overlapThread->wait();  
  247.         }  
  248.         if (CloseHandle(Win_Handle))  
  249.             Win_Handle = INVALID_HANDLE_VALUE;  
  250.         _bytesToWrite = 0;  
  251.         QIODevice::close();  
  252.     }  
  253.   
  254.     UNLOCK_MUTEX();  
  255. }  
  256.   
  257. /*! 
  258. \fn void Win_QextSerialPort::flush() 
  259. Flushes all pending I/O to the serial port.  This function has no effect if the serial port 
  260. associated with the class is not currently open. 
  261. */  
  262. void Win_QextSerialPort::flush() {  
  263.     LOCK_MUTEX();  
  264.     if (isOpen()) {  
  265.         FlushFileBuffers(Win_Handle);  
  266.     }  
  267.     UNLOCK_MUTEX();  
  268. }  
  269.   
  270. /*! 
  271. \fn qint64 Win_QextSerialPort::size() const 
  272. This function will return the number of bytes waiting in the receive queue of the serial port. 
  273. It is included primarily to provide a complete QIODevice interface, and will not record errors 
  274. in the lastErr member (because it is const).  This function is also not thread-safe - in 
  275. multithreading situations, use Win_QextSerialPort::bytesAvailable() instead. 
  276. */  
  277. qint64 Win_QextSerialPort::size() const {  
  278.     int availBytes;  
  279.     COMSTAT Win_ComStat;  
  280.     DWORD Win_ErrorMask=0;  
  281.     ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);  
  282.     availBytes = Win_ComStat.cbInQue;  
  283.     return (qint64)availBytes;  
  284. }  
  285.   
  286. /*! 
  287. \fn qint64 Win_QextSerialPort::bytesAvailable() 
  288. Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if 
  289. the port is not currently open, or -1 on error.  Error information can be retrieved by calling 
  290. Win_QextSerialPort::getLastError(). 
  291. */  
  292. qint64 Win_QextSerialPort::bytesAvailable() {  
  293.     LOCK_MUTEX();  
  294.     if (isOpen()) {  
  295.         DWORD Errors;  
  296.         COMSTAT Status;  
  297.         bool success=ClearCommError(Win_Handle, &Errors, &Status);  
  298.         translateError(Errors);  
  299.         if (success) {  
  300.             lastErr=E_NO_ERROR;  
  301.             UNLOCK_MUTEX();  
  302.             return Status.cbInQue + QIODevice::bytesAvailable();  
  303.         }  
  304.         UNLOCK_MUTEX();  
  305.         return (unsigned int)-1;  
  306.     }  
  307.     UNLOCK_MUTEX();  
  308.     return 0;  
  309. }  
  310.   
  311. /*! 
  312. \fn void Win_QextSerialPort::translateError(ulong error) 
  313. Translates a system-specific error code to a QextSerialPort error code.  Used internally. 
  314. */  
  315. void Win_QextSerialPort::translateError(ulong error) {  
  316.     if (error&CE_BREAK) {  
  317.         lastErr=E_BREAK_CONDITION;  
  318.     }  
  319.     else if (error&CE_FRAME) {  
  320.         lastErr=E_FRAMING_ERROR;  
  321.     }  
  322.     else if (error&CE_IOE) {  
  323.         lastErr=E_IO_ERROR;  
  324.     }  
  325.     else if (error&CE_MODE) {  
  326.         lastErr=E_INVALID_FD;  
  327.     }  
  328.     else if (error&CE_OVERRUN) {  
  329.         lastErr=E_BUFFER_OVERRUN;  
  330.     }  
  331.     else if (error&CE_RXPARITY) {  
  332.         lastErr=E_RECEIVE_PARITY_ERROR;  
  333.     }  
  334.     else if (error&CE_RXOVER) {  
  335.         lastErr=E_RECEIVE_OVERFLOW;  
  336.     }  
  337.     else if (error&CE_TXFULL) {  
  338.         lastErr=E_TRANSMIT_OVERFLOW;  
  339.     }  
  340. }  
  341.   
  342. /*! 
  343. \fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize) 
  344. Reads a block of data from the serial port.  This function will read at most maxlen bytes from 
  345. the serial port and place them in the buffer pointed to by data.  Return value is the number of 
  346. bytes actually read, or -1 on error. 
  347.  
  348. \warning before calling this function ensure that serial port associated with this class 
  349. is currently open (use isOpen() function to check if port is open). 
  350. */  
  351. qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)  
  352. {  
  353.     DWORD retVal;  
  354.       
  355.     LOCK_MUTEX();  
  356.       
  357.     retVal = 0;  
  358.     if (queryMode() == QextSerialBase::EventDriven) {  
  359.         OVERLAPPED overlapRead;  
  360.         overlapRead.Internal = 0;  
  361.         overlapRead.InternalHigh = 0;  
  362.         overlapRead.Offset = 0;  
  363.         overlapRead.OffsetHigh = 0;  
  364.         overlapRead.hEvent = CreateEvent(NULL, truefalse, NULL);  
  365.         if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) {  
  366.             if (GetLastError() == ERROR_IO_PENDING)  
  367.                 GetOverlappedResult(Win_Handle, & overlapRead, & retVal, true);  
  368.             else {  
  369.                 lastErr = E_READ_FAILED;  
  370.                 retVal = (DWORD)-1;  
  371.             }  
  372.         }  
  373.         CloseHandle(overlapRead.hEvent);  
  374.     } else if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {  
  375.         lastErr = E_READ_FAILED;  
  376.         retVal = (DWORD)-1;  
  377.     }  
  378.   
  379.     UNLOCK_MUTEX();  
  380.   
  381.     return (qint64)retVal;  
  382. }  
  383.   
  384. /*! 
  385. \fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize) 
  386. Writes a block of data to the serial port.  This function will write len bytes 
  387. from the buffer pointed to by data to the serial port.  Return value is the number 
  388. of bytes actually written, or -1 on error. 
  389.  
  390. \warning before calling this function ensure that serial port associated with this class 
  391. is currently open (use isOpen() function to check if port is open). 
  392. */  
  393. qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)  
  394. {  
  395.     DWORD retVal;  
  396.       
  397.     LOCK_MUTEX();  
  398.   
  399.     retVal = 0;  
  400.     if (queryMode() == QextSerialBase::EventDriven) {  
  401.         bytesToWriteLock->lockForWrite();  
  402.         _bytesToWrite += maxSize;  
  403.         bytesToWriteLock->unlock();  
  404.         overlapWrite.Internal = 0;  
  405.         overlapWrite.InternalHigh = 0;  
  406.         overlapWrite.Offset = 0;  
  407.         overlapWrite.OffsetHigh = 0;  
  408.         overlapWrite.hEvent = CreateEvent(NULL, truefalse, NULL);  
  409.         if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapWrite)) {  
  410.             lastErr = E_WRITE_FAILED;  
  411.             retVal = (DWORD)-1;  
  412.         } else  
  413.             retVal = maxSize;  
  414.     } else if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {  
  415.         lastErr = E_WRITE_FAILED;  
  416.         retVal = (DWORD)-1;  
  417.     }  
  418.       
  419.     UNLOCK_MUTEX();  
  420.   
  421.     return (qint64)retVal;  
  422. }  
  423.   
  424. /*! 
  425. \fn void Win_QextSerialPort::ungetChar(char c) 
  426. This function is included to implement the full QIODevice interface, and currently has no 
  427. purpose within this class.  This function is meaningless on an unbuffered device and currently 
  428. only prints a warning message to that effect. 
  429. */  
  430. void Win_QextSerialPort::ungetChar(char c) {  
  431.   
  432.     /*meaningless on unbuffered sequential device - return error and print a warning*/  
  433.     TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");  
  434. }  
  435.   
  436. /*! 
  437. \fn void Win_QextSerialPort::setFlowControl(FlowType flow) 
  438. Sets the flow control used by the port.  Possible values of flow are: 
  439. \verbatim 
  440.     FLOW_OFF            No flow control 
  441.     FLOW_HARDWARE       Hardware (RTS/CTS) flow control 
  442.     FLOW_XONXOFF        Software (XON/XOFF) flow control 
  443. \endverbatim 
  444. */  
  445. void Win_QextSerialPort::setFlowControl(FlowType flow) {  
  446.     LOCK_MUTEX();  
  447.     if (Settings.FlowControl!=flow) {  
  448.         Settings.FlowControl=flow;  
  449.     }  
  450.     if (isOpen()) {  
  451.         switch(flow) {  
  452.   
  453.             /*no flow control*/  
  454.             case FLOW_OFF:  
  455.                 Win_CommConfig.dcb.fOutxCtsFlow=FALSE;  
  456.                 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;  
  457.                 Win_CommConfig.dcb.fInX=FALSE;  
  458.                 Win_CommConfig.dcb.fOutX=FALSE;  
  459.                 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  460.                 break;  
  461.   
  462.             /*software (XON/XOFF) flow control*/  
  463.             case FLOW_XONXOFF:  
  464.                 Win_CommConfig.dcb.fOutxCtsFlow=FALSE;  
  465.                 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;  
  466.                 Win_CommConfig.dcb.fInX=TRUE;  
  467.                 Win_CommConfig.dcb.fOutX=TRUE;  
  468.                 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  469.                 break;  
  470.   
  471.             case FLOW_HARDWARE:  
  472.                 Win_CommConfig.dcb.fOutxCtsFlow=TRUE;  
  473.                 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;  
  474.                 Win_CommConfig.dcb.fInX=FALSE;  
  475.                 Win_CommConfig.dcb.fOutX=FALSE;  
  476.                 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  477.                 break;  
  478.         }  
  479.     }  
  480.     UNLOCK_MUTEX();  
  481. }  
  482.   
  483. /*! 
  484. \fn void Win_QextSerialPort::setParity(ParityType parity) 
  485. Sets the parity associated with the serial port.  The possible values of parity are: 
  486. \verbatim 
  487.     PAR_SPACE       Space Parity 
  488.     PAR_MARK        Mark Parity 
  489.     PAR_NONE        No Parity 
  490.     PAR_EVEN        Even Parity 
  491.     PAR_ODD         Odd Parity 
  492. \endverbatim 
  493. */  
  494. void Win_QextSerialPort::setParity(ParityType parity) {  
  495.     LOCK_MUTEX();  
  496.     if (Settings.Parity!=parity) {  
  497.         Settings.Parity=parity;  
  498.     }  
  499.     if (isOpen()) {  
  500.         Win_CommConfig.dcb.Parity=(unsigned char)parity;  
  501.         switch (parity) {  
  502.   
  503.             /*space parity*/  
  504.             case PAR_SPACE:  
  505.                 if (Settings.DataBits==DATA_8) {  
  506.                     TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");  
  507.                 }  
  508.                 Win_CommConfig.dcb.fParity=TRUE;  
  509.                 break;  
  510.   
  511.             /*mark parity - WINDOWS ONLY*/  
  512.             case PAR_MARK:  
  513.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning:  Mark parity is not supported by POSIX systems");  
  514.                 Win_CommConfig.dcb.fParity=TRUE;  
  515.                 break;  
  516.   
  517.             /*no parity*/  
  518.             case PAR_NONE:  
  519.                 Win_CommConfig.dcb.fParity=FALSE;  
  520.                 break;  
  521.   
  522.             /*even parity*/  
  523.             case PAR_EVEN:  
  524.                 Win_CommConfig.dcb.fParity=TRUE;  
  525.                 break;  
  526.   
  527.             /*odd parity*/  
  528.             case PAR_ODD:  
  529.                 Win_CommConfig.dcb.fParity=TRUE;  
  530.                 break;  
  531.         }  
  532.         SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  533.     }  
  534.     UNLOCK_MUTEX();  
  535. }  
  536.   
  537. /*! 
  538. \fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits) 
  539. Sets the number of data bits used by the serial port.  Possible values of dataBits are: 
  540. \verbatim 
  541.     DATA_5      5 data bits 
  542.     DATA_6      6 data bits 
  543.     DATA_7      7 data bits 
  544.     DATA_8      8 data bits 
  545. \endverbatim 
  546.  
  547. \note 
  548. This function is subject to the following restrictions: 
  549. \par 
  550.     5 data bits cannot be used with 2 stop bits. 
  551. \par 
  552.     1.5 stop bits can only be used with 5 data bits. 
  553. \par 
  554.     8 data bits cannot be used with space parity on POSIX systems. 
  555.  
  556. */  
  557. void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {  
  558.     LOCK_MUTEX();  
  559.     if (Settings.DataBits!=dataBits) {  
  560.         if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||  
  561.             (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {  
  562.         }  
  563.         else {  
  564.             Settings.DataBits=dataBits;  
  565.         }  
  566.     }  
  567.     if (isOpen()) {  
  568.         switch(dataBits) {  
  569.   
  570.             /*5 data bits*/  
  571.             case DATA_5:  
  572.                 if (Settings.StopBits==STOP_2) {  
  573.                     TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");  
  574.                 }  
  575.                 else {  
  576.                     Win_CommConfig.dcb.ByteSize=5;  
  577.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  578.                 }  
  579.                 break;  
  580.   
  581.             /*6 data bits*/  
  582.             case DATA_6:  
  583.                 if (Settings.StopBits==STOP_1_5) {  
  584.                     TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");  
  585.                 }  
  586.                 else {  
  587.                     Win_CommConfig.dcb.ByteSize=6;  
  588.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  589.                 }  
  590.                 break;  
  591.   
  592.             /*7 data bits*/  
  593.             case DATA_7:  
  594.                 if (Settings.StopBits==STOP_1_5) {  
  595.                     TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");  
  596.                 }  
  597.                 else {  
  598.                     Win_CommConfig.dcb.ByteSize=7;  
  599.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  600.                 }  
  601.                 break;  
  602.   
  603.             /*8 data bits*/  
  604.             case DATA_8:  
  605.                 if (Settings.StopBits==STOP_1_5) {  
  606.                     TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");  
  607.                 }  
  608.                 else {  
  609.                     Win_CommConfig.dcb.ByteSize=8;  
  610.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  611.                 }  
  612.                 break;  
  613.         }  
  614.     }  
  615.     UNLOCK_MUTEX();  
  616. }  
  617.   
  618. /*! 
  619. \fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits) 
  620. Sets the number of stop bits used by the serial port.  Possible values of stopBits are: 
  621. \verbatim 
  622.     STOP_1      1 stop bit 
  623.     STOP_1_5    1.5 stop bits 
  624.     STOP_2      2 stop bits 
  625. \endverbatim 
  626.  
  627. \note 
  628. This function is subject to the following restrictions: 
  629. \par 
  630.     2 stop bits cannot be used with 5 data bits. 
  631. \par 
  632.     1.5 stop bits cannot be used with 6 or more data bits. 
  633. \par 
  634.     POSIX does not support 1.5 stop bits. 
  635. */  
  636. void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {  
  637.     LOCK_MUTEX();  
  638.     if (Settings.StopBits!=stopBits) {  
  639.         if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||  
  640.             (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {  
  641.         }  
  642.         else {  
  643.             Settings.StopBits=stopBits;  
  644.         }  
  645.     }  
  646.     if (isOpen()) {  
  647.         switch (stopBits) {  
  648.   
  649.             /*one stop bit*/  
  650.             case STOP_1:  
  651.                 Win_CommConfig.dcb.StopBits=ONESTOPBIT;  
  652.                 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  653.                 break;  
  654.   
  655.             /*1.5 stop bits*/  
  656.             case STOP_1_5:  
  657.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");  
  658.                 if (Settings.DataBits!=DATA_5) {  
  659.                     TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");  
  660.                 }  
  661.                 else {  
  662.                     Win_CommConfig.dcb.StopBits=ONE5STOPBITS;  
  663.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  664.                 }  
  665.                 break;  
  666.   
  667.             /*two stop bits*/  
  668.             case STOP_2:  
  669.                 if (Settings.DataBits==DATA_5) {  
  670.                     TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");  
  671.                 }  
  672.                 else {  
  673.                     Win_CommConfig.dcb.StopBits=TWOSTOPBITS;  
  674.                     SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  675.                 }  
  676.                 break;  
  677.         }  
  678.     }  
  679.     UNLOCK_MUTEX();  
  680. }  
  681.   
  682. /*! 
  683. \fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) 
  684. Sets the baud rate of the serial port.  Note that not all rates are applicable on 
  685. all platforms.  The following table shows translations of the various baud rate 
  686. constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an * 
  687. are speeds that are usable on both Windows and POSIX. 
  688. \verbatim 
  689.  
  690.   RATE          Windows Speed   POSIX Speed 
  691.   -----------   -------------   ----------- 
  692.    BAUD50                 110          50 
  693.    BAUD75                 110          75 
  694.   *BAUD110                110         110 
  695.    BAUD134                110         134.5 
  696.    BAUD150                110         150 
  697.    BAUD200                110         200 
  698.   *BAUD300                300         300 
  699.   *BAUD600                600         600 
  700.   *BAUD1200              1200        1200 
  701.    BAUD1800              1200        1800 
  702.   *BAUD2400              2400        2400 
  703.   *BAUD4800              4800        4800 
  704.   *BAUD9600              9600        9600 
  705.    BAUD14400            14400        9600 
  706.   *BAUD19200            19200       19200 
  707.   *BAUD38400            38400       38400 
  708.    BAUD56000            56000       38400 
  709.   *BAUD57600            57600       57600 
  710.    BAUD76800            57600       76800 
  711.   *BAUD115200          115200      115200 
  712.    BAUD128000          128000      115200 
  713.    BAUD256000          256000      115200 
  714. \endverbatim 
  715. */  
  716. void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {  
  717.     LOCK_MUTEX();  
  718.     if (Settings.BaudRate!=baudRate) {  
  719.         switch (baudRate) {  
  720.             case BAUD50:  
  721.             case BAUD75:  
  722.             case BAUD134:  
  723.             case BAUD150:  
  724.             case BAUD200:  
  725.                 Settings.BaudRate=BAUD110;  
  726.                 break;  
  727.   
  728.             case BAUD1800:  
  729.                 Settings.BaudRate=BAUD1200;  
  730.                 break;  
  731.   
  732.             case BAUD76800:  
  733.                 Settings.BaudRate=BAUD57600;  
  734.                 break;  
  735.   
  736.             default:  
  737.                 Settings.BaudRate=baudRate;  
  738.                 break;  
  739.         }  
  740.     }  
  741.     if (isOpen()) {  
  742.         switch (baudRate) {  
  743.   
  744.             /*50 baud*/  
  745.             case BAUD50:  
  746.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation.  Switching to 110 baud.");  
  747.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  748.                 break;  
  749.   
  750.             /*75 baud*/  
  751.             case BAUD75:  
  752.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation.  Switching to 110 baud.");  
  753.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  754.                 break;  
  755.   
  756.             /*110 baud*/  
  757.             case BAUD110:  
  758.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  759.                 break;  
  760.   
  761.             /*134.5 baud*/  
  762.             case BAUD134:  
  763.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation.  Switching to 110 baud.");  
  764.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  765.                 break;  
  766.   
  767.             /*150 baud*/  
  768.             case BAUD150:  
  769.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation.  Switching to 110 baud.");  
  770.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  771.                 break;  
  772.   
  773.             /*200 baud*/  
  774.             case BAUD200:  
  775.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation.  Switching to 110 baud.");  
  776.                 Win_CommConfig.dcb.BaudRate=CBR_110;  
  777.                 break;  
  778.   
  779.             /*300 baud*/  
  780.             case BAUD300:  
  781.                 Win_CommConfig.dcb.BaudRate=CBR_300;  
  782.                 break;  
  783.   
  784.             /*600 baud*/  
  785.             case BAUD600:  
  786.                 Win_CommConfig.dcb.BaudRate=CBR_600;  
  787.                 break;  
  788.   
  789.             /*1200 baud*/  
  790.             case BAUD1200:  
  791.                 Win_CommConfig.dcb.BaudRate=CBR_1200;  
  792.                 break;  
  793.   
  794.             /*1800 baud*/  
  795.             case BAUD1800:  
  796.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation.  Switching to 1200 baud.");  
  797.                 Win_CommConfig.dcb.BaudRate=CBR_1200;  
  798.                 break;  
  799.   
  800.             /*2400 baud*/  
  801.             case BAUD2400:  
  802.                 Win_CommConfig.dcb.BaudRate=CBR_2400;  
  803.                 break;  
  804.   
  805.             /*4800 baud*/  
  806.             case BAUD4800:  
  807.                 Win_CommConfig.dcb.BaudRate=CBR_4800;  
  808.                 break;  
  809.   
  810.             /*9600 baud*/  
  811.             case BAUD9600:  
  812.                 Win_CommConfig.dcb.BaudRate=CBR_9600;  
  813.                 break;  
  814.   
  815.             /*14400 baud*/  
  816.             case BAUD14400:  
  817.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");  
  818.                 Win_CommConfig.dcb.BaudRate=CBR_14400;  
  819.                 break;  
  820.   
  821.             /*19200 baud*/  
  822.             case BAUD19200:  
  823.                 Win_CommConfig.dcb.BaudRate=CBR_19200;  
  824.                 break;  
  825.   
  826.             /*38400 baud*/  
  827.             case BAUD38400:  
  828.                 Win_CommConfig.dcb.BaudRate=CBR_38400;  
  829.                 break;  
  830.   
  831.             /*56000 baud*/  
  832.             case BAUD56000:  
  833.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");  
  834.                 Win_CommConfig.dcb.BaudRate=CBR_56000;  
  835.                 break;  
  836.   
  837.             /*57600 baud*/  
  838.             case BAUD57600:  
  839.                 Win_CommConfig.dcb.BaudRate=CBR_57600;  
  840.                 break;  
  841.   
  842.             /*76800 baud*/  
  843.             case BAUD76800:  
  844.                 TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation.  Switching to 57600 baud.");  
  845.                 Win_CommConfig.dcb.BaudRate=CBR_57600;  
  846.                 break;  
  847.   
  848.             /*115200 baud*/  
  849.             case BAUD115200:  
  850.                 Win_CommConfig.dcb.BaudRate=CBR_115200;  
  851.                 break;  
  852.   
  853.             /*128000 baud*/  
  854.             case BAUD128000:  
  855.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");  
  856.                 Win_CommConfig.dcb.BaudRate=CBR_128000;  
  857.                 break;  
  858.   
  859.             /*256000 baud*/  
  860.             case BAUD256000:  
  861.                 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");  
  862.                 Win_CommConfig.dcb.BaudRate=CBR_256000;  
  863.                 break;  
  864.         }  
  865.         SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));  
  866.     }  
  867.     UNLOCK_MUTEX();  
  868. }  
  869.   
  870. /*! 
  871. \fn void Win_QextSerialPort::setDtr(bool set) 
  872. Sets DTR line to the requested state (high by default).  This function will have no effect if 
  873. the port associated with the class is not currently open. 
  874. */  
  875. void Win_QextSerialPort::setDtr(bool set) {  
  876.     LOCK_MUTEX();  
  877.     if (isOpen()) {  
  878.         if (set) {  
  879.             EscapeCommFunction(Win_Handle, SETDTR);  
  880.         }  
  881.         else {  
  882.             EscapeCommFunction(Win_Handle, CLRDTR);  
  883.         }  
  884.     }  
  885.     UNLOCK_MUTEX();  
  886. }  
  887.   
  888. /*! 
  889. \fn void Win_QextSerialPort::setRts(bool set) 
  890. Sets RTS line to the requested state (high by default).  This function will have no effect if 
  891. the port associated with the class is not currently open. 
  892. */  
  893. void Win_QextSerialPort::setRts(bool set) {  
  894.     LOCK_MUTEX();  
  895.     if (isOpen()) {  
  896.         if (set) {  
  897.             EscapeCommFunction(Win_Handle, SETRTS);  
  898.         }  
  899.         else {  
  900.             EscapeCommFunction(Win_Handle, CLRRTS);  
  901.         }  
  902.     }  
  903.     UNLOCK_MUTEX();  
  904. }  
  905.   
  906. /*! 
  907. \fn ulong Win_QextSerialPort::lineStatus(void) 
  908. returns the line status as stored by the port function.  This function will retrieve the states 
  909. of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines 
  910. can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned 
  911. long with specific bits indicating which lines are high.  The following constants should be used 
  912. to examine the states of individual lines: 
  913.  
  914. \verbatim 
  915. Mask        Line 
  916. ------      ---- 
  917. LS_CTS      CTS 
  918. LS_DSR      DSR 
  919. LS_DCD      DCD 
  920. LS_RI       RI 
  921. \endverbatim 
  922.  
  923. This function will return 0 if the port associated with the class is not currently open. 
  924. */  
  925. ulong Win_QextSerialPort::lineStatus(void) {  
  926.     unsigned long Status=0, Temp=0;  
  927.     LOCK_MUTEX();  
  928.     if (isOpen()) {  
  929.         GetCommModemStatus(Win_Handle, &Temp);  
  930.         if (Temp&MS_CTS_ON) {  
  931.             Status|=LS_CTS;  
  932.         }  
  933.         if (Temp&MS_DSR_ON) {  
  934.             Status|=LS_DSR;  
  935.         }  
  936.         if (Temp&MS_RING_ON) {  
  937.             Status|=LS_RI;  
  938.         }  
  939.         if (Temp&MS_RLSD_ON) {  
  940.             Status|=LS_DCD;  
  941.         }  
  942.     }  
  943.     UNLOCK_MUTEX();  
  944.     return Status;  
  945. }  
  946.   
  947. bool Win_QextSerialPort::waitForReadyRead(int msecs)  
  948. {  
  949.     //@todo implement  
  950.     return false;  
  951. }  
  952.   
  953. qint64 Win_QextSerialPort::bytesToWrite() const  
  954. {  
  955.     return _bytesToWrite;  
  956. }  
  957.   
  958. void Win_QextSerialPort::monitorCommEvent()  
  959. {  
  960.     DWORD eventMask = 0;  
  961.   
  962.     ResetEvent(overlap.hEvent);  
  963.     if (!WaitCommEvent(Win_Handle, & eventMask, & overlap))  
  964.         if (GetLastError() != ERROR_IO_PENDING)  
  965.             qCritical("WaitCommEvent error %ld\n", GetLastError());  
  966.   
  967.     if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) {  
  968.         //overlap event occured  
  969.         DWORD undefined;  
  970.         if (!GetOverlappedResult(Win_Handle, & overlap, & undefined, false)) {  
  971.             qWarning("Comm event overlapped error %ld", GetLastError());  
  972.             return;  
  973.         }  
  974.         if (eventMask & EV_RXCHAR) {  
  975.             if (sender() != this)  
  976.                 emit readyRead();  
  977.         }  
  978.         if (eventMask & EV_TXEMPTY) {  
  979.             DWORD numBytes;  
  980.             GetOverlappedResult(Win_Handle, & overlapWrite, & numBytes, true);  
  981.             bytesToWriteLock->lockForWrite();  
  982.             if (sender() != this)  
  983.                 emit bytesWritten(bytesToWrite());  
  984.             _bytesToWrite = 0;  
  985.             bytesToWriteLock->unlock();  
  986.         }  
  987.         if (eventMask & EV_DSR)  
  988.             if (lineStatus() & LS_DSR)  
  989.                 emit dsrChanged(true);  
  990.             else  
  991.                 emit dsrChanged(false);  
  992.     }  
  993. }  
  994.   
  995. void Win_QextSerialPort::terminateCommWait()  
  996. {  
  997.     SetCommMask(Win_Handle, 0);  
  998. }  
  999.   
  1000.   
  1001. /*! 
  1002. \fn void Win_QextSerialPort::setTimeout(ulong millisec); 
  1003. Sets the read and write timeouts for the port to millisec milliseconds. 
  1004. Setting 0 for both sec and millisec indicates that timeouts are not used for read nor 
  1005. write operations. Setting -1 indicates that read and write should return immediately. 
  1006.  
  1007. \note this function does nothing in event driven mode. 
  1008. */  
  1009. void Win_QextSerialPort::setTimeout(long millisec) {  
  1010.     LOCK_MUTEX();  
  1011.     Settings.Timeout_Millisec = millisec;  
  1012.   
  1013.     if (millisec == -1) {  
  1014.         Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
  1015.         Win_CommTimeouts.ReadTotalTimeoutConstant = 0;  
  1016.     } else {  
  1017.         Win_CommTimeouts.ReadIntervalTimeout = millisec;  
  1018.         Win_CommTimeouts.ReadTotalTimeoutConstant = millisec;  
  1019.     }  
  1020.     Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
  1021.     Win_CommTimeouts.WriteTotalTimeoutMultiplier = millisec;  
  1022.     Win_CommTimeouts.WriteTotalTimeoutConstant = 0;  
  1023.     if (queryMode() != QextSerialBase::EventDriven)  
  1024.         SetCommTimeouts(Win_Handle, &Win_CommTimeouts);  
  1025.   
  1026.     UNLOCK_MUTEX();  
  1027. }  
  1028.   
  1029.   
  1030. Win_QextSerialThread::Win_QextSerialThread(Win_QextSerialPort * qesp):  
  1031.     QThread()  
  1032. {  
  1033.     this->qesp = qesp;  
  1034.     terminate = false;  
  1035. }  
  1036.   
  1037. void Win_QextSerialThread::stop()  
  1038. {  
  1039.     terminate = true;  
  1040.     qesp->terminateCommWait();  
  1041. }  
  1042.   
  1043. void Win_QextSerialThread::run()  
  1044. {  
  1045.     while (!terminate)  
  1046.         qesp->monitorCommEvent();  
  1047.     terminate = false;  
  1048. }  

实际运行效果截图:

(-----------完----------)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值