├── qextserialport ├── examples │ ├── examples.pro │ ├── qespta │ │ ├── README │ │ ├── qespta.pro │ │ ├── main.cpp │ │ ├── MainWindow.h │ │ ├── QespTest.h │ │ ├── MainWindow.cpp │ │ ├── MessageWindow.h │ │ ├── MessageWindow.cpp │ │ └── QespTest.cpp │ ├── enumerator │ │ ├── enumerator.pro │ │ └── main.cpp │ ├── event │ │ ├── event.pro │ │ ├── PortListener.h │ │ ├── main.cpp │ │ └── PortListener.cpp │ └── uartassistant │ │ ├── main.cpp │ │ ├── uartassistant.pro │ │ ├── hled.h │ │ ├── dialog.h │ │ ├── hled.cpp │ │ ├── dialog.cpp │ │ └── dialog.ui ├── doc │ ├── examples │ │ ├── images │ │ │ └── uartassistant.png │ │ ├── qespta.qdoc │ │ ├── enumerator.qdoc │ │ └── uartassistant.qdoc │ ├── doc.pri │ ├── readme.txt │ ├── qextserialport.qdocconf │ ├── style │ │ └── style.css │ └── index.qdoc ├── .gitignore ├── extserialport.prf.in ├── src │ ├── qextserialport.pri │ ├── qextserialenumerator_unix.cpp │ ├── qextserialport_global.h │ ├── qextserialenumerator.h │ ├── qextserialenumerator_p.h │ ├── qextserialenumerator.cpp │ ├── qextserialenumerator_linux.cpp │ ├── qextserialport.h │ ├── qextserialport_p.h │ ├── qextserialenumerator_win.cpp │ ├── qextserialenumerator_osx.cpp │ ├── qextserialport_win.cpp │ └── qextserialport_unix.cpp ├── README ├── qextserialport.pro ├── LICENSE └── ChangeLog ├── main.cpp ├── README.md ├── main.pro ├── print.h ├── qledindicator.cpp ├── qledindicator.h ├── mainwindow.h ├── Makefile └── main.pro.user /qextserialport/examples/examples.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | SUBDIRS = qespta enumerator \ 3 | uartassistant 4 | win32:SUBDIRS += event 5 | 6 | -------------------------------------------------------------------------------- /qextserialport/doc/examples/images/uartassistant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CETECIran/qtSerialDataPlotFFT/HEAD/qextserialport/doc/examples/images/uartassistant.png -------------------------------------------------------------------------------- /qextserialport/examples/qespta/README: -------------------------------------------------------------------------------- 1 | This is simple application using QextSerialPort library. 2 | 3 | Port settings are in QespTest constructor (QespTest.cpp) 4 | 5 | -------------------------------------------------------------------------------- /qextserialport/examples/enumerator/enumerator.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | DEPENDPATH += . 3 | CONFIG += console 4 | include(../../src/qextserialport.pri) 5 | SOURCES += main.cpp 6 | 7 | -------------------------------------------------------------------------------- /qextserialport/doc/examples/qespta.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \example examples/qespta 3 | \title qespta Demo 4 | 5 | The example demonstrates how to use QextSerialPort. 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /qextserialport/examples/event/event.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | DEPENDPATH += . 3 | CONFIG += console 4 | include(../../src/qextserialport.pri) 5 | 6 | SOURCES += main.cpp PortListener.cpp 7 | HEADERS += PortListener.h 8 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dialog.h" 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | Dialog w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /qextserialport/doc/doc.pri: -------------------------------------------------------------------------------- 1 | OTHER_FILES += $$PWD/qextserialport.qdocconf 2 | 3 | #name of qdoc3 has been changed to qdoc under Qt5 4 | QESP_QDOC = qdoc 5 | lessThan(QT_MAJOR_VERSION, 5):QESP_QDOC = qdoc3 6 | 7 | docs_target.target = docs 8 | docs_target.commands = $$QESP_QDOC $$PWD/qextserialport.qdocconf 9 | 10 | QMAKE_EXTRA_TARGETS = docs_target 11 | QMAKE_CLEAN += "-r $$PWD/html" 12 | 13 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/qespta.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | DEPENDPATH += . 3 | QT += core gui 4 | contains(QT_VERSION, ^5\\..*\\..*): QT += widgets 5 | HEADERS += MainWindow.h \ 6 | MessageWindow.h \ 7 | QespTest.h 8 | 9 | SOURCES += main.cpp \ 10 | MainWindow.cpp \ 11 | MessageWindow.cpp \ 12 | QespTest.cpp 13 | 14 | include(../../src/qextserialport.pri) 15 | -------------------------------------------------------------------------------- /qextserialport/doc/examples/enumerator.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \example examples/enumerator 3 | \title enumerator Demo 4 | 5 | The example demonstrates how to use QextSerialEnumerator. 6 | 7 | Include the proper header file 8 | \snippet examples/enumerator/main.cpp 0 9 | 10 | Get available ports in the system. 11 | \snippet examples/enumerator/main.cpp 1 12 | 13 | Output 14 | \snippet examples/enumerator/main.cpp 2 15 | */ 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qtSerialDataPlotFFT 2 | simple qt application that compute Real Time (Real) FFT of Data coming From Serial Port, and Plot Both Raw Data and FFT using QcustomPlot. 3 | 4 | qt creator 4.8.5 was used to make this project . 5 | it receive comma seperated value from serial port and plot raw data using QcustomPlot 6 | it Also compute Realtime SDFT whenever one sample receive and update plot immediately . 7 | it also support logging received Data to File . 8 | 9 | if you have any problem let me know . 10 | -------------------------------------------------------------------------------- /qextserialport/examples/event/PortListener.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #ifndef PORTLISTENER_H_ 5 | #define PORTLISTENER_H_ 6 | 7 | #include 8 | #include "qextserialport.h" 9 | 10 | class PortListener : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | PortListener(const QString &portName); 15 | 16 | private: 17 | QextSerialPort *port; 18 | 19 | private slots: 20 | void onReadyRead(); 21 | void onDsrChanged(bool status); 22 | 23 | }; 24 | 25 | 26 | #endif /*PORTLISTENER_H_*/ 27 | -------------------------------------------------------------------------------- /qextserialport/examples/event/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @brief Main file. 4 | * @author Michal Policht 5 | */ 6 | 7 | #include 8 | #include "PortListener.h" 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | QCoreApplication app(argc, argv); 13 | 14 | QString portName = QLatin1String("COM1"); // update this to use your port of choice 15 | PortListener listener(portName); // signals get hooked up internally 16 | 17 | // start the event loop and wait for signals 18 | return app.exec(); 19 | } 20 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/uartassistant.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2011-11-06T21:37:41 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | contains(QT_VERSION, ^5\\..*\\..*): QT += widgets 9 | 10 | TARGET = uartassistant 11 | TEMPLATE = app 12 | 13 | include(../../src/qextserialport.pri) 14 | 15 | SOURCES += main.cpp\ 16 | dialog.cpp\ 17 | hled.cpp 18 | 19 | HEADERS += dialog.h \ 20 | hled.h 21 | 22 | FORMS += dialog.ui 23 | -------------------------------------------------------------------------------- /qextserialport/doc/examples/uartassistant.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \example examples/uartassistant 3 | \title UartAssistant Demo 4 | 5 | The example demonstrates how to use QextSerialPort. 6 | 7 | Initialze UI element. 8 | \snippet examples/uartassistant/dialog.cpp 0 9 | 10 | Initialize serial port 11 | \snippet examples/uartassistant/dialog.cpp 1 12 | 13 | port Settings 14 | \snippet examples/uartassistant/dialog.cpp 2 15 | 16 | Open or Close the port. 17 | \snippet examples/uartassistant/dialog.cpp 3 18 | 19 | Read from or Write to the port 20 | \snippet examples/uartassistant/dialog.cpp 4 21 | 22 | \image uartassistant.png 23 | */ 24 | 25 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @brief Main file. 4 | * @author Micha? Policht 5 | */ 6 | 7 | #include 8 | #include "MainWindow.h" 9 | #include "MessageWindow.h" 10 | 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | QApplication app(argc, argv); 15 | //! [0] 16 | #if QT_VERSION < QT_VERSION_CHECK(5,0,0) 17 | //redirect debug messages to the MessageWindow dialog 18 | qInstallMsgHandler(MessageWindow::AppendMsgWrapper); 19 | #else 20 | qInstallMessageHandler(MessageWindow::AppendMsgWrapper); 21 | #endif 22 | //! [0] 23 | 24 | MainWindow mainWindow; 25 | mainWindow.show(); 26 | 27 | return app.exec(); 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/MainWindow.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MainWindow.h 3 | * @brief Application's Main Window. 4 | * @see MainWindow 5 | * @author Micha? Policht 6 | */ 7 | 8 | #ifndef MAINWINDOW_H_ 9 | #define MAINWINDOW_H_ 10 | 11 | #include 12 | 13 | class QMenu; 14 | class QAction; 15 | 16 | class MainWindow : public QMainWindow 17 | { 18 | Q_OBJECT 19 | 20 | QMenu *fileMenu; 21 | QAction *exitAct; 22 | QMenu *helpMenu; 23 | QAction *aboutAct; 24 | 25 | private: 26 | void createMenus(); 27 | void createActions(); 28 | 29 | private slots: 30 | void about(); 31 | 32 | public: 33 | MainWindow(); 34 | 35 | }; 36 | 37 | #endif /*MAINWINDOW_H_*/ 38 | 39 | -------------------------------------------------------------------------------- /qextserialport/.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.pro.user* 3 | *.app 4 | *.moc 5 | *.prl 6 | Makefile* 7 | doc/html/ 8 | *.framework/ 9 | *.xcodeproj/ 10 | debug/ 11 | release/ 12 | qtc-gdbmacros/ 13 | *.rej 14 | *.orig 15 | *.obj 16 | *.swp 17 | *.dll 18 | *.exp 19 | *.ilk 20 | *.pdb 21 | *.lib 22 | Thumbs.db 23 | moc_*.cpp 24 | qrc_*.cpp 25 | *.o 26 | *.so.* 27 | *.so 28 | *.pdb 29 | ui_*.h 30 | *~ 31 | .qmake.cache 32 | extserialport.prf 33 | lib/* 34 | *.orig 35 | *.exe 36 | *.vcproj 37 | *.vcproj.*.user 38 | *_resource.rc 39 | *.sln 40 | *.idb 41 | *.ncb 42 | *.suo 43 | examples/enumerator/enumerator 44 | examples/event/event 45 | examples/qespta/qespta 46 | examples/uartassistant/uartassistant 47 | object_script.* 48 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/hled.h: -------------------------------------------------------------------------------- 1 | #ifndef HLED_H 2 | #define HLED_H 3 | 4 | #include 5 | 6 | class QColor; 7 | 8 | class HLed : public QWidget 9 | { 10 | Q_OBJECT 11 | public: 12 | HLed(QWidget *parent = 0); 13 | ~HLed(); 14 | 15 | QColor color() const; 16 | QSize sizeHint() const; 17 | QSize minimumSizeHint() const; 18 | 19 | public slots: 20 | void setColor(const QColor &color); 21 | void toggle(); 22 | void turnOn(bool on=true); 23 | void turnOff(bool off=true); 24 | 25 | protected: 26 | void paintEvent(QPaintEvent *); 27 | int ledWidth() const; 28 | 29 | private: 30 | struct Private; 31 | Private * const m_d; 32 | }; 33 | 34 | #endif // HLED_H 35 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/QespTest.h: -------------------------------------------------------------------------------- 1 | /* qesptest.h 2 | **************************************/ 3 | #ifndef _QESPTEST_H_ 4 | #define _QESPTEST_H_ 5 | 6 | #include 7 | 8 | class QLineEdit; 9 | class QTextEdit; 10 | class QextSerialPort; 11 | class QSpinBox; 12 | 13 | class QespTest : public QWidget 14 | { 15 | Q_OBJECT 16 | public: 17 | QespTest(QWidget *parent=0); 18 | 19 | virtual ~QespTest(); 20 | 21 | private: 22 | QLineEdit *message; 23 | QSpinBox *delaySpinBox; 24 | QTextEdit *received_msg; 25 | QextSerialPort *port; 26 | 27 | private slots: 28 | void transmitMsg(); 29 | void receiveMsg(); 30 | void appendCR(); 31 | void appendLF(); 32 | void closePort(); 33 | void openPort(); 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /qextserialport/extserialport.prf.in: -------------------------------------------------------------------------------- 1 | defineReplace(qextLibraryName) { 2 | unset(LIBRARY_NAME) 3 | LIBRARY_NAME = \$\$1 4 | greaterThan(QT_MAJOR_VERSION, 4):LIBRARY_NAME ~= s,^Qt,Qt\$\$QT_MAJOR_VERSION, 5 | CONFIG(debug, debug|release) { 6 | !debug_and_release|build_pass { 7 | mac:LIBRARY_NAME = \$\${LIBRARY_NAME}_debug 8 | else:win32:LIBRARY_NAME = \$\${LIBRARY_NAME}d 9 | } 10 | } 11 | return(\$\$LIBRARY_NAME) 12 | } 13 | 14 | !!IF qesp_mac_framework 15 | LIBS += -framework $$QESP_LIB_BASENAME 16 | INCLUDEPATH += $$[QT_INSTALL_LIBS]/$${QESP_LIB_BASENAME}.framework/Headers 17 | !!ELSE 18 | LIBS += -l\$\$qextLibraryName($$QESP_LIB_BASENAME) 19 | INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtExtSerialPort 20 | !!ENDIF 21 | 22 | !!IF !qesp_static 23 | DEFINES += QEXTSERIALPORT_USING_SHARED 24 | !!ENDIF 25 | -------------------------------------------------------------------------------- /main.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-10-20T04:57:52 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | #CONFIG += extserialport 10 | #LIBS += -lfftw3 11 | #LIBS += -L /usr/lib/libfftw3.so 12 | 13 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 14 | 15 | TARGET = main 16 | TEMPLATE = app 17 | 18 | 19 | SOURCES += main.cpp\ 20 | mainwindow.cpp \ 21 | qcustomplot.cpp \ 22 | qledindicator.cpp 23 | 24 | HEADERS += mainwindow.h \ 25 | qcustomplot.h \ 26 | qledindicator.h 27 | 28 | FORMS += mainwindow.ui 29 | 30 | 31 | #LIBS += -L /usr/local/Qt-5.3.2/lib/libQt5ExtSerialPort.so 32 | #INCLUDEPATH += -I /usr/local/Qt-5.3.2/include/QtExtSerialPort/ 33 | INCLUDEPATH += -I /usr/local/include 34 | 35 | include(qextserialport/src/qextserialport.pri) 36 | 37 | OTHER_FILES += \ 38 | ../../../../Downloads/icons/at-sign-document.png 39 | -------------------------------------------------------------------------------- /qextserialport/examples/enumerator/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @brief Main file. 4 | * @author Micha? Policht 5 | */ 6 | //! [0] 7 | #include "qextserialenumerator.h" 8 | //! [0] 9 | #include 10 | #include 11 | int main() 12 | { 13 | //! [1] 14 | QList ports = QextSerialEnumerator::getPorts(); 15 | //! [1] 16 | qDebug() << "List of ports:"; 17 | //! [2] 18 | foreach (QextPortInfo info, ports) { 19 | qDebug() << "port name:" << info.portName; 20 | qDebug() << "friendly name:" << info.friendName; 21 | qDebug() << "physical name:" << info.physName; 22 | qDebug() << "enumerator name:" << info.enumName; 23 | qDebug() << "vendor ID:" << info.vendorID; 24 | qDebug() << "product ID:" << info.productID; 25 | 26 | qDebug() << "==================================="; 27 | } 28 | //! [2] 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /qextserialport/doc/readme.txt: -------------------------------------------------------------------------------- 1 | Note: 2 | 3 | If you are using qextserialport-XXX.tar.gz, the qesp.qch and 4 | html files have been provided. 5 | 6 | Open the file "html/index.html" using your web browser. 7 | Or integrated the "html/qesp.qch" into your QtCreator. 8 | 9 | 10 | == How to generate help files? == 11 | 12 | Simply run following commands at toplevel directory. 13 | qmake 14 | make docs 15 | 16 | Or run the following command at this directory 17 | qdoc3 qextserialport.qdocconf 18 | 19 | Then a folder called "html" will be generated. 20 | Open the file "html/index.html" using your web browser. 21 | 22 | == How to integrated into Qt Creator or Qt Assistant? == 23 | 24 | Once the html files are generated. run following commands 25 | cd doc/html 26 | qhelpgenerator qesp.qhp 27 | 28 | A file called "qesp.qch" will be generated. 29 | 30 | For Qt Assistant: 31 | Edit ==> Preferences ==> Documentations ==> Add... 32 | 33 | For Qt Creator 34 | Tools ==> Options ==> Help ==> Documentations ==> Add... 35 | 36 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/dialog.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_H 2 | #define DIALOG_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class Dialog; 8 | } 9 | class QTimer; 10 | class QextSerialPort; 11 | class QextSerialEnumerator; 12 | 13 | class Dialog : public QDialog 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit Dialog(QWidget *parent = 0); 19 | ~Dialog(); 20 | 21 | protected: 22 | void changeEvent(QEvent *e); 23 | 24 | private Q_SLOTS: 25 | void onPortNameChanged(const QString &name); 26 | void onBaudRateChanged(int idx); 27 | void onParityChanged(int idx); 28 | void onDataBitsChanged(int idx); 29 | void onStopBitsChanged(int idx); 30 | void onQueryModeChanged(int idx); 31 | void onTimeoutChanged(int val); 32 | void onOpenCloseButtonClicked(); 33 | void onSendButtonClicked(); 34 | void onReadyRead(); 35 | 36 | void onPortAddedOrRemoved(); 37 | 38 | private: 39 | Ui::Dialog *ui; 40 | QTimer *timer; 41 | QextSerialPort *port; 42 | QextSerialEnumerator *enumerator; 43 | }; 44 | 45 | #endif // DIALOG_H 46 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | DEPENDPATH += $$PWD 3 | 4 | PUBLIC_HEADERS += $$PWD/qextserialport.h \ 5 | $$PWD/qextserialenumerator.h \ 6 | $$PWD/qextserialport_global.h 7 | 8 | HEADERS += $$PUBLIC_HEADERS \ 9 | $$PWD/qextserialport_p.h \ 10 | $$PWD/qextserialenumerator_p.h \ 11 | 12 | SOURCES += $$PWD/qextserialport.cpp \ 13 | $$PWD/qextserialenumerator.cpp 14 | unix { 15 | SOURCES += $$PWD/qextserialport_unix.cpp 16 | linux* { 17 | SOURCES += $$PWD/qextserialenumerator_linux.cpp 18 | } else:macx { 19 | SOURCES += $$PWD/qextserialenumerator_osx.cpp 20 | } else { 21 | SOURCES += $$PWD/qextserialenumerator_unix.cpp 22 | } 23 | } 24 | win32:SOURCES += $$PWD/qextserialport_win.cpp \ 25 | $$PWD/qextserialenumerator_win.cpp 26 | 27 | linux*{ 28 | !qesp_linux_udev:DEFINES += QESP_NO_UDEV 29 | qesp_linux_udev: LIBS += -ludev 30 | } 31 | 32 | macx:LIBS += -framework IOKit -framework CoreFoundation 33 | win32:LIBS += -lsetupapi -ladvapi32 -luser32 34 | 35 | # moc doesn't detect Q_OS_LINUX correctly, so add this to make it work 36 | linux*:DEFINES += __linux__ 37 | -------------------------------------------------------------------------------- /qextserialport/examples/event/PortListener.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PortListener.h" 3 | #include 4 | 5 | PortListener::PortListener(const QString &portName) 6 | { 7 | qDebug() << "hi there"; 8 | this->port = new QextSerialPort(portName, QextSerialPort::EventDriven); 9 | port->setBaudRate(BAUD9600); 10 | port->setFlowControl(FLOW_OFF); 11 | port->setParity(PAR_NONE); 12 | port->setDataBits(DATA_8); 13 | port->setStopBits(STOP_2); 14 | 15 | if (port->open(QIODevice::ReadWrite) == true) { 16 | connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead())); 17 | connect(port, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool))); 18 | if (!(port->lineStatus() & LS_DSR)) 19 | qDebug() << "warning: device is not turned on"; 20 | qDebug() << "listening for data on" << port->portName(); 21 | } 22 | else { 23 | qDebug() << "device failed to open:" << port->errorString(); 24 | } 25 | } 26 | 27 | void PortListener::onReadyRead() 28 | { 29 | QByteArray bytes; 30 | int a = port->bytesAvailable(); 31 | bytes.resize(a); 32 | port->read(bytes.data(), bytes.size()); 33 | qDebug() << "bytes read:" << bytes.size(); 34 | qDebug() << "bytes:" << bytes; 35 | } 36 | 37 | void PortListener::onDsrChanged(bool status) 38 | { 39 | if (status) 40 | qDebug() << "device was turned on"; 41 | else 42 | qDebug() << "device was turned off"; 43 | } 44 | -------------------------------------------------------------------------------- /print.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | 3 | print.h 4 | 5 | Functions for printing to screen. 6 | 7 | ************************************************************************ 8 | 9 | This file is part of QRealFourier. 10 | 11 | QRealFourier is free software: you can redistribute it and/or modify it 12 | under the terms of the Lesser GNU General Public License as published 13 | by the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | Foobar is distributed in the hope that it will be useful, but WITHOUT 17 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public 19 | License for more details. 20 | 21 | You should have received a copy of the Lesser GNU General Public License 22 | along with Foobar. If not, see . 23 | 24 | ************************************************************************ 25 | 26 | Copyright © 2012 - 2013 Christoph Stallmann, University of Pretoria 27 | 28 | Developer: Christoph Stallmann 29 | University of Pretoria 30 | Department of Computer Science 31 | 32 | http://www.visore.org 33 | http://sourceforge.net/projects/qrealfourier 34 | http://github.com/visore/QRealFourier 35 | 36 | qrealfourier@visore.org 37 | qrealfourier@gmail.com 38 | 39 | ***********************************************************************/ 40 | 41 | #ifndef PRINT_H 42 | #define PRINT_H 43 | 44 | #include 45 | #include 46 | 47 | using namespace std; 48 | 49 | void print(QString string) 50 | { 51 | cout << string.toLatin1().data(); 52 | } 53 | 54 | void print(float values[], int size) 55 | { 56 | for(int i = 0; i < size; ++i) 57 | { 58 | print(QString::number(values[i], 'f', 4)); 59 | print(" "); 60 | } 61 | print("\n"); 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MainWindow.cpp 3 | * @brief MainWindow Implementation. 4 | * @see MainWindow.h 5 | * @author Micha? Policht 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include "MainWindow.h" 12 | #include "MessageWindow.h" 13 | #include "QespTest.h" 14 | 15 | MainWindow::MainWindow() 16 | { 17 | //central widget 18 | QespTest *qespTest = new QespTest(); 19 | setCentralWidget(qespTest); 20 | //bottom dock widget 21 | MessageWindow *msgWindow = new MessageWindow(); 22 | addDockWidget(Qt::BottomDockWidgetArea, msgWindow); 23 | 24 | createActions(); 25 | createMenus(); 26 | 27 | setWindowTitle(tr("QextSerialPort Test Application")); 28 | } 29 | 30 | void MainWindow::about() 31 | { 32 | QMessageBox::about(this, tr("About "), 33 | tr("""
" 34 | "author: Michal Policht
" 35 | "xpolik@users.sourceforge.net")); 36 | } 37 | 38 | void MainWindow::createActions() 39 | { 40 | //File actions 41 | exitAct = new QAction(tr("E&xit"), this); 42 | exitAct->setShortcut(tr("CTRL+D")); 43 | exitAct->setStatusTip(tr("Exit the application")); 44 | connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); 45 | 46 | //Help actions 47 | aboutAct = new QAction(tr("&About"), this); 48 | aboutAct->setShortcut(tr("CTRL+A")); 49 | aboutAct->setStatusTip(tr("About application")); 50 | connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); 51 | } 52 | 53 | void MainWindow::createMenus() 54 | { 55 | fileMenu = menuBar()->addMenu(tr("&File")); 56 | fileMenu->addAction(exitAct); 57 | 58 | helpMenu = menuBar()->addMenu(tr("&Help")); 59 | helpMenu->addAction(aboutAct); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /qextserialport/README: -------------------------------------------------------------------------------- 1 | = About QextSerialPort = 2 | 3 | QextSerialPort provides an interface to old fashioned serial ports for Qt-based applications. It currently supports Mac OS X, Windows, Linux, FreeBSD. 4 | 5 | http://code.google.com/p/qextserialport/ 6 | 7 | == How to use (1) == 8 | 9 | * Download the source code. 10 | 11 | * Put the source code in any directory you like. For example, 3rdparty: 12 | 13 | |-- project.pro 14 | |-- .... 15 | |-- 3rdparty\ 16 | | |-- qextserialport\ 17 | | | 18 | 19 | * Add following line to your qmake project file: 20 | 21 | include(3rdparty/qextserialport/src/qextserialport.pri) 22 | 23 | * Using QextSerialPort in your code. Enjoy it! 24 | 25 | #include "qextserialport.h" 26 | .... 27 | QextSerialPort * port = new QextSerialPort(); 28 | .... 29 | 30 | == How to use (2) == 31 | It's very easy to compile QextSerialPort directly into your application 32 | (see above section), however, we would prefer to use it as a shared library. 33 | 34 | * Download the source code, and put it in any location you like. 35 | 36 | * Run following command to generate library. 37 | 38 | qmake 39 | make (or nmake) 40 | sudo make install (or nmake install) 41 | 42 | * Add following line to your project's file 43 | 44 | CONFIG += extserialport 45 | 46 | * Using QextSerialPort in your code. Enjoy it! 47 | 48 | #include "qextserialport.h" 49 | .... 50 | QextSerialPort * port = new QextSerialPort(); 51 | .... 52 | 53 | == Build Documents == 54 | * Run 55 | qmake 56 | make docs 57 | 58 | * Note: More information can be found in doc/readme.txt 59 | 60 | == Build examples == 61 | * Goto examples directory, then run 62 | qmake (or qmake -r) 63 | make (or nmake) 64 | 65 | -------------------------------------------------------------------------------- /qledindicator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "qledindicator.h" 5 | 6 | const qreal QLedIndicator::scaledSize = 1000; /* Visual Studio static const mess */ 7 | 8 | QLedIndicator::QLedIndicator(QWidget *parent) : QAbstractButton(parent) 9 | { 10 | setMinimumSize(24,24); 11 | setCheckable(true); 12 | onColor1 = QColor(0,255,0); 13 | onColor2 = QColor(0,192,0); 14 | offColor1 = QColor(0,28,0); 15 | offColor2 = QColor(0,128,0); 16 | } 17 | 18 | void QLedIndicator::resizeEvent(QResizeEvent *event) { 19 | update(); 20 | } 21 | 22 | void QLedIndicator::paintEvent(QPaintEvent *event) { 23 | qreal realSize = qMin(width(), height()); 24 | 25 | QRadialGradient gradient; 26 | QPainter painter(this); 27 | QPen pen(Qt::black); 28 | pen.setWidth(1); 29 | 30 | painter.setRenderHint(QPainter::Antialiasing); 31 | painter.translate(width()/2, height()/2); 32 | painter.scale(realSize/scaledSize, realSize/scaledSize); 33 | 34 | gradient = QRadialGradient (QPointF(-500,-500), 1500, QPointF(-500,-500)); 35 | gradient.setColorAt(0, QColor(224,224,224)); 36 | gradient.setColorAt(1, QColor(28,28,28)); 37 | painter.setPen(pen); 38 | painter.setBrush(QBrush(gradient)); 39 | painter.drawEllipse(QPointF(0,0), 500, 500); 40 | 41 | gradient = QRadialGradient (QPointF(500,500), 1500, QPointF(500,500)); 42 | gradient.setColorAt(0, QColor(224,224,224)); 43 | gradient.setColorAt(1, QColor(28,28,28)); 44 | painter.setPen(pen); 45 | painter.setBrush(QBrush(gradient)); 46 | painter.drawEllipse(QPointF(0,0), 450, 450); 47 | 48 | painter.setPen(pen); 49 | if( isChecked() ) { 50 | gradient = QRadialGradient (QPointF(-500,-500), 1500, QPointF(-500,-500)); 51 | gradient.setColorAt(0, onColor1); 52 | gradient.setColorAt(1, onColor2); 53 | } else { 54 | gradient = QRadialGradient (QPointF(500,500), 1500, QPointF(500,500)); 55 | gradient.setColorAt(0, offColor1); 56 | gradient.setColorAt(1, offColor2); 57 | } 58 | painter.setBrush(gradient); 59 | painter.drawEllipse(QPointF(0,0), 400, 400); 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator_unix.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialenumerator.h" 33 | #include "qextserialenumerator_p.h" 34 | #include 35 | 36 | void QextSerialEnumeratorPrivate::platformSpecificInit() 37 | { 38 | } 39 | 40 | void QextSerialEnumeratorPrivate::platformSpecificDestruct() 41 | { 42 | } 43 | 44 | QList QextSerialEnumeratorPrivate::getPorts_sys() 45 | { 46 | QList infoList; 47 | QESP_WARNING("Enumeration for POSIX systems (except Linux) is not implemented yet."); 48 | return infoList; 49 | } 50 | 51 | bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool setup) 52 | { 53 | Q_UNUSED(setup) 54 | QESP_WARNING("Notifications for *Nix/FreeBSD are not implemented yet"); 55 | return false; 56 | } 57 | -------------------------------------------------------------------------------- /qextserialport/doc/qextserialport.qdocconf: -------------------------------------------------------------------------------- 1 | # Run qdoc3 from the directory that contains this file. 2 | project = qesp 3 | description = QextSerialPort Reference Documentation 4 | url = http://code.google.com/p/qextserialport 5 | 6 | outputencoding = UTF-8 7 | language = Cpp 8 | 9 | #Paths are relative to the location of this file 10 | headerdirs = . ../src 11 | sourcedirs = . ../src 12 | exampledirs = ../examples .. 13 | imagedirs = ./examples/images images 14 | 15 | Cpp.ignoretokens = QEXTSERIALPORT_EXPORT 16 | 17 | indexes = $QTDIR/doc/html/qt.index 18 | 19 | qhp.projects = qesp 20 | qhp.qesp.file = qesp.qhp 21 | qhp.qesp.namespace = com.google.code.qextserialport.120 22 | qhp.qesp.virtualFolder = qdoc 23 | qhp.qesp.indexTitle = QextSerialPort Reference Documentation 24 | qhp.qesp.indexRoot = 25 | qhp.qesp.extraFiles = style/style.css 26 | 27 | 28 | #------------------------------------------------------------------ 29 | outputdir = html 30 | outputformats = HTML 31 | 32 | headers.fileextensions = "*.h" 33 | sources.fileextensions = "*.cpp *.qdoc" 34 | 35 | HTML.templatedir = . 36 | HTML.stylesheets = style/style.css 37 | 38 | HTML.headerstyles = " \n" 39 | HTML.endheader = "\n" 40 | 41 | HTML.postheader = "\n" \ 42 | "\n" \ 43 | "
" \ 44 | "Home ·" \ 45 | " All Classes ·" \ 46 | "
" 47 | 48 | HTML.footer = "


\n" \ 49 | "\n" \ 50 | "\n" \ 51 | "\n" \ 52 | "\n" \ 53 | "
Copyright © 2000-2012QextSerialPort Project
QextSerialPort Manual
" 54 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/MessageWindow.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MessageWindow.h 3 | * @brief Message Window. 4 | * @see MessageWindow 5 | * @author Micha? Policht 6 | */ 7 | 8 | #ifndef MESSAGEWINDOW_H_ 9 | #define MESSAGEWINDOW_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | /** 16 | * Message Window. Handling errors and other messages. 17 | */ 18 | class MessageWindow: public QDockWidget 19 | { 20 | Q_OBJECT 21 | 22 | QTextEdit msgTextEdit; ///< Main widget. 23 | static MessageWindow *MsgHandler; ///< Set in constructor. 24 | static const char *WINDOW_TITLE; ///< Window title. 25 | 26 | private: 27 | static QString QtMsgToQString(QtMsgType type, const char *msg); 28 | 29 | protected: 30 | /** 31 | * Handle custom events. MessageWindow hadles custom events listed in 32 | * EventType enum. 33 | */ 34 | virtual void customEvent(QEvent* event); 35 | 36 | public: 37 | enum EventType {MessageEventType = QEvent::User}; ///< Custom event types. 38 | 39 | /** 40 | * Default constructor. 41 | * @param parent parent widget. 42 | * @param flags widget flags. 43 | */ 44 | MessageWindow(QWidget* parent = 0, Qt::WindowFlags flags = 0); 45 | 46 | /** 47 | * Append message wrapper. Since ISO forbids casting member functions 48 | * to C functions, wrapper is needed to use this class as QtMsgHandler. 49 | * This method is thread-safe but not reentrant. 50 | * @param type message type. 51 | * @param msg message string. 52 | */ 53 | static void AppendMsgWrapper(QtMsgType type, const char *msg); 54 | #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 55 | static void AppendMsgWrapper(QtMsgType type, const QMessageLogContext &context, const QString &msg); 56 | #endif 57 | /** 58 | * Post message event to the main event loop. This function encapsulates 59 | * message into MessageEvent object and passes it to the main event loop. 60 | * @param type message type. 61 | * @param msg message string. 62 | */ 63 | void postMsgEvent(QtMsgType type, const char *msg); 64 | 65 | }; 66 | 67 | 68 | /** 69 | * Message Event. Custom event used by @ref MessageWindow to provide multi-threaded 70 | * access. Encapsulates message inside @a msg variable. 71 | */ 72 | class MessageEvent: public QEvent 73 | { 74 | public: 75 | QString msg; ///< Message string. 76 | 77 | /** 78 | * Contructor. 79 | * @param msg message to post. 80 | */ 81 | MessageEvent(QString &msg); 82 | }; 83 | 84 | #endif /*MESSAGEWINDOW_H_*/ 85 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport_global.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #ifndef QEXTSERIALPORT_GLOBAL_H 33 | #define QEXTSERIALPORT_GLOBAL_H 34 | 35 | #include 36 | 37 | #ifdef QEXTSERIALPORT_BUILD_SHARED 38 | # define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT 39 | #elif defined(QEXTSERIALPORT_USING_SHARED) 40 | # define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT 41 | #else 42 | # define QEXTSERIALPORT_EXPORT 43 | #endif 44 | 45 | // ### for compatible with old version. should be removed in QESP 2.0 46 | #ifdef _TTY_NOWARN_ 47 | # define QESP_NO_WARN 48 | #endif 49 | #ifdef _TTY_NOWARN_PORT_ 50 | # define QESP_NO_PORTABILITY_WARN 51 | #endif 52 | 53 | /*if all warning messages are turned off, flag portability warnings to be turned off as well*/ 54 | #ifdef QESP_NO_WARN 55 | # define QESP_NO_PORTABILITY_WARN 56 | #endif 57 | 58 | /*macros for warning and debug messages*/ 59 | #ifdef QESP_NO_PORTABILITY_WARN 60 | # define QESP_PORTABILITY_WARNING while (false)qWarning 61 | #else 62 | # define QESP_PORTABILITY_WARNING qWarning 63 | #endif /*QESP_NOWARN_PORT*/ 64 | 65 | #ifdef QESP_NO_WARN 66 | # define QESP_WARNING while (false)qWarning 67 | #else 68 | # define QESP_WARNING qWarning 69 | #endif /*QESP_NOWARN*/ 70 | 71 | #endif // QEXTSERIALPORT_GLOBAL_H 72 | 73 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #ifndef _QEXTSERIALENUMERATOR_H_ 33 | #define _QEXTSERIALENUMERATOR_H_ 34 | 35 | #include 36 | #include 37 | #include "qextserialport_global.h" 38 | 39 | struct QextPortInfo { 40 | QString portName; ///< Port name. 41 | QString physName; ///< Physical name. 42 | QString friendName; ///< Friendly name. 43 | QString enumName; ///< Enumerator name. 44 | int vendorID; ///< Vendor ID. 45 | int productID; ///< Product ID 46 | }; 47 | 48 | class QextSerialEnumeratorPrivate; 49 | class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject 50 | { 51 | Q_OBJECT 52 | Q_DECLARE_PRIVATE(QextSerialEnumerator) 53 | public: 54 | QextSerialEnumerator(QObject *parent=0); 55 | ~QextSerialEnumerator(); 56 | 57 | static QList getPorts(); 58 | void setUpNotifications(); 59 | 60 | Q_SIGNALS: 61 | void deviceDiscovered(const QextPortInfo &info); 62 | void deviceRemoved(const QextPortInfo &info); 63 | 64 | private: 65 | Q_DISABLE_COPY(QextSerialEnumerator) 66 | #if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) 67 | Q_PRIVATE_SLOT(d_func(), void _q_deviceEvent()) 68 | #endif 69 | QextSerialEnumeratorPrivate *d_ptr; 70 | }; 71 | 72 | #endif /*_QEXTSERIALENUMERATOR_H_*/ 73 | -------------------------------------------------------------------------------- /qledindicator.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2010 by Tn * 3 | * thenobody@poczta.fm * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU Library General Public License as * 7 | * published by the Free Software Foundation; either version 3 of the * 8 | * License, or (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU Library General Public * 16 | * License along with this program; if not, write to the * 17 | * Free Software Foundation, Inc., * 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 19 | ***************************************************************************/ 20 | 21 | #ifndef QLEDINDICATOR_H 22 | #define QLEDINDICATOR_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class QLedIndicator : public QAbstractButton 30 | { 31 | Q_PROPERTY(QColor onColor1 WRITE setOnColor1 READ getOnColor1 ); 32 | Q_PROPERTY(QColor onColor2 WRITE setOnColor2 READ getOnColor2 ); 33 | Q_PROPERTY(QColor offColor1 WRITE setOffColor1 READ getOffColor1 ); 34 | Q_PROPERTY(QColor offColor2 WRITE setOffColor2 READ getOffColor2 ); 35 | Q_OBJECT 36 | public: 37 | QLedIndicator(QWidget *parent); 38 | 39 | void setOnColor1(QColor c) { onColor1 = c; } 40 | void setOffColor1(QColor c) { offColor1 = c; } 41 | void setOnColor2(QColor c) { onColor2 = c; } 42 | void setOffColor2(QColor c) { offColor2 = c; } 43 | 44 | QColor getOnColor1(void) { return onColor1; } 45 | QColor getOffColor1(void) { return offColor1; } 46 | QColor getOnColor2(void) { return onColor2; } 47 | QColor getOffColor2(void) { return offColor2; } 48 | 49 | protected: 50 | virtual void paintEvent (QPaintEvent *event); 51 | virtual void resizeEvent(QResizeEvent *event); 52 | 53 | private: 54 | static const qreal scaledSize; /* init in cpp */ 55 | QColor onColor1, offColor1; 56 | QColor onColor2, offColor2; 57 | QPixmap ledBuffer; 58 | }; 59 | 60 | #endif // QLEDINDICATOR_H 61 | -------------------------------------------------------------------------------- /qextserialport/doc/style/style.css: -------------------------------------------------------------------------------- 1 | a:link, a:visited { 2 | color: #00732F; 3 | text-decoration: none; 4 | font-weight: bold; 5 | } 6 | 7 | body { 8 | font: normal 400 14px/1.2 Arial; 9 | margin-top: 85px; 10 | } 11 | 12 | h1 { 13 | margin: 0; 14 | } 15 | 16 | h2 { 17 | font: 500 20px/1.2 Arial; 18 | } 19 | 20 | h3.fn, span.fn { 21 | -moz-border-radius: 7px 7px 7px 7px; 22 | -webkit-border-radius: 7px 7px 7px 7px; 23 | border-radius: 7px 7px 7px 7px; 24 | background-color: #F6F6F6; 25 | border-width: 1px; 26 | border-style: solid; 27 | border-color: #E6E6E6; 28 | word-spacing: 3px; 29 | padding: 3px 5px; 30 | } 31 | 32 | table, pre { 33 | -moz-border-radius: 7px 7px 7px 7px; 34 | -webkit-border-radius: 7px 7px 7px 7px; 35 | border-radius: 7px 7px 7px 7px; 36 | background-color: #F6F6F6; 37 | border: 1px solid #E6E6E6; 38 | border-collapse: separate; 39 | font-size: 12px; 40 | line-height: 1.2; 41 | margin-bottom: 25px; 42 | margin-left: 15px; 43 | } 44 | 45 | table td { 46 | padding: 3px 15px 3px 20px; 47 | } 48 | 49 | table tr.even { 50 | background-color: white; 51 | color: #66666E; 52 | } 53 | 54 | table tr.odd { 55 | background-color: #F6F6F6; 56 | color: #66666E; 57 | } 58 | 59 | li { 60 | margin-bottom: 10px; 61 | padding-left: 12px; 62 | } 63 | 64 | .cpp { 65 | display: block; 66 | margin: 10; 67 | overflow: hidden; 68 | overflow-x: hidden; 69 | overflow-y: hidden; 70 | padding: 20px 0 20px 0; 71 | } 72 | 73 | .footer { 74 | margin-top: 50px; 75 | } 76 | 77 | .memItemLeft { 78 | padding-right: 3px; 79 | } 80 | 81 | .memItemRight { 82 | padding: 3px 15px 3px 0; 83 | } 84 | 85 | .qml { 86 | display: block; 87 | margin: 10; 88 | overflow: hidden; 89 | overflow-x: hidden; 90 | overflow-y: hidden; 91 | padding: 20px 0 20px 0; 92 | } 93 | 94 | .qmldefault { 95 | padding-left: 5px; 96 | float: right; 97 | color: red; 98 | } 99 | 100 | .qmlreadonly { 101 | padding-left: 5px; 102 | float: right; 103 | color: #254117; 104 | } 105 | 106 | .rightAlign { 107 | padding: 3px 5px 3px 10px; 108 | text-align: right; 109 | } 110 | 111 | .title { 112 | background-color: white; 113 | color: #44A51C; 114 | font-family: Verdana; 115 | font-size: 35px; 116 | font-weight: normal; 117 | left: 0; 118 | padding-bottom: 5px; 119 | padding-left: 16px; 120 | padding-top: 20px; 121 | position: absolute; 122 | right: 0; 123 | top: 0; 124 | } 125 | 126 | .toc { 127 | float: right; 128 | -moz-border-radius: 7px 7px 7px 7px; 129 | -webkit-border-radius: 7px 7px 7px 7px; 130 | border-radius: 7px 7px 7px 7px; 131 | background-color: #F6F6F6; 132 | border: 1px solid #DDD; 133 | margin: 0 20px 10px 10px; 134 | padding: 20px 15px 20px 20px; 135 | height: auto; 136 | width: 200px; 137 | } 138 | -------------------------------------------------------------------------------- /qextserialport/qextserialport.pro: -------------------------------------------------------------------------------- 1 | ############################### *User Config* ############################### 2 | 3 | # Uncomment following line if you want to build a static library 4 | # CONFIG += qesp_static 5 | 6 | # Uncomment following line if you want to build framework for mac 7 | # macx:CONFIG += qesp_mac_framework 8 | 9 | # Uncomment following line if you want to enable udev for linux 10 | # linux*:CONFIG += qesp_linux_udev 11 | 12 | # Note: you can create a ".qmake.cache" file, then copy these lines to it. 13 | # If so, you can avoid to change this project file. 14 | ############################### *User Config* ############################### 15 | 16 | defineReplace(qextLibraryName) { 17 | unset(LIBRARY_NAME) 18 | LIBRARY_NAME = $$1 19 | macx:qesp_mac_framework { 20 | QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME 21 | export(QMAKE_FRAMEWORK_BUNDLE_NAME) 22 | } else { 23 | greaterThan(QT_MAJOR_VERSION, 4):LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION, 24 | } 25 | CONFIG(debug, debug|release) { 26 | !debug_and_release|build_pass { 27 | mac:LIBRARY_NAME = $${LIBRARY_NAME}_debug 28 | else:win32:LIBRARY_NAME = $${LIBRARY_NAME}d 29 | } 30 | } 31 | return($$LIBRARY_NAME) 32 | } 33 | 34 | TEMPLATE=lib 35 | include(src/qextserialport.pri) 36 | 37 | #create_prl is needed, otherwise, MinGW can't found libqextserialport1.a 38 | CONFIG += create_prl 39 | 40 | #mac framework is designed for shared library 41 | macx:qesp_mac_framework:qesp_static: CONFIG -= qesp_static 42 | !macx:qesp_mac_framework:CONFIG -= qesp_mac_framework 43 | 44 | qesp_static { 45 | CONFIG += static 46 | } else { 47 | CONFIG += shared 48 | macx:!qesp_mac_framework:CONFIG += absolute_library_soname 49 | DEFINES += QEXTSERIALPORT_BUILD_SHARED 50 | } 51 | 52 | #Creare lib bundle for mac 53 | macx:qesp_mac_framework { 54 | CONFIG += lib_bundle 55 | FRAMEWORK_HEADERS.files = $$PUBLIC_HEADERS 56 | FRAMEWORK_HEADERS.path = Headers 57 | QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS 58 | } 59 | 60 | win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release build_all 61 | 62 | #For non-windows system, only depends on QtCore module 63 | unix:QT = core 64 | else:QT = core gui 65 | 66 | #generate proper library name 67 | greaterThan(QT_MAJOR_VERSION, 4) { 68 | QESP_LIB_BASENAME = QtExtSerialPort 69 | } else { 70 | QESP_LIB_BASENAME = qextserialport 71 | } 72 | TARGET = $$qextLibraryName($$QESP_LIB_BASENAME) 73 | VERSION = 1.2.0 74 | 75 | # generate feature file by qmake based on this *.in file. 76 | QMAKE_SUBSTITUTES += extserialport.prf.in 77 | OTHER_FILES += extserialport.prf.in 78 | 79 | # for make docs 80 | include(doc/doc.pri) 81 | 82 | # for make install 83 | win32:!qesp_static { 84 | dlltarget.path = $$[QT_INSTALL_BINS] 85 | INSTALLS += dlltarget 86 | } 87 | !macx|!qesp_mac_framework { 88 | headers.files = $$PUBLIC_HEADERS 89 | headers.path = $$[QT_INSTALL_HEADERS]/QtExtSerialPort 90 | INSTALLS += headers 91 | } 92 | target.path = $$[QT_INSTALL_LIBS] 93 | 94 | features.files = extserialport.prf 95 | features.path = $$[QMAKE_MKSPECS]/features 96 | INSTALLS += target features 97 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/hled.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hled.h" 3 | 4 | struct HLed::Private 5 | { 6 | public: 7 | Private() 8 | : darkerFactor(300), color(Qt::green), isOn(true) 9 | { } 10 | 11 | int darkerFactor; 12 | QColor color; 13 | bool isOn; 14 | }; 15 | 16 | HLed::HLed(QWidget *parent) 17 | :QWidget(parent), m_d(new Private) 18 | { 19 | } 20 | 21 | HLed::~HLed() 22 | { 23 | delete m_d; 24 | } 25 | 26 | QColor HLed::color() const 27 | { 28 | return m_d->color; 29 | } 30 | 31 | void HLed::setColor(const QColor &color) 32 | { 33 | if (m_d->color == color) 34 | return; 35 | update(); 36 | } 37 | 38 | QSize HLed::sizeHint() const 39 | { 40 | return QSize(20, 20); 41 | } 42 | 43 | QSize HLed::minimumSizeHint() const 44 | { 45 | return QSize(16, 16); 46 | } 47 | 48 | void HLed::toggle() 49 | { 50 | m_d->isOn = !m_d->isOn; 51 | update(); 52 | } 53 | 54 | void HLed::turnOn(bool on) 55 | { 56 | m_d->isOn = on; 57 | update(); 58 | } 59 | 60 | void HLed::turnOff(bool off) 61 | { 62 | turnOn(!off); 63 | } 64 | 65 | void HLed::paintEvent(QPaintEvent * /*event*/) 66 | { 67 | int width = ledWidth(); 68 | 69 | QPainter painter(this); 70 | painter.setRenderHint(QPainter::Antialiasing); 71 | 72 | QColor color = m_d->isOn ? m_d->color 73 | : m_d->color.darker(m_d->darkerFactor); 74 | 75 | QBrush brush; 76 | brush.setStyle(Qt::SolidPattern); 77 | brush.setColor(color); 78 | painter.setBrush(brush); 79 | // draw plain 80 | painter.drawEllipse(1, 1, width-1, width-1); 81 | 82 | QPen pen; 83 | pen.setWidth(2); 84 | 85 | int pos = width / 5 + 1; 86 | int lightWidth = width * 2 / 3; 87 | int lightQuote = 130 * 2 / (lightWidth ? lightWidth : 1) + 100; 88 | 89 | // draw bright spot 90 | while (lightWidth) { 91 | color = color.lighter(lightQuote); 92 | pen.setColor(color); 93 | painter.setPen(pen); 94 | painter.drawEllipse(pos, pos, lightWidth, lightWidth); 95 | lightWidth--; 96 | 97 | if (!lightWidth) 98 | break; 99 | 100 | painter.drawEllipse(pos, pos, lightWidth, lightWidth); 101 | lightWidth--; 102 | 103 | if (!lightWidth) 104 | break; 105 | 106 | painter.drawEllipse(pos, pos, lightWidth, lightWidth); 107 | pos++; 108 | lightWidth--; 109 | } 110 | 111 | //draw border 112 | painter.setBrush(Qt::NoBrush); 113 | 114 | int angle = -720; 115 | color = palette().color(QPalette::Light); 116 | 117 | for (int arc=120; arc<2880; arc+=240) { 118 | pen.setColor(color); 119 | painter.setPen(pen); 120 | int w = width - pen.width()/2; 121 | painter.drawArc(pen.width()/2, pen.width()/2, w, w, angle+arc, 240); 122 | painter.drawArc(pen.width()/2, pen.width()/2, w, w, angle-arc, 240); 123 | color = color.darker(110); 124 | } 125 | } 126 | 127 | int HLed::ledWidth() const 128 | { 129 | int width = qMin(this->width(), this->height()); 130 | width -= 2; 131 | return width > 0 ? width : 0; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/MessageWindow.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MessageWindow.cpp 3 | * @brief MessageWindow Implementation. 4 | * @see MessageWindow.h 5 | * @author Micha? Policht 6 | */ 7 | 8 | #include 9 | #include "MessageWindow.h" 10 | #include 11 | #include 12 | #include 13 | 14 | const char *MessageWindow::WINDOW_TITLE = "Message Window"; 15 | MessageWindow *MessageWindow::MsgHandler = NULL; 16 | 17 | MessageWindow::MessageWindow(QWidget *parent, Qt::WindowFlags flags) 18 | : QDockWidget(parent, flags), 19 | msgTextEdit(this) 20 | { 21 | setWindowTitle(tr(WINDOW_TITLE)); 22 | msgTextEdit.setReadOnly(true); 23 | setWidget(&msgTextEdit); 24 | 25 | MessageWindow::MsgHandler = this; 26 | } 27 | 28 | //static 29 | QString MessageWindow::QtMsgToQString(QtMsgType type, const char *msg) 30 | { 31 | switch (type) { 32 | case QtDebugMsg: 33 | return QLatin1String("Debug: ")+QLatin1String(msg); 34 | case QtWarningMsg: 35 | return QLatin1String("Warning: ")+QLatin1String(msg); 36 | case QtCriticalMsg: 37 | return QLatin1String("Critical: ")+QLatin1String(msg); 38 | case QtFatalMsg: 39 | return QLatin1String("Fatal: ")+QLatin1String(msg); 40 | default: 41 | return QLatin1String("Unrecognized message type: ")+QLatin1String(msg); 42 | } 43 | } 44 | 45 | //static 46 | void MessageWindow::AppendMsgWrapper(QtMsgType type, const char *msg) 47 | { 48 | static QMutex mutex; 49 | QMutexLocker locker(&mutex); 50 | 51 | if (MessageWindow::MsgHandler != NULL) 52 | return MessageWindow::MsgHandler->postMsgEvent(type, msg); 53 | else 54 | fprintf(stderr, "%s", MessageWindow::QtMsgToQString(type, msg).toLatin1().data()); 55 | } 56 | 57 | #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 58 | void MessageWindow::AppendMsgWrapper(QtMsgType type, const QMessageLogContext & /*context*/, const QString &msg) 59 | { 60 | AppendMsgWrapper(type, msg.toLatin1().data()); 61 | } 62 | #endif 63 | 64 | void MessageWindow::customEvent(QEvent *event) 65 | { 66 | if (static_cast(event->type()) == MessageWindow::MessageEventType) 67 | msgTextEdit.append(dynamic_cast(event)->msg); 68 | } 69 | 70 | void MessageWindow::postMsgEvent(QtMsgType type, const char *msg) 71 | { 72 | QString qmsg = MessageWindow::QtMsgToQString(type, msg); 73 | switch (type) { 74 | case QtDebugMsg: 75 | break; 76 | case QtWarningMsg: 77 | qmsg.prepend(QLatin1String("")); 78 | qmsg.append(QLatin1String("")); 79 | break; 80 | case QtCriticalMsg: 81 | if (QMessageBox::critical(this, QLatin1String("Critical Error"), qmsg, 82 | QMessageBox::Ignore, 83 | QMessageBox::Abort, 84 | QMessageBox::NoButton) == QMessageBox::Abort) 85 | abort(); // core dump 86 | qmsg.prepend(QLatin1String("")); 87 | qmsg.append(QLatin1String("")); 88 | break; 89 | case QtFatalMsg: 90 | QMessageBox::critical(this, QLatin1String("Fatal Error"), qmsg, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); 91 | abort(); // deliberately core dump 92 | } 93 | //it's impossible to change GUI directly from thread other than the main thread 94 | //so post message encapsulated by MessageEvent to the main thread's event queue 95 | QCoreApplication::postEvent(this, new MessageEvent(qmsg)); 96 | } 97 | 98 | MessageEvent::MessageEvent(QString &msg): 99 | QEvent(static_cast(MessageWindow::MessageEventType)) 100 | { 101 | this->msg = msg; 102 | } 103 | -------------------------------------------------------------------------------- /qextserialport/examples/qespta/QespTest.cpp: -------------------------------------------------------------------------------- 1 | /* QespTest.cpp 2 | **************************************/ 3 | #include "QespTest.h" 4 | #include "qextserialport.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | QespTest::QespTest(QWidget *parent) 13 | : QWidget(parent) 14 | 15 | { 16 | //modify the port settings on your own 17 | #ifdef Q_OS_UNIX 18 | port = new QextSerialPort(QLatin1String("/dev/ttyS0"), QextSerialPort::Polling); 19 | #else 20 | port = new QextSerialPort(QLatin1String("COM1"), QextSerialPort::Polling); 21 | #endif /*Q_OS_UNIX*/ 22 | port->setBaudRate(BAUD19200); 23 | port->setFlowControl(FLOW_OFF); 24 | port->setParity(PAR_NONE); 25 | port->setDataBits(DATA_8); 26 | port->setStopBits(STOP_2); 27 | //set timeouts to 500 ms 28 | port->setTimeout(500); 29 | 30 | message = new QLineEdit(this); 31 | 32 | // transmit receive 33 | QPushButton *transmitButton = new QPushButton(tr("Transmit")); 34 | connect(transmitButton, SIGNAL(clicked()), SLOT(transmitMsg())); 35 | QPushButton *receiveButton = new QPushButton(tr("Receive")); 36 | connect(receiveButton, SIGNAL(clicked()), SLOT(receiveMsg())); 37 | QHBoxLayout *trLayout = new QHBoxLayout; 38 | trLayout->addWidget(transmitButton); 39 | trLayout->addWidget(receiveButton); 40 | 41 | //CR LF 42 | QPushButton *CRButton = new QPushButton(tr("CR")); 43 | connect(CRButton, SIGNAL(clicked()), SLOT(appendCR())); 44 | QPushButton *LFButton = new QPushButton(tr("LF")); 45 | connect(LFButton, SIGNAL(clicked()), SLOT(appendLF())); 46 | QHBoxLayout *crlfLayout = new QHBoxLayout; 47 | crlfLayout->addWidget(CRButton); 48 | crlfLayout->addWidget(LFButton); 49 | 50 | //open close 51 | QPushButton *openButton = new QPushButton(tr("Open")); 52 | connect(openButton, SIGNAL(clicked()), SLOT(openPort())); 53 | QPushButton *closeButton = new QPushButton(tr("Close")); 54 | connect(closeButton, SIGNAL(clicked()), SLOT(closePort())); 55 | QHBoxLayout *ocLayout = new QHBoxLayout; 56 | ocLayout->addWidget(openButton); 57 | ocLayout->addWidget(closeButton); 58 | 59 | received_msg = new QTextEdit(); 60 | 61 | QVBoxLayout *myVBox = new QVBoxLayout; 62 | myVBox->addWidget(message); 63 | myVBox->addLayout(crlfLayout); 64 | myVBox->addLayout(trLayout); 65 | myVBox->addLayout(ocLayout); 66 | myVBox->addWidget(received_msg); 67 | setLayout(myVBox); 68 | 69 | qDebug("isOpen : %d", port->isOpen()); 70 | } 71 | 72 | QespTest::~QespTest() 73 | { 74 | delete port; 75 | port = NULL; 76 | } 77 | 78 | void QespTest::transmitMsg() 79 | { 80 | int i = port->write(message->text().toLatin1()); 81 | qDebug("trasmitted : %d", i); 82 | } 83 | 84 | void QespTest::receiveMsg() 85 | { 86 | char buff[1024]; 87 | int numBytes; 88 | 89 | numBytes = port->bytesAvailable(); 90 | if(numBytes > 1024) 91 | numBytes = 1024; 92 | 93 | int i = port->read(buff, numBytes); 94 | if (i != -1) 95 | buff[i] = '\0'; 96 | else 97 | buff[0] = '\0'; 98 | QString msg = QLatin1String(buff); 99 | 100 | received_msg->append(msg); 101 | received_msg->ensureCursorVisible(); 102 | qDebug("bytes available: %d", numBytes); 103 | qDebug("received: %d", i); 104 | } 105 | 106 | 107 | void QespTest::appendCR() 108 | { 109 | message->insert(QLatin1String("\x0D")); 110 | } 111 | 112 | void QespTest::appendLF() 113 | { 114 | message->insert(QLatin1String("\x0A")); 115 | } 116 | 117 | void QespTest::closePort() 118 | { 119 | port->close(); 120 | qDebug("is open: %d", port->isOpen()); 121 | } 122 | 123 | void QespTest::openPort() 124 | { 125 | port->open(QIODevice::ReadWrite | QIODevice::Unbuffered); 126 | qDebug("is open: %d", port->isOpen()); 127 | } 128 | 129 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "qextserialport.h" 8 | #include "qextserialport.h" 9 | #include "qextserialenumerator.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "qledindicator.h" 19 | #include 20 | 21 | namespace Ui { 22 | class MainWindow; 23 | } 24 | 25 | class MainWindow : public QMainWindow 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit MainWindow(QWidget *parent = 0); 31 | ~MainWindow(); 32 | 33 | typedef std::complex Complex; 34 | 35 | void setupRealtimeRawDataPlot(QCustomPlot *customPlot); 36 | void setupFFTDataPlot(QCustomPlot *customPlot,double data); 37 | void setupStyledDemo(QCustomPlot *customPlot); 38 | void setupAdvancedAxesDemo(QCustomPlot *customPlot); 39 | void setupColorMapDemo(QCustomPlot *customPlot); 40 | void ParseSignalFile(); 41 | 42 | void setupPlayground(QCustomPlot *customPlot); 43 | void init_port(); // port initialisation function 44 | void ReadFromBoard(); 45 | void SendCommandToBoard(QString Data); 46 | void listSerialPorts(); 47 | int FFTmain(); 48 | void shiftData(double *data, int len, double newValue); 49 | void logData(); 50 | 51 | //fft function declration 52 | void sdft_init_coeffs(); 53 | void sdft_init(); 54 | void sdft_add_data(); 55 | void sdft(); 56 | void isdft(); 57 | void ft(); 58 | double mag(Complex& c); 59 | void powr_spectrum(double *powr); 60 | 61 | 62 | void onReceiveMsg(); 63 | protected: 64 | void changeEvent(QEvent *e); 65 | 66 | private slots: 67 | void realtimeDataSlot(); 68 | // void screenShot(); 69 | // void allScreenShots(); 70 | // void transmitCmd(int value); // sending function 71 | void on_realtimeBtn_clicked(); 72 | //void onReadyReadFromBoard(); 73 | 74 | 75 | 76 | 77 | private Q_SLOTS : 78 | void on_connectOrDisconnectBtn_clicked(); 79 | void onPortNameChanged(const QString &name); 80 | void onBaudRateChanged(int idx); 81 | void onParityChanged(int idx); 82 | void onDataBitsChanged(int idx); 83 | void onStopBitsChanged(int idx); 84 | void onQueryModeChanged(int idx); 85 | void onTimeoutChanged(int val); 86 | void onReadyRead(); 87 | void onPortAddedOrRemoved(); 88 | void on_stopBtn_clicked(); 89 | void on_commandLinkBtnClearConsole_clicked(); 90 | void on_toolButton_browse_clicked(); 91 | void radioBtnbox_randData(); 92 | void radioBtnbox_offline(); 93 | 94 | void on_SendToSerialPort_clicked(); 95 | 96 | private: 97 | 98 | Ui::MainWindow *ui; 99 | QString demoName; 100 | QTimer dataTimer; 101 | QTimer dataTime_fft; 102 | QCPItemTracer *itemDemoPhaseTracer; 103 | int currentDemoIndex; 104 | QextSerialPort *port; 105 | QTimer *timer; 106 | QextSerialEnumerator *enumerator; 107 | double globalSerialDataValue =0; 108 | int prevTempAdc; 109 | int currentTempAdc; 110 | QLedIndicator *LED0; 111 | QLedIndicator *LED1; 112 | QLedIndicator *LED2; 113 | QFile logFile; 114 | QTextStream logSerialDataStream; 115 | QList serialDataList; 116 | 117 | //FFT Data Source 118 | static const int N = 512; 119 | // input signal 120 | int in[N]; 121 | 122 | // frequencies of input signal after ft 123 | // Size increased by one because the optimized sdft code writes data to freqs[N] 124 | Complex freqs[N+1]; 125 | 126 | // output signal after inverse ft of freqs 127 | double out1[N]; 128 | double out2[N]; 129 | 130 | // forward coeffs -2 PI e^iw -- normalized (divided by N) 131 | Complex coeffs[N]; 132 | // inverse coeffs 2 PI e^iw 133 | Complex icoeffs[N]; 134 | 135 | // global index for input and output signals 136 | int idx; 137 | 138 | int oldest_data, newest_data; 139 | int globalSerialDataCounter; 140 | }; 141 | 142 | #endif // MAINWINDOW_H 143 | -------------------------------------------------------------------------------- /qextserialport/LICENSE: -------------------------------------------------------------------------------- 1 | From QextSerialPort 1.2-beta on, we use MIT license for QextSerialPort project. 2 | 3 | == License == 4 | 5 | Copyright (c) 2000-2003 Wayne Roth 6 | Copyright (c) 2004-2007 Stefan Sander 7 | Copyright (c) 2007 Michal Policht 8 | Copyright (c) 2008 Brandon Fosdick 9 | Copyright (c) 2009-2010 Liam Staskawicz 10 | Copyright (c) 2011 Debao Zhang 11 | 12 | Web: http://code.google.com/p/qextserialport/ 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining 15 | a copy of this software and associated documentation files (the 16 | "Software"), to deal in the Software without restriction, including 17 | without limitation the rights to use, copy, modify, merge, publish, 18 | distribute, sublicense, and/or sell copies of the Software, and to 19 | permit persons to whom the Software is furnished to do so, subject to 20 | the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be 23 | included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | 33 | == Why license needed? == 34 | 35 | Many users complains that, without a proper licence they can not use this library. 36 | 37 | * http://groups.google.com/group/qextserialport/browse_thread/thread/0e8756920b01da82 38 | 39 | Hi, 40 | we are considering using a modified version of QExtSerialPort in one of our 41 | projects (Qt Creator, http://qt.gitorious.org/qt-creator). 42 | Would it be possible to add license header information or a license file to the 43 | QExtSerialPort code base? - This would make re-use of the code base easier. 44 | If that is not possible, could we redistribute the source code with BSD- 45 | license headers manually added? 46 | 47 | And 48 | 49 | I am also considering packaging the software for Debian, but I 50 | couldn't do it yet just because of the license. 51 | 52 | * http://code.google.com/p/qextserialport/issues/detail?id=8 53 | 54 | Questions: 55 | Can I use qextserialport in a commercial product? 56 | If yes, how? 57 | Compile it in? I guess no. 58 | If I can use it as a library, how should the README be formulated? 59 | Is the "MIT license" from 2008 appropriate? 60 | 61 | == Why can we use MIT? == 62 | 63 | Form the history of [http://lists.trolltech.com/qt-interest/2004-12/msg01022.html qt-interest mail list] 64 | 65 | * Wayne Roth, the original author of the project, had said that: 66 | 67 | the code is in the public domain. Do whatever you like with it. Right 68 | now I have too many other things to do to put any serious time into 69 | fixing it. Trolltech should be aware of this already; they asked 70 | about a license when they offered to host the tarball. 71 | 72 | * Stefan Sander, the maintainer of qextserialport on sourceforge, said that 73 | 74 | Hello, 75 | My project registration at !SourceForge have been approved. 76 | http://www.sf.net/projects/qextserialport 77 | I thought an initial licence of Public Domain would be best solution. 78 | Someone wrote: - Because its public domain, some could fork it under different licenses - 79 | 80 | And from [http://groups.google.com/group/qextserialport/browse_thread/thread/fbcddbfb4a0b5a51?pli=1 this thread] on qesp mail list, we can see that, current maintainers and users agree with a MIT licence. 81 | 82 | * Brandon Fosdick, 83 | 84 | I would vote for BSD or MIT :) 85 | 86 | * Liam Staskawicz, 87 | 88 | That works for me - let's call it MIT and go for it :) 89 | 90 | And from [[https://groups.google.com/forum/?fromgroups#!topic/qextserialport/P_5TrNHBICE this other thread]] on the same mailing list: 91 | 92 | * Michal Policht, 93 | 94 | I agree to license. 95 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator_p.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** Copyright (c) 2012 Doug Brown 9 | ** All right reserved. 10 | ** Web: http://code.google.com/p/qextserialport/ 11 | ** 12 | ** Permission is hereby granted, free of charge, to any person obtaining 13 | ** a copy of this software and associated documentation files (the 14 | ** "Software"), to deal in the Software without restriction, including 15 | ** without limitation the rights to use, copy, modify, merge, publish, 16 | ** distribute, sublicense, and/or sell copies of the Software, and to 17 | ** permit persons to whom the Software is furnished to do so, subject to 18 | ** the following conditions: 19 | ** 20 | ** The above copyright notice and this permission notice shall be 21 | ** included in all copies or substantial portions of the Software. 22 | ** 23 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | ** 31 | ****************************************************************************/ 32 | #ifndef _QEXTSERIALENUMERATOR_P_H_ 33 | #define _QEXTSERIALENUMERATOR_P_H_ 34 | 35 | // 36 | // W A R N I N G 37 | // ------------- 38 | // 39 | // This file is not part of the QESP API. It exists for the convenience 40 | // of other QESP classes. This header file may change from version to 41 | // version without notice, or even be removed. 42 | // 43 | // We mean it. 44 | // 45 | 46 | #include "qextserialenumerator.h" 47 | 48 | #ifdef Q_OS_WIN 49 | // needed for mingw to pull in appropriate dbt business... 50 | // probably a better way to do this 51 | // http://mingw-users.1079350.n2.nabble.com/DEV-BROADCAST-DEVICEINTERFACE-was-not-declared-in-this-scope-td3552762.html 52 | # ifdef __MINGW32__ 53 | # define _WIN32_WINNT 0x0501 54 | # define _WIN32_WINDOWS 0x0501 55 | # define WINVER 0x0501 56 | # endif 57 | # include 58 | #endif /*Q_OS_WIN*/ 59 | 60 | #ifdef Q_OS_MAC 61 | # include 62 | #endif /*Q_OS_MAC*/ 63 | 64 | #if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) 65 | # include 66 | extern "C" { 67 | # include 68 | } 69 | #endif 70 | 71 | class QextSerialRegistrationWidget; 72 | class QextSerialEnumeratorPrivate 73 | { 74 | Q_DECLARE_PUBLIC(QextSerialEnumerator) 75 | public: 76 | QextSerialEnumeratorPrivate(QextSerialEnumerator *enumrator); 77 | ~QextSerialEnumeratorPrivate(); 78 | void platformSpecificInit(); 79 | void platformSpecificDestruct(); 80 | 81 | static QList getPorts_sys(); 82 | bool setUpNotifications_sys(bool setup); 83 | 84 | #ifdef Q_OS_WIN 85 | LRESULT onDeviceChanged(WPARAM wParam, LPARAM lParam); 86 | bool matchAndDispatchChangedDevice(const QString &deviceID, const GUID &guid, WPARAM wParam); 87 | # ifdef QT_GUI_LIB 88 | QextSerialRegistrationWidget *notificationWidget; 89 | # endif 90 | #endif /*Q_OS_WIN*/ 91 | 92 | #ifdef Q_OS_MAC 93 | /*! 94 | * Search for serial ports using IOKit. 95 | * \param infoList list with result. 96 | */ 97 | static void iterateServicesOSX(io_object_t service, QList &infoList); 98 | static bool getServiceDetailsOSX(io_object_t service, QextPortInfo *portInfo); 99 | void onDeviceDiscoveredOSX(io_object_t service); 100 | void onDeviceTerminatedOSX(io_object_t service); 101 | friend void deviceDiscoveredCallbackOSX(void *ctxt, io_iterator_t serialPortIterator); 102 | friend void deviceTerminatedCallbackOSX(void *ctxt, io_iterator_t serialPortIterator); 103 | 104 | IONotificationPortRef notificationPortRef; 105 | #endif // Q_OS_MAC 106 | 107 | #if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) 108 | QSocketNotifier *notifier; 109 | int notifierFd; 110 | struct udev *udev; 111 | struct udev_monitor *monitor; 112 | 113 | void _q_deviceEvent(); 114 | #endif 115 | 116 | private: 117 | QextSerialEnumerator *q_ptr; 118 | }; 119 | 120 | #endif //_QEXTSERIALENUMERATOR_P_H_ 121 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/dialog.cpp: -------------------------------------------------------------------------------- 1 | #include "qextserialport.h" 2 | #include "qextserialenumerator.h" 3 | #include "dialog.h" 4 | #include "ui_dialog.h" 5 | #include 6 | 7 | Dialog::Dialog(QWidget *parent) : 8 | QDialog(parent), 9 | ui(new Ui::Dialog) 10 | { 11 | ui->setupUi(this); 12 | 13 | //! [0] 14 | foreach (QextPortInfo info, QextSerialEnumerator::getPorts()) 15 | ui->portBox->addItem(info.portName); 16 | //make sure user can input their own port name! 17 | ui->portBox->setEditable(true); 18 | 19 | ui->baudRateBox->addItem("1200", BAUD1200); 20 | ui->baudRateBox->addItem("2400", BAUD2400); 21 | ui->baudRateBox->addItem("4800", BAUD4800); 22 | ui->baudRateBox->addItem("9600", BAUD9600); 23 | ui->baudRateBox->addItem("19200", BAUD19200); 24 | ui->baudRateBox->setCurrentIndex(3); 25 | 26 | ui->parityBox->addItem("NONE", PAR_NONE); 27 | ui->parityBox->addItem("ODD", PAR_ODD); 28 | ui->parityBox->addItem("EVEN", PAR_EVEN); 29 | 30 | ui->dataBitsBox->addItem("5", DATA_5); 31 | ui->dataBitsBox->addItem("6", DATA_6); 32 | ui->dataBitsBox->addItem("7", DATA_7); 33 | ui->dataBitsBox->addItem("8", DATA_8); 34 | ui->dataBitsBox->setCurrentIndex(3); 35 | 36 | ui->stopBitsBox->addItem("1", STOP_1); 37 | ui->stopBitsBox->addItem("2", STOP_2); 38 | 39 | ui->queryModeBox->addItem("Polling", QextSerialPort::Polling); 40 | ui->queryModeBox->addItem("EventDriven", QextSerialPort::EventDriven); 41 | //! [0] 42 | 43 | ui->led->turnOff(); 44 | 45 | timer = new QTimer(this); 46 | timer->setInterval(40); 47 | //! [1] 48 | PortSettings settings = {BAUD9600, DATA_8, PAR_NONE, STOP_1, FLOW_OFF, 10}; 49 | port = new QextSerialPort(ui->portBox->currentText(), settings, QextSerialPort::Polling); 50 | //! [1] 51 | 52 | enumerator = new QextSerialEnumerator(this); 53 | enumerator->setUpNotifications(); 54 | 55 | connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), SLOT(onBaudRateChanged(int))); 56 | connect(ui->parityBox, SIGNAL(currentIndexChanged(int)), SLOT(onParityChanged(int))); 57 | connect(ui->dataBitsBox, SIGNAL(currentIndexChanged(int)), SLOT(onDataBitsChanged(int))); 58 | connect(ui->stopBitsBox, SIGNAL(currentIndexChanged(int)), SLOT(onStopBitsChanged(int))); 59 | connect(ui->queryModeBox, SIGNAL(currentIndexChanged(int)), SLOT(onQueryModeChanged(int))); 60 | connect(ui->timeoutBox, SIGNAL(valueChanged(int)), SLOT(onTimeoutChanged(int))); 61 | connect(ui->portBox, SIGNAL(editTextChanged(QString)), SLOT(onPortNameChanged(QString))); 62 | connect(ui->openCloseButton, SIGNAL(clicked()), SLOT(onOpenCloseButtonClicked())); 63 | connect(ui->sendButton, SIGNAL(clicked()), SLOT(onSendButtonClicked())); 64 | connect(timer, SIGNAL(timeout()), SLOT(onReadyRead())); 65 | connect(port, SIGNAL(readyRead()), SLOT(onReadyRead())); 66 | 67 | connect(enumerator, SIGNAL(deviceDiscovered(QextPortInfo)), SLOT(onPortAddedOrRemoved())); 68 | connect(enumerator, SIGNAL(deviceRemoved(QextPortInfo)), SLOT(onPortAddedOrRemoved())); 69 | 70 | setWindowTitle(tr("QextSerialPort Demo")); 71 | } 72 | 73 | Dialog::~Dialog() 74 | { 75 | delete ui; 76 | delete port; 77 | } 78 | 79 | void Dialog::changeEvent(QEvent *e) 80 | { 81 | QDialog::changeEvent(e); 82 | switch (e->type()) { 83 | case QEvent::LanguageChange: 84 | ui->retranslateUi(this); 85 | break; 86 | default: 87 | break; 88 | } 89 | } 90 | 91 | void Dialog::onPortNameChanged(const QString & /*name*/) 92 | { 93 | if (port->isOpen()) { 94 | port->close(); 95 | ui->led->turnOff(); 96 | } 97 | } 98 | //! [2] 99 | void Dialog::onBaudRateChanged(int idx) 100 | { 101 | port->setBaudRate((BaudRateType)ui->baudRateBox->itemData(idx).toInt()); 102 | } 103 | 104 | void Dialog::onParityChanged(int idx) 105 | { 106 | port->setParity((ParityType)ui->parityBox->itemData(idx).toInt()); 107 | } 108 | 109 | void Dialog::onDataBitsChanged(int idx) 110 | { 111 | port->setDataBits((DataBitsType)ui->dataBitsBox->itemData(idx).toInt()); 112 | } 113 | 114 | void Dialog::onStopBitsChanged(int idx) 115 | { 116 | port->setStopBits((StopBitsType)ui->stopBitsBox->itemData(idx).toInt()); 117 | } 118 | 119 | void Dialog::onQueryModeChanged(int idx) 120 | { 121 | port->setQueryMode((QextSerialPort::QueryMode)ui->queryModeBox->itemData(idx).toInt()); 122 | } 123 | 124 | void Dialog::onTimeoutChanged(int val) 125 | { 126 | port->setTimeout(val); 127 | } 128 | //! [2] 129 | //! [3] 130 | void Dialog::onOpenCloseButtonClicked() 131 | { 132 | if (!port->isOpen()) { 133 | port->setPortName(ui->portBox->currentText()); 134 | port->open(QIODevice::ReadWrite); 135 | } 136 | else { 137 | port->close(); 138 | } 139 | 140 | //If using polling mode, we need a QTimer 141 | if (port->isOpen() && port->queryMode() == QextSerialPort::Polling) 142 | timer->start(); 143 | else 144 | timer->stop(); 145 | 146 | //update led's status 147 | ui->led->turnOn(port->isOpen()); 148 | } 149 | //! [3] 150 | //! [4] 151 | void Dialog::onSendButtonClicked() 152 | { 153 | if (port->isOpen() && !ui->sendEdit->toPlainText().isEmpty()) 154 | port->write(ui->sendEdit->toPlainText().toLatin1()); 155 | } 156 | 157 | void Dialog::onReadyRead() 158 | { 159 | if (port->bytesAvailable()) { 160 | ui->recvEdit->moveCursor(QTextCursor::End); 161 | ui->recvEdit->insertPlainText(QString::fromLatin1(port->readAll())); 162 | } 163 | } 164 | 165 | void Dialog::onPortAddedOrRemoved() 166 | { 167 | QString current = ui->portBox->currentText(); 168 | 169 | ui->portBox->blockSignals(true); 170 | ui->portBox->clear(); 171 | foreach (QextPortInfo info, QextSerialEnumerator::getPorts()) 172 | ui->portBox->addItem(info.portName); 173 | 174 | ui->portBox->setCurrentIndex(ui->portBox->findText(current)); 175 | 176 | ui->portBox->blockSignals(false); 177 | } 178 | 179 | //! [4] 180 | -------------------------------------------------------------------------------- /qextserialport/examples/uartassistant/dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 604 10 | 485 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 800 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Port: 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | BaudRate: 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | DataBits: 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Parity: 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | StopBits: 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | QueryMode: 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Timeout: 99 | 100 | 101 | 102 | 103 | 104 | 105 | ms 106 | 107 | 108 | -1 109 | 110 | 111 | 10000 112 | 113 | 114 | 10 115 | 116 | 117 | 10 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 0 130 | 0 131 | 132 | 133 | 134 | 135 | 20 136 | 20 137 | 138 | 139 | 140 | 141 | 25 142 | 25 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | Open/Close 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Qt::Vertical 160 | 161 | 162 | 163 | 20 164 | 40 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | Send 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | HLed 184 | QWidget 185 |
hled.h
186 | 1 187 |
188 |
189 | 190 | 191 |
192 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialenumerator.h" 33 | #include "qextserialenumerator_p.h" 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | QextSerialEnumeratorPrivate::QextSerialEnumeratorPrivate(QextSerialEnumerator *enumrator) 40 | :q_ptr(enumrator) 41 | { 42 | platformSpecificInit(); 43 | } 44 | 45 | QextSerialEnumeratorPrivate::~QextSerialEnumeratorPrivate() 46 | { 47 | platformSpecificDestruct(); 48 | } 49 | 50 | /*! 51 | \class QextPortInfo 52 | 53 | \brief The QextPortInfo class containing port information. 54 | 55 | Structure containing port information. 56 | 57 | \code 58 | QString portName; ///< Port name. 59 | QString physName; ///< Physical name. 60 | QString friendName; ///< Friendly name. 61 | QString enumName; ///< Enumerator name. 62 | int vendorID; ///< Vendor ID. 63 | int productID; ///< Product ID 64 | \endcode 65 | */ 66 | 67 | /*! \class QextSerialEnumerator 68 | 69 | \brief The QextSerialEnumerator class provides list of ports available in the system. 70 | 71 | \section1 Usage 72 | To poll the system for a list of connected devices, simply use getPorts(). Each 73 | QextPortInfo structure will populated with information about the corresponding device. 74 | 75 | \bold Example 76 | \code 77 | QList ports = QextSerialEnumerator::getPorts(); 78 | foreach (QextPortInfo port, ports) { 79 | // inspect port... 80 | } 81 | \endcode 82 | 83 | To enable event-driven notification of device connection events, first call 84 | setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved() 85 | signals. Event-driven behavior is currently available only on Windows and OS X. 86 | 87 | \bold Example 88 | \code 89 | QextSerialEnumerator *enumerator = new QextSerialEnumerator(); 90 | connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)), 91 | myClass, SLOT(onDeviceDiscovered(const QextPortInfo &))); 92 | connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)), 93 | myClass, SLOT(onDeviceRemoved(const QextPortInfo &))); 94 | \endcode 95 | 96 | \section1 Credits 97 | Windows implementation is based on Zach Gorman's work from 98 | \l {http://www.codeproject.com}{The Code Project} (\l http://www.codeproject.com/system/setupdi.asp). 99 | 100 | OS X implementation, see \l http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html 101 | 102 | \bold author Michal Policht, Liam Staskawicz 103 | */ 104 | 105 | /*! 106 | \fn void QextSerialEnumerator::deviceDiscovered(const QextPortInfo &info) 107 | A new device has been connected to the system. 108 | 109 | setUpNotifications() must be called first to enable event-driven device notifications. 110 | Currently only implemented on Windows and OS X. 111 | 112 | \a info The device that has been discovered. 113 | */ 114 | 115 | /*! 116 | \fn void QextSerialEnumerator::deviceRemoved(const QextPortInfo &info); 117 | A device has been disconnected from the system. 118 | 119 | setUpNotifications() must be called first to enable event-driven device notifications. 120 | Currently only implemented on Windows and OS X. 121 | 122 | \a info The device that was disconnected. 123 | */ 124 | 125 | /*! 126 | Constructs a QextSerialEnumerator object with the given \a parent. 127 | */ 128 | QextSerialEnumerator::QextSerialEnumerator(QObject *parent) 129 | :QObject(parent), d_ptr(new QextSerialEnumeratorPrivate(this)) 130 | { 131 | if (!QMetaType::isRegistered(QMetaType::type("QextPortInfo"))) 132 | qRegisterMetaType("QextPortInfo"); 133 | } 134 | 135 | /*! 136 | Destructs the QextSerialEnumerator object. 137 | */ 138 | QextSerialEnumerator::~QextSerialEnumerator() 139 | { 140 | delete d_ptr; 141 | } 142 | 143 | /*! 144 | Get list of ports. 145 | 146 | return list of ports currently available in the system. 147 | */ 148 | QList QextSerialEnumerator::getPorts() 149 | { 150 | return QextSerialEnumeratorPrivate::getPorts_sys(); 151 | } 152 | 153 | /*! 154 | Enable event-driven notifications of board discovery/removal. 155 | */ 156 | void QextSerialEnumerator::setUpNotifications() 157 | { 158 | Q_D(QextSerialEnumerator); 159 | if (!d->setUpNotifications_sys(true)) 160 | QESP_WARNING("Setup Notification Failed..."); 161 | } 162 | 163 | #include "moc_qextserialenumerator.cpp" 164 | -------------------------------------------------------------------------------- /qextserialport/doc/index.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \page index.html 3 | \title QextSerialPort Manual 4 | 5 | \section1 Overview 6 | QextSerialPort provides an interface to old fashioned serial ports for 7 | Qt-based applications. It currently supports Mac OS X, Windows, Linux, FreeBSD. 8 | 9 | From QextSerialPort 1.2-beta on, license of the project has been changed to MIT. 10 | 11 | \list 12 | \o Revision 0.9.x is Qt 2 & 3 compatible. 13 | \o Revision 1.x.x is Qt 4 compatible. 14 | \o From revision 1.2beta1 on, Qt 5 support is added. 15 | \endlist 16 | 17 | 18 | \section1 Classes 19 | \list 20 | \o \l QextSerialPort encapsulates a serial port on both POSIX and Windows systems. 21 | \o \l QextSerialEnumerator enumerates ports currently available in the system. 22 | \endlist 23 | 24 | \section1 Getting Started 25 | 26 | 27 | \section2 Usage(1): Source Code Only 28 | 29 | The package contains a qextserialport.pri file that allows you to integrate the component into programs that use qmake for the build step. 30 | 31 | Download the source code. 32 | Put the source code in any directory you like. For example, 3rdparty: 33 | 34 | \code 35 | |-- project.pro 36 | |-- .... 37 | |-- 3rdparty\ 38 | | |-- qextserialport\ 39 | | | 40 | \endcode 41 | 42 | Add following line to your qmake project file: 43 | \code 44 | include(pathToPri/qextserialport.pri) 45 | \endcode 46 | 47 | Then, using QextSerialPort in your code 48 | \code 49 | #include "qextserialport.h" 50 | ... 51 | MyClass::MyClass() 52 | { 53 | port = new QextSerialPort("COM1"); 54 | connect(port, SIGNAL(readyRead()), this, SLOT(onDataAvailable())); 55 | port->open(); 56 | } 57 | 58 | void MyClass::onDataAvailable() 59 | { 60 | QByteArray data = port->readAll(); 61 | processNewData(usbdata); 62 | } 63 | \endcode 64 | 65 | \section2 Usage(2): shared library 66 | Although QextSerialPort can be directly compiled into your application, You may prefer 67 | to use QextSerailPort as an library, which is very easy too. 68 | 69 | 1. Download the source code, and put it in any location you like. 70 | 71 | 2. Goto the top level directory ,run following command to generate library. 72 | 73 | \code 74 | qmake 75 | sudo make install (or nmake install) 76 | \endcode 77 | 78 | 3. Add following line to your project's file 79 | 80 | \code 81 | CONFIG += extserialport 82 | \endcode 83 | 84 | 4. Using QextSerialPort in your code. Enjoy it! 85 | 86 | \code 87 | #include "qextserialport.h" 88 | .... 89 | QextSerialPort * port = new QextSerialPort(); 90 | .... 91 | \endcode 92 | 93 | \section2 Usage(3): Static library 94 | 95 | Someone prefer to use QextSerailPort as static library. 96 | 97 | Open the project file: qextserialport.pro, add uncomment follow line 98 | 99 | \code 100 | # CONFIG += qesp_static 101 | \endcode 102 | 103 | Then follow the same steps as shared library 104 | 105 | \code 106 | qmake 107 | sudo make install 108 | \endcode 109 | 110 | The static library, the header files, and the feature file will be installed to your system. 111 | 112 | Add following line to your qmake's project file: 113 | 114 | \code 115 | CONFIG += extserialport 116 | \endcode 117 | 118 | \section1 Platform Special 119 | 120 | \section2 For MacX: Build as framework 121 | 122 | Open the project file: *qextserialport.pro*, and uncomment follow line 123 | 124 | \code 125 | # CONFIG += qesp_mac_framework 126 | \endcode 127 | 128 | Then follow the same steps as shared library, Goto the top level directory , and run 129 | 130 | \code 131 | qmake 132 | sudo make install 133 | \endcode 134 | 135 | The framework which includes libraries and the header files, and the feature file will be installed to your system. 136 | 137 | Add following line to your qmake's project file: 138 | 139 | \code 140 | CONFIG += extserialport 141 | \endcode 142 | 143 | \section2 For Linux: Enable udev 144 | 145 | Open the project file: *qextserialport.pro*, uncomment follow line 146 | 147 | \code 148 | #linux*:CONFIG += qesp_linux_udev 149 | \endcode 150 | 151 | Note, If you are using the usage(1), Add following line before include the qextserialport.pri file. 152 | \code 153 | CONFIG += qesp_linux_udev 154 | \endcode 155 | 156 | 157 | \section2 Build documents 158 | \code 159 | make docs 160 | \endcode 161 | 162 | \section1 Examples 163 | \list 164 | \o \l examples/enumerator 165 | \o \l examples/qespta 166 | \o \l examples/uartassistant 167 | \endlist 168 | 169 | \section1 Resources 170 | \section2 Nokia(Trolltech) 171 | \list 172 | \o \l {http://doc.trolltech.com/qq/qq12-iodevice.html} {Writing a Custom I/O Device} 173 | \o \l {http://doc.trolltech.com/3.3/qiodevice.html} {Qt 3.3: QIODevice Class Reference} 174 | \o \l {http://doc.trolltech.com/4.7/qiodevice.html} {Qt 4.7: QIODevice Class Reference} 175 | \endlist 176 | \section2 MSDN 177 | \list 178 | \o \l {http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_resources.asp} {Communications Resources} 179 | \o \l {http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/about_communications_resources.asp} {About Communications Resources} 180 | \o \l {http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/using_communications_resources.asp}{Using Communications Resources} 181 | \o \l {http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_functions.asp} {Communications Functions} 182 | \o \l {http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_structures.asp} {Communications Structures} 183 | \endlist 184 | \section2 TLDP 185 | \list 186 | \o \l {http://www.tldp.org/HOWTO/Serial-HOWTO.html}{Serial HOWTO} 187 | \o \l {http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/}{Serial Programming HOWTO} 188 | \endlist 189 | \section2 Other 190 | \list 191 | \o \l {http://www.easysw.com/~mike/serial/serial.html} {Serial Programming Guide for POSIX Operating Systems} 192 | \endlist 193 | 194 | */ 195 | 196 | /*! 197 | \page classes.html 198 | \generatelist annotatedclasses 199 | */ 200 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Makefile for building: main 3 | # Generated by qmake (2.01a) (Qt 4.8.5) on: Thu Feb 5 22:19:05 2015 4 | # Project: main.pro 5 | # Template: app 6 | # Command: /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/bin/qmake -o Makefile main.pro 7 | ############################################################################# 8 | 9 | first: release 10 | install: release-install 11 | uninstall: release-uninstall 12 | MAKEFILE = Makefile 13 | QMAKE = /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/bin/qmake 14 | DEL_FILE = rm 15 | CHK_DIR_EXISTS= test -d 16 | MKDIR = mkdir -p 17 | COPY = cp 18 | COPY_FILE = $(COPY) 19 | COPY_DIR = cp -r 20 | INSTALL_FILE = $(COPY_FILE) 21 | INSTALL_PROGRAM = $(COPY_FILE) 22 | INSTALL_DIR = $(COPY_DIR) 23 | DEL_FILE = rm 24 | SYMLINK = 25 | DEL_DIR = rmdir 26 | MOVE = mv 27 | CHK_DIR_EXISTS= test -d 28 | MKDIR = mkdir -p 29 | SUBTARGETS = \ 30 | release \ 31 | debug 32 | 33 | release: $(MAKEFILE).Release FORCE 34 | $(MAKE) -f $(MAKEFILE).Release 35 | release-make_default: $(MAKEFILE).Release FORCE 36 | $(MAKE) -f $(MAKEFILE).Release 37 | release-make_first: $(MAKEFILE).Release FORCE 38 | $(MAKE) -f $(MAKEFILE).Release first 39 | release-all: $(MAKEFILE).Release FORCE 40 | $(MAKE) -f $(MAKEFILE).Release all 41 | release-clean: $(MAKEFILE).Release FORCE 42 | $(MAKE) -f $(MAKEFILE).Release clean 43 | release-distclean: $(MAKEFILE).Release FORCE 44 | $(MAKE) -f $(MAKEFILE).Release distclean 45 | release-install: $(MAKEFILE).Release FORCE 46 | $(MAKE) -f $(MAKEFILE).Release install 47 | release-uninstall: $(MAKEFILE).Release FORCE 48 | $(MAKE) -f $(MAKEFILE).Release uninstall 49 | debug: $(MAKEFILE).Debug FORCE 50 | $(MAKE) -f $(MAKEFILE).Debug 51 | debug-make_default: $(MAKEFILE).Debug FORCE 52 | $(MAKE) -f $(MAKEFILE).Debug 53 | debug-make_first: $(MAKEFILE).Debug FORCE 54 | $(MAKE) -f $(MAKEFILE).Debug first 55 | debug-all: $(MAKEFILE).Debug FORCE 56 | $(MAKE) -f $(MAKEFILE).Debug all 57 | debug-clean: $(MAKEFILE).Debug FORCE 58 | $(MAKE) -f $(MAKEFILE).Debug clean 59 | debug-distclean: $(MAKEFILE).Debug FORCE 60 | $(MAKE) -f $(MAKEFILE).Debug distclean 61 | debug-install: $(MAKEFILE).Debug FORCE 62 | $(MAKE) -f $(MAKEFILE).Debug install 63 | debug-uninstall: $(MAKEFILE).Debug FORCE 64 | $(MAKE) -f $(MAKEFILE).Debug uninstall 65 | 66 | Makefile: main.pro ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/win32-g++-4.6/qmake.conf ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/qdevice.pri \ 67 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/device_config.prf \ 68 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/qconfig.pri \ 69 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt_functions.prf \ 70 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt_config.prf \ 71 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/win32-g++/qmake.conf \ 72 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/exclusive_builds.prf \ 73 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/default_pre.prf \ 74 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/default_pre.prf \ 75 | qextserialport/src/qextserialport.pri \ 76 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/release.prf \ 77 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/debug_and_release.prf \ 78 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/default_post.prf \ 79 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/default_post.prf \ 80 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/stl.prf \ 81 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/rtti.prf \ 82 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/exceptions.prf \ 83 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/static.prf \ 84 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/warn_on.prf \ 85 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt.prf \ 86 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/thread.prf \ 87 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/moc.prf \ 88 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/windows.prf \ 89 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/resources.prf \ 90 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/uic.prf \ 91 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/yacc.prf \ 92 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/lex.prf \ 93 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/include_source_dir.prf \ 94 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/qtmain.prl \ 95 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/QtGui.prl \ 96 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/QtCore.prl 97 | $(QMAKE) -o Makefile main.pro 98 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/qdevice.pri: 99 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/device_config.prf: 100 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/qconfig.pri: 101 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt_functions.prf: 102 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt_config.prf: 103 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/win32-g++/qmake.conf: 104 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/exclusive_builds.prf: 105 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/default_pre.prf: 106 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/default_pre.prf: 107 | qextserialport/src/qextserialport.pri: 108 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/release.prf: 109 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/debug_and_release.prf: 110 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/default_post.prf: 111 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/default_post.prf: 112 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/stl.prf: 113 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/rtti.prf: 114 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/exceptions.prf: 115 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/static.prf: 116 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/warn_on.prf: 117 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/qt.prf: 118 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/thread.prf: 119 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/moc.prf: 120 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/win32/windows.prf: 121 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/resources.prf: 122 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/uic.prf: 123 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/yacc.prf: 124 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/lex.prf: 125 | ../../../mxe/usr/i686-pc-mingw32/qt/mkspecs/features/include_source_dir.prf: 126 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/qtmain.prl: 127 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/QtGui.prl: 128 | /home/cetec/Projects/mxe/usr/i686-pc-mingw32/qt/lib/QtCore.prl: 129 | qmake: qmake_all FORCE 130 | @$(QMAKE) -o Makefile main.pro 131 | 132 | qmake_all: FORCE 133 | 134 | make_default: release-make_default debug-make_default FORCE 135 | make_first: release-make_first debug-make_first FORCE 136 | all: release-all debug-all FORCE 137 | clean: release-clean debug-clean FORCE 138 | distclean: release-distclean debug-distclean FORCE 139 | -$(DEL_FILE) Makefile 140 | 141 | check: first 142 | 143 | release-mocclean: $(MAKEFILE).Release 144 | $(MAKE) -f $(MAKEFILE).Release mocclean 145 | debug-mocclean: $(MAKEFILE).Debug 146 | $(MAKE) -f $(MAKEFILE).Debug mocclean 147 | mocclean: release-mocclean debug-mocclean 148 | 149 | release-mocables: $(MAKEFILE).Release 150 | $(MAKE) -f $(MAKEFILE).Release mocables 151 | debug-mocables: $(MAKEFILE).Debug 152 | $(MAKE) -f $(MAKEFILE).Debug mocables 153 | mocables: release-mocables debug-mocables 154 | FORCE: 155 | 156 | $(MAKEFILE).Release: Makefile 157 | $(MAKEFILE).Debug: Makefile 158 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator_linux.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** Copyright (c) 2012 Doug Brown 9 | ** All right reserved. 10 | ** Web: http://code.google.com/p/qextserialport/ 11 | ** 12 | ** Permission is hereby granted, free of charge, to any person obtaining 13 | ** a copy of this software and associated documentation files (the 14 | ** "Software"), to deal in the Software without restriction, including 15 | ** without limitation the rights to use, copy, modify, merge, publish, 16 | ** distribute, sublicense, and/or sell copies of the Software, and to 17 | ** permit persons to whom the Software is furnished to do so, subject to 18 | ** the following conditions: 19 | ** 20 | ** The above copyright notice and this permission notice shall be 21 | ** included in all copies or substantial portions of the Software. 22 | ** 23 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | ** 31 | ****************************************************************************/ 32 | 33 | #include "qextserialenumerator.h" 34 | #include "qextserialenumerator_p.h" 35 | #include 36 | #include 37 | #include 38 | 39 | void QextSerialEnumeratorPrivate::platformSpecificInit() 40 | { 41 | #ifndef QESP_NO_UDEV 42 | monitor = NULL; 43 | notifierFd = -1; 44 | notifier = NULL; 45 | 46 | udev = udev_new(); 47 | if (!udev) 48 | qCritical() << "Unable to initialize udev notifications"; 49 | #endif 50 | } 51 | 52 | void QextSerialEnumeratorPrivate::platformSpecificDestruct() 53 | { 54 | #ifndef QESP_NO_UDEV 55 | if (notifier) { 56 | notifier->setEnabled(false); 57 | delete notifier; 58 | } 59 | 60 | if (monitor) 61 | udev_monitor_unref(monitor); 62 | 63 | if (udev) 64 | udev_unref(udev); 65 | #endif 66 | } 67 | 68 | #ifndef QESP_NO_UDEV 69 | static QextPortInfo portInfoFromDevice(struct udev_device *dev) 70 | { 71 | QString vendor = QString::fromLatin1(udev_device_get_property_value(dev, "ID_VENDOR_ID")); 72 | QString product = QString::fromLatin1(udev_device_get_property_value(dev, "ID_MODEL_ID")); 73 | 74 | QextPortInfo pi; 75 | pi.vendorID = vendor.toInt(0, 16); 76 | pi.productID = product.toInt(0, 16); 77 | pi.portName = QString::fromLatin1(udev_device_get_devnode(dev)); 78 | pi.physName = pi.portName; 79 | 80 | return pi; 81 | } 82 | #endif 83 | 84 | QList QextSerialEnumeratorPrivate::getPorts_sys() 85 | { 86 | QList infoList; 87 | #ifndef QESP_NO_UDEV 88 | struct udev *ud = udev_new(); 89 | if (!ud) { 90 | qCritical() << "Unable to enumerate ports because udev is not initialized."; 91 | return infoList; 92 | } 93 | 94 | struct udev_enumerate *enumerate = udev_enumerate_new(ud); 95 | udev_enumerate_add_match_subsystem(enumerate, "tty"); 96 | udev_enumerate_scan_devices(enumerate); 97 | struct udev_list_entry *list = udev_enumerate_get_list_entry(enumerate); 98 | struct udev_list_entry *entry; 99 | udev_list_entry_foreach(entry, list) { 100 | const char *path; 101 | struct udev_device *dev; 102 | 103 | // Have to grab the actual udev device here... 104 | path = udev_list_entry_get_name(entry); 105 | dev = udev_device_new_from_syspath(ud, path); 106 | 107 | infoList.append(portInfoFromDevice(dev)); 108 | 109 | // Done with this device 110 | udev_device_unref(dev); 111 | } 112 | // Done with the list and this udev 113 | udev_enumerate_unref(enumerate); 114 | udev_unref(ud); 115 | #else 116 | QStringList portNamePrefixes, portNameList; 117 | portNamePrefixes << QLatin1String("ttyS*"); // list normal serial ports first 118 | 119 | QDir dir(QLatin1String("/dev")); 120 | portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); 121 | 122 | // remove the values which are not serial ports for e.g. /dev/ttysa 123 | for (int i = 0; i < portNameList.size(); i++) { 124 | bool ok; 125 | QString current = portNameList.at(i); 126 | // remove the ttyS part, and check, if the other part is a number 127 | current.remove(0,4).toInt(&ok, 10); 128 | if (!ok) { 129 | portNameList.removeAt(i); 130 | i--; 131 | } 132 | } 133 | 134 | // get the non standard serial ports names 135 | // (USB-serial, bluetooth-serial, 18F PICs, and so on) 136 | // if you know an other name prefix for serial ports please let us know 137 | portNamePrefixes.clear(); 138 | portNamePrefixes << QLatin1String("ttyACM*") << QLatin1String("ttyUSB*") << QLatin1String("rfcomm*"); 139 | portNameList += dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); 140 | 141 | foreach (QString str , portNameList) { 142 | QextPortInfo inf; 143 | inf.physName = QLatin1String("/dev/")+str; 144 | inf.portName = str; 145 | 146 | if (str.contains(QLatin1String("ttyS"))) { 147 | inf.friendName = QLatin1String("Serial port ")+str.remove(0, 4); 148 | } 149 | else if (str.contains(QLatin1String("ttyUSB"))) { 150 | inf.friendName = QLatin1String("USB-serial adapter ")+str.remove(0, 6); 151 | } 152 | else if (str.contains(QLatin1String("rfcomm"))) { 153 | inf.friendName = QLatin1String("Bluetooth-serial adapter ")+str.remove(0, 6); 154 | } 155 | inf.enumName = QLatin1String("/dev"); // is there a more helpful name for this? 156 | infoList.append(inf); 157 | } 158 | #endif 159 | 160 | return infoList; 161 | } 162 | 163 | bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool setup) 164 | { 165 | Q_UNUSED(setup); 166 | #ifndef QESP_NO_UDEV 167 | Q_Q(QextSerialEnumerator); 168 | if (!udev) { 169 | qCritical() << "Unable to initialize notifications because udev is not initialized."; 170 | return false; 171 | } 172 | 173 | // Emit signals immediately for devices already connected (Windows version seems to behave 174 | // this way) 175 | foreach (QextPortInfo i, getPorts_sys()) 176 | Q_EMIT q->deviceDiscovered(i); 177 | 178 | // Look for tty devices from udev. 179 | monitor = udev_monitor_new_from_netlink(udev, "udev"); 180 | udev_monitor_filter_add_match_subsystem_devtype(monitor, "tty", NULL); 181 | udev_monitor_enable_receiving(monitor); 182 | notifierFd = udev_monitor_get_fd(monitor); 183 | notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read); 184 | q->connect(notifier, SIGNAL(activated(int)), q, SLOT(_q_deviceEvent())); 185 | notifier->setEnabled(true); 186 | 187 | return true; 188 | #else 189 | return false; 190 | #endif 191 | } 192 | 193 | #ifndef QESP_NO_UDEV 194 | void QextSerialEnumeratorPrivate::_q_deviceEvent() 195 | { 196 | Q_Q(QextSerialEnumerator); 197 | struct udev_device *dev = udev_monitor_receive_device(monitor); 198 | if (dev) { 199 | QextPortInfo pi = portInfoFromDevice(dev); 200 | 201 | QLatin1String action(udev_device_get_action(dev)); 202 | udev_device_unref(dev); 203 | 204 | if (action == QLatin1String("add")) 205 | Q_EMIT q->deviceDiscovered(pi); 206 | else if (action == QLatin1String("remove")) 207 | Q_EMIT q->deviceRemoved(pi); 208 | } 209 | } 210 | #endif 211 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #ifndef _QEXTSERIALPORT_H_ 33 | #define _QEXTSERIALPORT_H_ 34 | 35 | #include 36 | #include "qextserialport_global.h" 37 | #ifdef Q_OS_UNIX 38 | #include 39 | #endif 40 | /*line status constants*/ 41 | // ### QESP2.0 move to enum 42 | #define LS_CTS 0x01 43 | #define LS_DSR 0x02 44 | #define LS_DCD 0x04 45 | #define LS_RI 0x08 46 | #define LS_RTS 0x10 47 | #define LS_DTR 0x20 48 | #define LS_ST 0x40 49 | #define LS_SR 0x80 50 | 51 | /*error constants*/ 52 | // ### QESP2.0 move to enum 53 | #define E_NO_ERROR 0 54 | #define E_INVALID_FD 1 55 | #define E_NO_MEMORY 2 56 | #define E_CAUGHT_NON_BLOCKED_SIGNAL 3 57 | #define E_PORT_TIMEOUT 4 58 | #define E_INVALID_DEVICE 5 59 | #define E_BREAK_CONDITION 6 60 | #define E_FRAMING_ERROR 7 61 | #define E_IO_ERROR 8 62 | #define E_BUFFER_OVERRUN 9 63 | #define E_RECEIVE_OVERFLOW 10 64 | #define E_RECEIVE_PARITY_ERROR 11 65 | #define E_TRANSMIT_OVERFLOW 12 66 | #define E_READ_FAILED 13 67 | #define E_WRITE_FAILED 14 68 | #define E_FILE_NOT_FOUND 15 69 | #define E_PERMISSION_DENIED 16 70 | #define E_AGAIN 17 71 | 72 | enum BaudRateType 73 | { 74 | #if defined(Q_OS_UNIX) || defined(qdoc) 75 | BAUD50 = 50, //POSIX ONLY 76 | BAUD75 = 75, //POSIX ONLY 77 | BAUD134 = 134, //POSIX ONLY 78 | BAUD150 = 150, //POSIX ONLY 79 | BAUD200 = 200, //POSIX ONLY 80 | BAUD1800 = 1800, //POSIX ONLY 81 | # if defined(B76800) || defined(qdoc) 82 | BAUD76800 = 76800, //POSIX ONLY 83 | # endif 84 | # if (defined(B230400) && defined(B4000000)) || defined(qdoc) 85 | BAUD230400 = 230400, //POSIX ONLY 86 | BAUD460800 = 460800, //POSIX ONLY 87 | BAUD500000 = 500000, //POSIX ONLY 88 | BAUD576000 = 576000, //POSIX ONLY 89 | BAUD921600 = 921600, //POSIX ONLY 90 | BAUD1000000 = 1000000, //POSIX ONLY 91 | BAUD1152000 = 1152000, //POSIX ONLY 92 | BAUD1500000 = 1500000, //POSIX ONLY 93 | BAUD2000000 = 2000000, //POSIX ONLY 94 | BAUD2500000 = 2500000, //POSIX ONLY 95 | BAUD3000000 = 3000000, //POSIX ONLY 96 | BAUD3500000 = 3500000, //POSIX ONLY 97 | BAUD4000000 = 4000000, //POSIX ONLY 98 | # endif 99 | #endif //Q_OS_UNIX 100 | #if defined(Q_OS_WIN) || defined(qdoc) 101 | BAUD14400 = 14400, //WINDOWS ONLY 102 | BAUD56000 = 56000, //WINDOWS ONLY 103 | BAUD128000 = 128000, //WINDOWS ONLY 104 | BAUD256000 = 256000, //WINDOWS ONLY 105 | #endif //Q_OS_WIN 106 | BAUD110 = 110, 107 | BAUD300 = 300, 108 | BAUD600 = 600, 109 | BAUD1200 = 1200, 110 | BAUD2400 = 2400, 111 | BAUD4800 = 4800, 112 | BAUD9600 = 9600, 113 | BAUD19200 = 19200, 114 | BAUD38400 = 38400, 115 | BAUD57600 = 57600, 116 | BAUD115200 = 115200 117 | }; 118 | 119 | enum DataBitsType 120 | { 121 | DATA_5 = 5, 122 | DATA_6 = 6, 123 | DATA_7 = 7, 124 | DATA_8 = 8 125 | }; 126 | 127 | enum ParityType 128 | { 129 | PAR_NONE, 130 | PAR_ODD, 131 | PAR_EVEN, 132 | #if defined(Q_OS_WIN) || defined(qdoc) 133 | PAR_MARK, //WINDOWS ONLY 134 | #endif 135 | PAR_SPACE 136 | }; 137 | 138 | enum StopBitsType 139 | { 140 | STOP_1, 141 | #if defined(Q_OS_WIN) || defined(qdoc) 142 | STOP_1_5, //WINDOWS ONLY 143 | #endif 144 | STOP_2 145 | }; 146 | 147 | enum FlowType 148 | { 149 | FLOW_OFF, 150 | FLOW_HARDWARE, 151 | FLOW_XONXOFF 152 | }; 153 | 154 | /** 155 | * structure to contain port settings 156 | */ 157 | struct PortSettings 158 | { 159 | BaudRateType BaudRate; 160 | DataBitsType DataBits; 161 | ParityType Parity; 162 | StopBitsType StopBits; 163 | FlowType FlowControl; 164 | long Timeout_Millisec; 165 | }; 166 | 167 | class QextSerialPortPrivate; 168 | class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice 169 | { 170 | Q_OBJECT 171 | Q_DECLARE_PRIVATE(QextSerialPort) 172 | Q_ENUMS(QueryMode) 173 | Q_PROPERTY(QString portName READ portName WRITE setPortName) 174 | Q_PROPERTY(QueryMode queryMode READ queryMode WRITE setQueryMode) 175 | public: 176 | enum QueryMode { 177 | Polling, 178 | EventDriven 179 | }; 180 | 181 | explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0); 182 | explicit QextSerialPort(const QString &name, QueryMode mode = EventDriven, QObject *parent = 0); 183 | explicit QextSerialPort(const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0); 184 | QextSerialPort(const QString &name, const PortSettings &s, QueryMode mode = EventDriven, QObject *parent=0); 185 | 186 | ~QextSerialPort(); 187 | 188 | QString portName() const; 189 | QueryMode queryMode() const; 190 | BaudRateType baudRate() const; 191 | DataBitsType dataBits() const; 192 | ParityType parity() const; 193 | StopBitsType stopBits() const; 194 | FlowType flowControl() const; 195 | 196 | bool open(OpenMode mode); 197 | bool isSequential() const; 198 | void close(); 199 | void flush(); 200 | qint64 bytesAvailable() const; 201 | bool canReadLine() const; 202 | QByteArray readAll(); 203 | 204 | ulong lastError() const; 205 | 206 | ulong lineStatus(); 207 | QString errorString(); 208 | 209 | public Q_SLOTS: 210 | void setPortName(const QString &name); 211 | void setQueryMode(QueryMode mode); 212 | void setBaudRate(BaudRateType); 213 | void setDataBits(DataBitsType); 214 | void setParity(ParityType); 215 | void setStopBits(StopBitsType); 216 | void setFlowControl(FlowType); 217 | void setTimeout(long); 218 | 219 | void setDtr(bool set=true); 220 | void setRts(bool set=true); 221 | 222 | Q_SIGNALS: 223 | void dsrChanged(bool status); 224 | 225 | protected: 226 | qint64 readData(char *data, qint64 maxSize); 227 | qint64 writeData(const char *data, qint64 maxSize); 228 | 229 | private: 230 | Q_DISABLE_COPY(QextSerialPort) 231 | 232 | #ifdef Q_OS_WIN 233 | Q_PRIVATE_SLOT(d_func(), void _q_onWinEvent(HANDLE)) 234 | #endif 235 | Q_PRIVATE_SLOT(d_func(), void _q_canRead()) 236 | 237 | QextSerialPortPrivate *const d_ptr; 238 | }; 239 | 240 | #endif 241 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport_p.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #ifndef _QEXTSERIALPORT_P_H_ 33 | #define _QEXTSERIALPORT_P_H_ 34 | 35 | // 36 | // W A R N I N G 37 | // ------------- 38 | // 39 | // This file is not part of the QESP API. It exists for the convenience 40 | // of other QESP classes. This header file may change from version to 41 | // version without notice, or even be removed. 42 | // 43 | // We mean it. 44 | // 45 | 46 | #include "qextserialport.h" 47 | #include 48 | #ifdef Q_OS_UNIX 49 | # include 50 | #elif (defined Q_OS_WIN) 51 | # include 52 | #endif 53 | #include 54 | 55 | // This is QextSerialPort's read buffer, needed by posix system. 56 | // ref: QRingBuffer & QIODevicePrivateLinearBuffer 57 | class QextReadBuffer 58 | { 59 | public: 60 | inline QextReadBuffer(size_t growth=4096) 61 | : len(0), first(0), buf(0), capacity(0), basicBlockSize(growth) { 62 | } 63 | 64 | ~QextReadBuffer() { 65 | delete [] buf; 66 | } 67 | 68 | inline void clear() { 69 | first = buf; 70 | len = 0; 71 | } 72 | 73 | inline int size() const { 74 | return len; 75 | } 76 | 77 | inline bool isEmpty() const { 78 | return len == 0; 79 | } 80 | 81 | inline int read(char *target, int size) { 82 | int r = qMin(size, len); 83 | if (r == 1) { 84 | *target = *first; 85 | --len; 86 | ++first; 87 | } else { 88 | memcpy(target, first, r); 89 | len -= r; 90 | first += r; 91 | } 92 | return r; 93 | } 94 | 95 | inline char *reserve(size_t size) { 96 | if ((first - buf) + len + size > capacity) { 97 | size_t newCapacity = qMax(capacity, basicBlockSize); 98 | while (newCapacity < len + size) 99 | newCapacity *= 2; 100 | if (newCapacity > capacity) { 101 | // allocate more space 102 | char *newBuf = new char[newCapacity]; 103 | memmove(newBuf, first, len); 104 | delete [] buf; 105 | buf = newBuf; 106 | capacity = newCapacity; 107 | } else { 108 | // shift any existing data to make space 109 | memmove(buf, first, len); 110 | } 111 | first = buf; 112 | } 113 | char *writePtr = first + len; 114 | len += (int)size; 115 | return writePtr; 116 | } 117 | 118 | inline void chop(int size) { 119 | if (size >= len) { 120 | clear(); 121 | } else { 122 | len -= size; 123 | } 124 | } 125 | 126 | inline void squeeze() { 127 | if (first != buf) { 128 | memmove(buf, first, len); 129 | first = buf; 130 | } 131 | size_t newCapacity = basicBlockSize; 132 | while (newCapacity < size_t(len)) 133 | newCapacity *= 2; 134 | if (newCapacity < capacity) { 135 | char *tmp = static_cast(realloc(buf, newCapacity)); 136 | if (tmp) { 137 | buf = tmp; 138 | capacity = newCapacity; 139 | } 140 | } 141 | } 142 | 143 | inline QByteArray readAll() { 144 | char *f = first; 145 | int l = len; 146 | clear(); 147 | return QByteArray(f, l); 148 | } 149 | 150 | inline int readLine(char *target, int size) { 151 | int r = qMin(size, len); 152 | char *eol = static_cast(memchr(first, '\n', r)); 153 | if (eol) 154 | r = 1+(eol-first); 155 | memcpy(target, first, r); 156 | len -= r; 157 | first += r; 158 | return int(r); 159 | } 160 | 161 | inline bool canReadLine() const { 162 | return memchr(first, '\n', len); 163 | } 164 | 165 | private: 166 | int len; 167 | char *first; 168 | char *buf; 169 | size_t capacity; 170 | size_t basicBlockSize; 171 | }; 172 | 173 | class QWinEventNotifier; 174 | class QReadWriteLock; 175 | class QSocketNotifier; 176 | 177 | class QextSerialPortPrivate 178 | { 179 | Q_DECLARE_PUBLIC(QextSerialPort) 180 | public: 181 | QextSerialPortPrivate(QextSerialPort *q); 182 | ~QextSerialPortPrivate(); 183 | enum DirtyFlagEnum 184 | { 185 | DFE_BaudRate = 0x0001, 186 | DFE_Parity = 0x0002, 187 | DFE_StopBits = 0x0004, 188 | DFE_DataBits = 0x0008, 189 | DFE_Flow = 0x0010, 190 | DFE_TimeOut = 0x0100, 191 | DFE_ALL = 0x0fff, 192 | DFE_Settings_Mask = 0x00ff //without TimeOut 193 | }; 194 | mutable QReadWriteLock lock; 195 | QString port; 196 | PortSettings settings; 197 | QextReadBuffer readBuffer; 198 | int settingsDirtyFlags; 199 | ulong lastErr; 200 | QextSerialPort::QueryMode queryMode; 201 | 202 | // platform specific members 203 | #ifdef Q_OS_UNIX 204 | int fd; 205 | QSocketNotifier *readNotifier; 206 | struct termios currentTermios; 207 | struct termios oldTermios; 208 | #elif (defined Q_OS_WIN) 209 | HANDLE handle; 210 | OVERLAPPED overlap; 211 | COMMCONFIG commConfig; 212 | COMMTIMEOUTS commTimeouts; 213 | QWinEventNotifier *winEventNotifier; 214 | DWORD eventMask; 215 | QList pendingWrites; 216 | QReadWriteLock *bytesToWriteLock; 217 | #endif 218 | 219 | /*fill PortSettings*/ 220 | void setBaudRate(BaudRateType baudRate, bool update=true); 221 | void setDataBits(DataBitsType dataBits, bool update=true); 222 | void setParity(ParityType parity, bool update=true); 223 | void setStopBits(StopBitsType stopbits, bool update=true); 224 | void setFlowControl(FlowType flow, bool update=true); 225 | void setTimeout(long millisec, bool update=true); 226 | void setPortSettings(const PortSettings &settings, bool update=true); 227 | 228 | void platformSpecificDestruct(); 229 | void platformSpecificInit(); 230 | void translateError(ulong error); 231 | void updatePortSettings(); 232 | 233 | qint64 readData_sys(char *data, qint64 maxSize); 234 | qint64 writeData_sys(const char *data, qint64 maxSize); 235 | void setDtr_sys(bool set=true); 236 | void setRts_sys(bool set=true); 237 | bool open_sys(QIODevice::OpenMode mode); 238 | bool close_sys(); 239 | bool flush_sys(); 240 | ulong lineStatus_sys(); 241 | qint64 bytesAvailable_sys() const; 242 | 243 | #ifdef Q_OS_WIN 244 | void _q_onWinEvent(HANDLE h); 245 | #endif 246 | void _q_canRead(); 247 | 248 | QextSerialPort *q_ptr; 249 | }; 250 | 251 | #endif //_QEXTSERIALPORT_P_H_ 252 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator_win.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialenumerator.h" 33 | #include "qextserialenumerator_p.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "qextserialport.h" 42 | 43 | #ifdef QT_GUI_LIB 44 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 45 | #include 46 | class QextSerialRegistrationWidget : public QWidget 47 | #else 48 | #include 49 | class QextSerialRegistrationWidget : public QWindow 50 | #endif 51 | { 52 | public: 53 | QextSerialRegistrationWidget(QextSerialEnumeratorPrivate *qese) { 54 | this->qese = qese; 55 | } 56 | ~QextSerialRegistrationWidget() {} 57 | 58 | protected: 59 | 60 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 61 | bool winEvent(MSG *message, long *result) { 62 | #else 63 | bool nativeEvent(const QByteArray & /*eventType*/, void *msg, long *result) { 64 | MSG *message = static_cast(msg); 65 | #endif 66 | if (message->message == WM_DEVICECHANGE) { 67 | qese->onDeviceChanged(message->wParam, message->lParam); 68 | *result = 1; 69 | return true; 70 | } 71 | return false; 72 | } 73 | private: 74 | QextSerialEnumeratorPrivate *qese; 75 | }; 76 | 77 | #endif // QT_GUI_LIB 78 | 79 | void QextSerialEnumeratorPrivate::platformSpecificInit() 80 | { 81 | #ifdef QT_GUI_LIB 82 | notificationWidget = 0; 83 | #endif // QT_GUI_LIB 84 | } 85 | 86 | /*! 87 | default 88 | */ 89 | void QextSerialEnumeratorPrivate::platformSpecificDestruct() 90 | { 91 | #ifdef QT_GUI_LIB 92 | if (notificationWidget) 93 | delete notificationWidget; 94 | #endif 95 | } 96 | 97 | // see http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426(v=vs.85).aspx 98 | // for list of GUID classes 99 | const GUID deviceClassGuids[] = 100 | { 101 | // Ports (COM & LPT ports), Class = Ports 102 | {0x4D36E978, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}}, 103 | // Modem, Class = Modem 104 | {0x4D36E96D, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}}, 105 | // Bluetooth Devices, Class = Bluetooth 106 | {0xE0CBF06C, 0xCD8B, 0x4647, {0xBB, 0x8A, 0x26, 0x3B, 0x43, 0xF0, 0xF9, 0x74}}, 107 | // Added by Arne Kristian Jansen, for use with com0com virtual ports (See Issue 54) 108 | {0xDF799E12, 0x3C56, 0x421B, {0xB2, 0x98, 0xB6, 0xD3, 0x64, 0x2B, 0xC8, 0x78}} 109 | }; 110 | 111 | /* Gordon Schumacher's macros for TCHAR -> QString conversions and vice versa */ 112 | #ifdef UNICODE 113 | #define QStringToTCHAR(x) (wchar_t *) x.utf16() 114 | #define PQStringToTCHAR(x) (wchar_t *) x->utf16() 115 | #define TCHARToQString(x) QString::fromUtf16((ushort *)(x)) 116 | #define TCHARToQStringN(x,y) QString::fromUtf16((ushort *)(x),(y)) 117 | #else 118 | #define QStringToTCHAR(x) x.local8Bit().constData() 119 | #define PQStringToTCHAR(x) x->local8Bit().constData() 120 | #define TCHARToQString(x) QString::fromLocal8Bit((char *)(x)) 121 | #define TCHARToQStringN(x,y) QString::fromLocal8Bit((char *)(x),(y)) 122 | #endif /*UNICODE*/ 123 | 124 | /*! 125 | \internal 126 | Get value of specified property from the registry. 127 | \a key handle to an open key. 128 | \a property property name. 129 | 130 | return property value. 131 | */ 132 | static QString getRegKeyValue(HKEY key, LPCTSTR property) 133 | { 134 | DWORD size = 0; 135 | DWORD type; 136 | ::RegQueryValueEx(key, property, NULL, NULL, NULL, &size); 137 | BYTE *buff = new BYTE[size]; 138 | QString result; 139 | if (::RegQueryValueEx(key, property, NULL, &type, buff, &size) == ERROR_SUCCESS) 140 | result = TCHARToQString(buff); 141 | ::RegCloseKey(key); 142 | delete [] buff; 143 | return result; 144 | } 145 | 146 | /*! 147 | \internal 148 | Get specific property from registry. 149 | \a devInfo pointer to the device information set that contains the interface 150 | and its underlying device. Returned by SetupDiGetClassDevs() function. 151 | \a devData pointer to an SP_DEVINFO_DATA structure that defines the device instance. 152 | this is returned by SetupDiGetDeviceInterfaceDetail() function. 153 | \a property registry property. One of defined SPDRP_* constants. 154 | 155 | return property string. 156 | */ 157 | static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property) 158 | { 159 | DWORD buffSize = 0; 160 | ::SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, NULL, 0, &buffSize); 161 | BYTE *buff = new BYTE[buffSize]; 162 | ::SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, buff, buffSize, NULL); 163 | QString result = TCHARToQString(buff); 164 | delete [] buff; 165 | return result; 166 | } 167 | 168 | /*! 169 | \internal 170 | */ 171 | static bool getDeviceDetailsWin(QextPortInfo *portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData 172 | , WPARAM wParam = DBT_DEVICEARRIVAL) 173 | { 174 | portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); 175 | if (wParam == DBT_DEVICEARRIVAL) 176 | portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); 177 | portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); 178 | QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); 179 | HKEY devKey = ::SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); 180 | portInfo->portName = getRegKeyValue(devKey, TEXT("PortName")); 181 | QRegExp idRx(QLatin1String("VID_(\\w+)&PID_(\\w+)")); 182 | if (hardwareIDs.toUpper().contains(idRx)) { 183 | bool dummy; 184 | portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); 185 | portInfo->productID = idRx.cap(2).toInt(&dummy, 16); 186 | //qDebug() << "got vid:" << vid << "pid:" << pid; 187 | } 188 | return true; 189 | } 190 | 191 | /*! 192 | \internal 193 | */ 194 | static void enumerateDevicesWin(const GUID &guid, QList *infoList) 195 | { 196 | HDEVINFO devInfo; 197 | if ((devInfo = ::SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT)) != INVALID_HANDLE_VALUE) { 198 | SP_DEVINFO_DATA devInfoData; 199 | devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 200 | for(int i = 0; ::SetupDiEnumDeviceInfo(devInfo, i, &devInfoData); i++) { 201 | QextPortInfo info; 202 | info.productID = info.vendorID = 0; 203 | getDeviceDetailsWin(&info, devInfo, &devInfoData); 204 | if (!info.portName.startsWith(QLatin1String("LPT"), Qt::CaseInsensitive)) 205 | infoList->append(info); 206 | } 207 | ::SetupDiDestroyDeviceInfoList(devInfo); 208 | } 209 | } 210 | 211 | 212 | static bool lessThan(const QextPortInfo &s1, const QextPortInfo &s2) 213 | { 214 | if (s1.portName.startsWith(QLatin1String("COM")) 215 | && s2.portName.startsWith(QLatin1String("COM"))) { 216 | return s1.portName.mid(3).toInt() QextSerialEnumeratorPrivate::getPorts_sys() 228 | { 229 | QList ports; 230 | const int count = sizeof(deviceClassGuids)/sizeof(deviceClassGuids[0]); 231 | for (int i=0; iwinId(), &dbh, flags) == NULL) { 260 | QESP_WARNING() << "RegisterDeviceNotification failed:" << GetLastError(); 261 | return false; 262 | } 263 | // setting up notifications doesn't tell us about devices already connected 264 | // so get those manually 265 | foreach (QextPortInfo port, getPorts_sys()) 266 | Q_EMIT q->deviceDiscovered(port); 267 | return true; 268 | #endif // QT_GUI_LIB 269 | } 270 | 271 | LRESULT QextSerialEnumeratorPrivate::onDeviceChanged(WPARAM wParam, LPARAM lParam) 272 | { 273 | if (DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam) { 274 | PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; 275 | if (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { 276 | PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; 277 | // delimiters are different across APIs...change to backslash. ugh. 278 | QString deviceID = TCHARToQString(pDevInf->dbcc_name).toUpper().replace(QLatin1String("#"), QLatin1String("\\")); 279 | 280 | const int count = sizeof(deviceClassGuids)/sizeof(deviceClassGuids[0]); 281 | for (int i=0; ideviceDiscovered(info); 310 | else if (wParam == DBT_DEVICEREMOVECOMPLETE) 311 | Q_EMIT q->deviceRemoved(info); 312 | break; 313 | } 314 | } 315 | SetupDiDestroyDeviceInfoList(devInfo); 316 | } 317 | return rv; 318 | } 319 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialenumerator_osx.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialenumerator.h" 33 | #include "qextserialenumerator_p.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | void QextSerialEnumeratorPrivate::platformSpecificInit() 40 | { 41 | } 42 | 43 | void QextSerialEnumeratorPrivate::platformSpecificDestruct() 44 | { 45 | IONotificationPortDestroy(notificationPortRef); 46 | } 47 | 48 | // static 49 | QList QextSerialEnumeratorPrivate::getPorts_sys() 50 | { 51 | QList infoList; 52 | io_iterator_t serialPortIterator = 0; 53 | kern_return_t kernResult = KERN_FAILURE; 54 | CFMutableDictionaryRef matchingDictionary; 55 | 56 | // first try to get any serialbsd devices, then try any USBCDC devices 57 | if (!(matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue))) { 58 | QESP_WARNING("IOServiceMatching returned a NULL dictionary."); 59 | return infoList; 60 | } 61 | CFDictionaryAddValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); 62 | 63 | // then create the iterator with all the matching devices 64 | if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS) { 65 | qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; 66 | return infoList; 67 | } 68 | iterateServicesOSX(serialPortIterator, infoList); 69 | IOObjectRelease(serialPortIterator); 70 | serialPortIterator = 0; 71 | 72 | if (!(matchingDictionary = IOServiceNameMatching("AppleUSBCDC"))) { 73 | QESP_WARNING("IOServiceNameMatching returned a NULL dictionary."); 74 | return infoList; 75 | } 76 | 77 | if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS) { 78 | qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; 79 | return infoList; 80 | } 81 | iterateServicesOSX(serialPortIterator, infoList); 82 | IOObjectRelease(serialPortIterator); 83 | 84 | return infoList; 85 | } 86 | 87 | void QextSerialEnumeratorPrivate::iterateServicesOSX(io_object_t service, QList &infoList) 88 | { 89 | // Iterate through all modems found. 90 | io_object_t usbService; 91 | while ((usbService = IOIteratorNext(service))) { 92 | QextPortInfo info; 93 | info.vendorID = 0; 94 | info.productID = 0; 95 | getServiceDetailsOSX(usbService, &info); 96 | infoList.append(info); 97 | } 98 | } 99 | 100 | bool QextSerialEnumeratorPrivate::getServiceDetailsOSX(io_object_t service, QextPortInfo *portInfo) 101 | { 102 | bool retval = true; 103 | CFTypeRef bsdPathAsCFString = NULL; 104 | CFTypeRef productNameAsCFString = NULL; 105 | CFTypeRef vendorIdAsCFNumber = NULL; 106 | CFTypeRef productIdAsCFNumber = NULL; 107 | // check the name of the modem's callout device 108 | bsdPathAsCFString = IORegistryEntryCreateCFProperty(service, CFSTR(kIOCalloutDeviceKey), 109 | kCFAllocatorDefault, 0); 110 | 111 | // wander up the hierarchy until we find the level that can give us the 112 | // vendor/product IDs and the product name, if available 113 | io_registry_entry_t parent; 114 | kern_return_t kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); 115 | while (kernResult == KERN_SUCCESS && !vendorIdAsCFNumber && !productIdAsCFNumber) { 116 | if (!productNameAsCFString) 117 | productNameAsCFString = IORegistryEntrySearchCFProperty(parent, 118 | kIOServicePlane, 119 | CFSTR("Product Name"), 120 | kCFAllocatorDefault, 0); 121 | vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, 122 | kIOServicePlane, 123 | CFSTR(kUSBVendorID), 124 | kCFAllocatorDefault, 0); 125 | productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, 126 | kIOServicePlane, 127 | CFSTR(kUSBProductID), 128 | kCFAllocatorDefault, 0); 129 | io_registry_entry_t oldparent = parent; 130 | kernResult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); 131 | IOObjectRelease(oldparent); 132 | } 133 | 134 | io_string_t ioPathName; 135 | IORegistryEntryGetPath(service, kIOServicePlane, ioPathName); 136 | portInfo->physName = ioPathName; 137 | 138 | if (bsdPathAsCFString) { 139 | char path[MAXPATHLEN]; 140 | if (CFStringGetCString((CFStringRef)bsdPathAsCFString, path, 141 | PATH_MAX, kCFStringEncodingUTF8)) 142 | portInfo->portName = path; 143 | CFRelease(bsdPathAsCFString); 144 | } 145 | 146 | if (productNameAsCFString) { 147 | char productName[MAXPATHLEN]; 148 | if (CFStringGetCString((CFStringRef)productNameAsCFString, productName, 149 | PATH_MAX, kCFStringEncodingUTF8)) 150 | portInfo->friendName = productName; 151 | CFRelease(productNameAsCFString); 152 | } 153 | 154 | if (vendorIdAsCFNumber) { 155 | SInt32 vID; 156 | if (CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberSInt32Type, &vID)) 157 | portInfo->vendorID = vID; 158 | CFRelease(vendorIdAsCFNumber); 159 | } 160 | 161 | if (productIdAsCFNumber) { 162 | SInt32 pID; 163 | if (CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberSInt32Type, &pID)) 164 | portInfo->productID = pID; 165 | CFRelease(productIdAsCFNumber); 166 | } 167 | IOObjectRelease(service); 168 | return retval; 169 | } 170 | 171 | // IOKit callbacks registered via setupNotifications() 172 | void deviceDiscoveredCallbackOSX(void *ctxt, io_iterator_t serialPortIterator) 173 | { 174 | QextSerialEnumeratorPrivate *d = (QextSerialEnumeratorPrivate *)ctxt; 175 | io_object_t serialService; 176 | while ((serialService = IOIteratorNext(serialPortIterator))) 177 | d->onDeviceDiscoveredOSX(serialService); 178 | } 179 | 180 | void deviceTerminatedCallbackOSX(void *ctxt, io_iterator_t serialPortIterator) 181 | { 182 | QextSerialEnumeratorPrivate *d = (QextSerialEnumeratorPrivate *)ctxt; 183 | io_object_t serialService; 184 | while ((serialService = IOIteratorNext(serialPortIterator))) 185 | d->onDeviceTerminatedOSX(serialService); 186 | } 187 | 188 | /* 189 | A device has been discovered via IOKit. 190 | Create a QextPortInfo if possible, and emit the signal indicating that we've found it. 191 | */ 192 | void QextSerialEnumeratorPrivate::onDeviceDiscoveredOSX(io_object_t service) 193 | { 194 | Q_Q(QextSerialEnumerator); 195 | QextPortInfo info; 196 | info.vendorID = 0; 197 | info.productID = 0; 198 | if (getServiceDetailsOSX(service, &info)) 199 | Q_EMIT q->deviceDiscovered(info); 200 | } 201 | 202 | /* 203 | Notification via IOKit that a device has been removed. 204 | Create a QextPortInfo if possible, and emit the signal indicating that it's gone. 205 | */ 206 | void QextSerialEnumeratorPrivate::onDeviceTerminatedOSX(io_object_t service) 207 | { 208 | Q_Q(QextSerialEnumerator); 209 | QextPortInfo info; 210 | info.vendorID = 0; 211 | info.productID = 0; 212 | if (getServiceDetailsOSX(service, &info)) 213 | Q_EMIT q->deviceRemoved(info); 214 | } 215 | 216 | /* 217 | Create matching dictionaries for the devices we want to get notifications for, 218 | and add them to the current run loop. Invoke the callbacks that will be responding 219 | to these notifications once to arm them, and discover any devices that 220 | are currently connected at the time notifications are setup. 221 | */ 222 | bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool /*setup*/) 223 | { 224 | kern_return_t kernResult; 225 | mach_port_t masterPort; 226 | CFRunLoopSourceRef notificationRunLoopSource; 227 | CFMutableDictionaryRef classesToMatch; 228 | CFMutableDictionaryRef cdcClassesToMatch; 229 | io_iterator_t portIterator; 230 | 231 | kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); 232 | if (KERN_SUCCESS != kernResult) { 233 | qDebug() << "IOMasterPort returned:" << kernResult; 234 | return false; 235 | } 236 | 237 | classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); 238 | if (classesToMatch == NULL) 239 | qDebug("IOServiceMatching returned a NULL dictionary."); 240 | else 241 | CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); 242 | 243 | if (!(cdcClassesToMatch = IOServiceNameMatching("AppleUSBCDC"))) { 244 | QESP_WARNING("couldn't create cdc matching dict"); 245 | return false; 246 | } 247 | 248 | // Retain an additional reference since each call to IOServiceAddMatchingNotification consumes one. 249 | classesToMatch = (CFMutableDictionaryRef) CFRetain(classesToMatch); 250 | cdcClassesToMatch = (CFMutableDictionaryRef) CFRetain(cdcClassesToMatch); 251 | 252 | notificationPortRef = IONotificationPortCreate(masterPort); 253 | if (notificationPortRef == NULL) { 254 | qDebug("IONotificationPortCreate return a NULL IONotificationPortRef."); 255 | return false; 256 | } 257 | 258 | notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPortRef); 259 | if (notificationRunLoopSource == NULL) { 260 | qDebug("IONotificationPortGetRunLoopSource returned NULL CFRunLoopSourceRef."); 261 | return false; 262 | } 263 | 264 | CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode); 265 | 266 | kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, classesToMatch, 267 | deviceDiscoveredCallbackOSX, this, &portIterator); 268 | if (kernResult != KERN_SUCCESS) { 269 | qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; 270 | return false; 271 | } 272 | 273 | // arm the callback, and grab any devices that are already connected 274 | deviceDiscoveredCallbackOSX(this, portIterator); 275 | 276 | kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, cdcClassesToMatch, 277 | deviceDiscoveredCallbackOSX, this, &portIterator); 278 | if (kernResult != KERN_SUCCESS) { 279 | qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; 280 | return false; 281 | } 282 | 283 | // arm the callback, and grab any devices that are already connected 284 | deviceDiscoveredCallbackOSX(this, portIterator); 285 | 286 | kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, classesToMatch, 287 | deviceTerminatedCallbackOSX, this, &portIterator); 288 | if (kernResult != KERN_SUCCESS) { 289 | qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; 290 | return false; 291 | } 292 | 293 | // arm the callback, and clear any devices that are terminated 294 | deviceTerminatedCallbackOSX(this, portIterator); 295 | 296 | kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, cdcClassesToMatch, 297 | deviceTerminatedCallbackOSX, this, &portIterator); 298 | if (kernResult != KERN_SUCCESS) { 299 | qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; 300 | return false; 301 | } 302 | 303 | // arm the callback, and clear any devices that are terminated 304 | deviceTerminatedCallbackOSX(this, portIterator); 305 | return true; 306 | } 307 | 308 | -------------------------------------------------------------------------------- /qextserialport/ChangeLog: -------------------------------------------------------------------------------- 1 | Change history for QextSerialPort (formerly QwSerialPort): 2 | (Lines beginning with + represent new functionality, * represent changed or 3 | fixed functionality, - represent removed or deprecated functionality) 4 | 5 | Version 1.2 rc (2012 Debao Zhang) 6 | * Build-system refactor 7 | * Issue 145 : Custom baud support for MacOS 8 | * Issue 36 : Fix Devices Notification for Vista 9 | * Issue 54 and Issue 108 : Try detect more ports for windows 10 | * Issue 139 : Adjust the name of generated library 11 | - QextWinEventNotifier has been removed 12 | 13 | Version 1.2 beta2 (2012 Debao Zhang) 14 | * Issue 124 : implement canReadLine 15 | * Issue 122 : make Dtr default to TRUE under Windows. 16 | * Issue 127 : fix QObject::MoveToThread brokes SerialPort on Windows 17 | * Issue 129 : Add custom baud support for Windows. 18 | * Issue 131 : Make sure portName returned by QextSerialEnumerator can be used by QextSerialPort 19 | * Issue 134 : Make "make install" really works 20 | * Issue 2: device discovery / removal notification on linux (read config_example.pri to figure out how to enable it.) 21 | 22 | Version 1.2 beta1 (2012 Debao Zhang) 23 | * D-pointer and Q_PRIVATE_SLOT are used to moving private members from QextSerialPort to QextSerialPortPrivate 24 | * qdoc3 instead of doxygen is used for generating documents 25 | * MIT license header add to all sources files 26 | + add a helper class QextWinEventNotifier for windows user, when user's SDK doesnot contain Qt's private files, this class will be auto selected. 27 | 28 | Version 1.2win-alpha (2007 Michal Policht) 29 | + Added QextSerialEnumerator pre-alpha. Works under W2k and later versions of Windows. 30 | + Event driven mechanism (alternative to polling) is now available on Windows. 31 | - Removed default (=0) parameter from open() functions. 32 | * Fixed bug #1714917 in Win_QextSerialPort::close() method (by Kurt). 33 | * Fixed problem with lack of proper blocking in readData() on win32 (by Brandon Fosdick). 34 | * Removed QT_THREAD_SUPPORT option. Now QextSerialPort must be always compiled with threads support. 35 | * Mutexes are not static. 36 | * setTimeout() now accepts only one parameter. 37 | * bytesAvailable() on POSIX now shows 0 bytes instead of -1 when no bytes are available. 38 | * bytesAvailable() is const. 39 | * native POSIX file descriptors instead of QFile->handle() calls 40 | + POSIX: Save and restore original termios when opening and closing the device 41 | * POSIX: Only disable special characters on systems that support it 42 | * POSIX: Use cfmakeraw(3) to get a non-canonical termios 43 | + POSIX: Call close(2) in close() to actually close the device 44 | 45 | Version 1.1 (official release) 46 | 47 | Version 1.0.1 48 | * Minor changes (mostly in test application) 49 | 50 | Version 1.0.0e (by Micha? Policht) 51 | * Fixed bytesAvailable(). Includes buffered bytes to the result. 52 | + Added isSequential() method. 53 | + Provided test application 54 | 55 | Version 1.0.0d ( changes by Micha? Policht ) 56 | - Removed isOpen() overriden declaration/implementation from qextserialport's classes. isOpen() relies on QIODevice now. 57 | - Removed bool portOpen variable. Replaced by internal QIODevice.openMode. 58 | - Removed getChar(), putChar() overriden declaration/implementation. QIODevice can handle this. 59 | * Calling open() with specified OpenMode invokes QIODevice::open() which result in proper openMode setting. 60 | * readData(), writeData() are protected as in QIODevice declaration. 61 | * QIODevice:: read() and write() function are working now (use them instead of readData() writeData()). 62 | * readData(), writeData() don't check if port is open any more (read() and write() assures that). The same behaviour can be found in QFile for example. 63 | * Fixed readLine(). 64 | 65 | * Fixed randomly crash on deletion bug on Windows ( by Stuart Nixon ) 66 | http://lists.trolltech.com/qt-interest/2007-02/thread00340-0.html#msg00351 67 | 68 | Version 0.9 (March 3, 2005) Stefan Sander : 69 | + Added a new precompiler constant, _TTY_FREEBSD_ 70 | to support FreeBSD port names. 71 | + Added _TTY_WIN_ constant in qextserialport.pro win32:DEFINES 72 | to have Windows port names as default when compiling on it. 73 | - Removed construct() call from QextSerialBase constructors, 74 | it is called indirectly through Win_QextSerialPort::construct() 75 | and Posix_QextSerialPort::construct(). 76 | + Added construct() call to Win_QextSerialPort constructors. 77 | + Added setTimeout(0, 500) call to Win_QextSerialPort::construct(). 78 | - Removed setTimeout(0, 500) call from Win_QextSerialPort(const char* name). 79 | * Fixed Posix_QextSerialPort::open(int) control flow, now the port settings 80 | are only applied if the associated file could be opened. 81 | * Fixed masking CR to NL, in Posix_CommConfig.c_iflag 82 | 83 | Version 0.8 (, 2003) (Alpha release): 84 | * Added code to set the port timeouts in Win_QextSerialPort's default 85 | constructor. 86 | * Fixed Posix_QextSerialPort::construct() to set up the port correctly. 87 | * Fixed syntax errors in 2 ioctl() calls in posix_QextSerialPort. 88 | * lastError is now initialized to E_NO_ERROR in the QextSerialBase 89 | constructor. 90 | * The select() call in posix_QextSerialPort::bytesWaiting() is now 91 | properly coded. Previously it would always time out. 92 | * Fixed runtime errors in the ioctl() calls for 93 | Posix_QextSerialPort::setDtr() and Posix_QextSerialPort::setRts(). 94 | Thanks to Marc Pignat. 95 | 96 | Version 0.7 (June 15, 2002) : 97 | (0.61 - unofficial release) 98 | * Fixed a small bug in the initializations of the static members when 99 | QT_THREAD_SUPPORT was defined. 100 | * Fixed a bug that caused Borland's compiler to choke on Windows platforms 101 | (which perversely actually stemmed from a shortcoming of Visual C++ that 102 | Borland doesn't have). 103 | 104 | (0.62 - unofficial release) 105 | * Fixed a bug that gave Q_LONG the wrong typedef for QT versions prior to 106 | 3.0. 107 | 108 | (0.63 - unofficial release) 109 | * Fixed 2 incorrect references to Posix_Comm_Config. 110 | * Fixed scoping of Posix_QextSerialPort::operator=(). 111 | * Posix_QextSerialPort::construct should now be coded correctly. 112 | * Fixed return type for Posix_QextSerialPort::size(). 113 | 114 | (0.64 - unofficial release) 115 | * Fixed all the port settings functions to work properly when opening the 116 | port for the first time - previously none of the settings were being 117 | applied when the port was opened. 118 | * Fixed an oversight in Win_QextSerialPort::open() that caused the setting 119 | of port parameters to fail on NT and 2000 systems. 120 | 121 | (0.7 - official release) 122 | * Fixed some calls to QextSerialBase constructors that no longer exist on 123 | the POSIX side. 124 | * Fixed the bad memcpy()'s in the POSIX copy constructor. 125 | * Fixed the Offset scoping problem under gcc 2.95. 126 | * The CBAUD flag has been deprecated on some POSIX systems. Fixed 127 | Posix_QextSerialPort::setBaudRate() to reflect this. 128 | * Added construct() calls to all of the Posix_QextSerialPort constructors. 129 | * Fixed double (and conflicting) typedefs of Offset when using QT versions 130 | prior to 3.0 131 | * Changed the call to CreateFile() to CreateFileA() in 132 | Win_QextSerialPort.cpp. This should get rid of problems for those using 133 | Unicode or other multibyte character sets for their string literals. 134 | * A few tweaks to the documentation. 135 | 136 | - Removed the protected Posix_Handle variable from Posix_QextSerialPort. 137 | 138 | Version 0.6 (March 11, 2002) : 139 | + Added a new precompiler constant, QTVER_PRE_30. QT3 changed the return 140 | types of some QIODevice functions. Therefore, if compiling on versions 141 | of QT prior to 3.0, you should always define QTVER_PRE_30 in your project. 142 | Also had to add some preprocessor blocks to support both 3.0 and earlier 143 | versions of QT. 144 | + Added implementations of 2 of the new constructors added in 0.5 to both 145 | Win_QextSerialPort and Posix_QextSerialPort. 146 | 147 | * The scoping of the enums used in the PortSettings struct has been fixed. 148 | * QObject inheritance has been removed. This should not affect the 149 | functionality of the classes. 150 | * Replaced a few stray references to mutex->unlock() with UNLOCK_MUTEX() in 151 | the Windows code. 152 | * Fixed several runtime errors caused by calling nonexistent members of 153 | QextSerialBase. 154 | * Fixed a whole bunch of little things that were causing MSVC to choke when 155 | compiling for Windows. 156 | 157 | Version 0.5 (February 15, 2002): 158 | + There are 4 new macros (LOCK_MUTEX, UNLOCK_MUTEX, TTY_WARNING, and 159 | TTY_PORTABILITY_WARNING) that replace most of those ugly #ifdef blocks in 160 | the code. 161 | + In place of the old namingConvention stuff, there is a new function, 162 | setName(). It is used to set the name of the device to be associated with 163 | the object. The new name() function can be used to retrieve the device 164 | name, which is stored in the new member variable portName. 165 | + There is a new version of open() that takes a const char* as a parameter. 166 | It can be used to specify the name of the device when it is opened rather 167 | than at construction time. 168 | 169 | * 3 constructors have been removed and 3 more added. There is now a copy 170 | constructor (and operator=()) as well as a constructor that takes a 171 | PortSettings structure as a parameter, and another that takes both a 172 | device name and a PortSettings structure. As a result of these changes 173 | the PortSettings structure declaration is no longer local to the 174 | QextSerialBase class. All of the removed constructors had to do with 175 | the setNamingConvention() system. 176 | * The static mutex member should now be reference-counted and only deleted 177 | when it is no longer referenced. 178 | * Most of the object construction duties have been pushed back into 179 | QextSerialBase 180 | * Fixed a couple resource leaks, mostly to do with unlocking the mutex 181 | properly 182 | 183 | - Removed the setNamingConvention() nonsense. 184 | - Removed all QStrings and calls to sprintf() for thread compatibility. 185 | - Removed setNumber() functions as well as the portNumber member variable, 186 | as they were only necessary under the setNamingConvention() system. 187 | 188 | I am grateful to Jorg Preiss (Preisz? Sorry, American keyboards don't have 189 | an ess-tset character ;)) for his invaluable input on most of the changes 190 | that went into this version. 191 | 192 | Version 0.4 (March 20, 2001): 193 | + All of the classes now derive from QObject as well as QIODevice. This 194 | is pretty much useless at the moment - signals and slots may be used 195 | to implement asynchronous communications in a future version 196 | + Added configurable timeouts via the setTimeout() function. The default 197 | timeout for read and write operations is now 500 milliseconds 198 | + There is now a functional .pro file for the library (thanks to 199 | Gunnstein Lye) 200 | + The prefixes for all of the classes have changed from Qw to Qext, in 201 | compliance with the qt-addons project standard 202 | 203 | * Fixed a bug that caused port settings to be restored incorrectly when 204 | switching ports with setNumber() 205 | * Minor changes to QextSerialBase::setNumber(). Functionality should now 206 | reflect the documentation, which has also been updated to reflect the 207 | changes that went in on version 0.3. 208 | * Some fixes to the documentation. The Posix_QextSerialPort and 209 | Win_QextSerialPort classes should no longer have any unnecessary 210 | references to inapplicable platforms, and the documentation for open() has 211 | been updated. 212 | * Should now compile without QT_THREAD_SUPPORT defined (ie, in single- 213 | threaded environments), although it will require slight changes to the 214 | makefile (tmake "CONFIG-=thread" should work) 215 | * Fixed a few compilation issues, especially on the POSIX side (should 216 | compile under Linux now :)) 217 | * POSIX code is a little cleaner and more efficient 218 | * Various small fixes to the documentation 219 | * Constants now follow a consistent naming convention, with underscores at 220 | the beginning and end of each. For example TTY_POSIX has become 221 | _TTY_POSIX_ 222 | 223 | Version 0.3 (Feb. 14, 2001): 224 | + Added a warning that appears when QwSerialPort is compiled on a POSIX 225 | platform that does not implement 76800 baud operation. In this situation 226 | QwSerialPort will also switch to 57600 baud. 227 | + Major code reorganization - there are now 4 classes instead of 1. This 228 | should remove a lot of the #ifdef...#else...#endif constructs and 229 | hopefully make the code easier to read. Including the class in your 230 | project is still done by including QwSerialPort.h and instantiating a 231 | QwSerialPort object. 232 | 233 | * The serial port associated with a QwSerialPort object is no longer 234 | opened on construction, or upon calling the setNumber() function. You 235 | must now explicitly call open() to open the port. 236 | 237 | Version 0.2 (Jan. 3, 2001): 238 | + Added lastError() function with rudimentary error codes 239 | + Better documentation 240 | + Added ability to examine the empty/not empty state of a port's input 241 | buffer with atEnd() 242 | + Added ability to retrieve the number of bytes in a port's input buffer 243 | with size() (thanks to Olivier Tubach) 244 | + Added ability to turn off portability warnings by defining 245 | TTY_NOWARN_PORT in your project 246 | + Added ability to turn off all warning messages by defining TTY_NOWARN 247 | in your project 248 | + Added ability to select POSIX serial functions in Windows NT/2000 by 249 | defining TTY_POSIX in your project (untested) 250 | + Added control over RTS and DTR lines with setRts() and setDtr() 251 | respectively 252 | + Added ability to query line status using lineStatus(). 253 | + Added readLine() functionality (thanks to Olivier Tubach) 254 | + Added bytesWaiting(), a non-const/thread-safe version of size() 255 | + The class should now be thread-safe through the use of a recursive 256 | QMutex (untested) 257 | 258 | * Fixed a bug that could cause hardware flow control not to work on some 259 | POSIX systems 260 | * Put in a few missing fileno() calls in the POSIX code 261 | * Fixed a few syntax errors that caused compilation to fail on POSIX systems 262 | 263 | - BAUD0 is no longer a valid baud rate setting - to drop the DTR line, 264 | call setDtr(FALSE) 265 | 266 | Version 0.1 (Dec. 11, 2000): 267 | Initial public release. 268 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport_win.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialport.h" 33 | #include "qextserialport_p.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 41 | # include 42 | #else 43 | # include 44 | #endif 45 | void QextSerialPortPrivate::platformSpecificInit() 46 | { 47 | handle = INVALID_HANDLE_VALUE; 48 | ZeroMemory(&overlap, sizeof(OVERLAPPED)); 49 | overlap.hEvent = CreateEvent(NULL, true, false, NULL); 50 | winEventNotifier = 0; 51 | bytesToWriteLock = new QReadWriteLock; 52 | } 53 | 54 | void QextSerialPortPrivate::platformSpecificDestruct() { 55 | CloseHandle(overlap.hEvent); 56 | delete bytesToWriteLock; 57 | } 58 | 59 | 60 | /*! 61 | \internal 62 | COM ports greater than 9 need \\.\ prepended 63 | 64 | This is only need when open the port. 65 | */ 66 | static QString fullPortNameWin(const QString &name) 67 | { 68 | QRegExp rx(QLatin1String("^COM(\\d+)")); 69 | QString fullName(name); 70 | if (fullName.contains(rx)) 71 | fullName.prepend(QLatin1String("\\\\.\\")); 72 | return fullName; 73 | } 74 | 75 | bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) 76 | { 77 | Q_Q(QextSerialPort); 78 | DWORD confSize = sizeof(COMMCONFIG); 79 | commConfig.dwSize = confSize; 80 | DWORD dwFlagsAndAttributes = 0; 81 | if (queryMode == QextSerialPort::EventDriven) 82 | dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; 83 | 84 | /*open the port*/ 85 | handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ|GENERIC_WRITE, 86 | 0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); 87 | if (handle != INVALID_HANDLE_VALUE) { 88 | q->setOpenMode(mode); 89 | /*configure port settings*/ 90 | GetCommConfig(handle, &commConfig, &confSize); 91 | GetCommState(handle, &(commConfig.dcb)); 92 | 93 | /*set up parameters*/ 94 | commConfig.dcb.fBinary = TRUE; 95 | commConfig.dcb.fInX = FALSE; 96 | commConfig.dcb.fOutX = FALSE; 97 | commConfig.dcb.fAbortOnError = FALSE; 98 | commConfig.dcb.fNull = FALSE; 99 | /* Dtr default to true. See Issue 122*/ 100 | commConfig.dcb.fDtrControl = TRUE; 101 | /*flush all settings*/ 102 | settingsDirtyFlags = DFE_ALL; 103 | updatePortSettings(); 104 | 105 | //init event driven approach 106 | if (queryMode == QextSerialPort::EventDriven) { 107 | if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { 108 | QESP_WARNING()<<"failed to set Comm Mask. Error code:"<("HANDLE"); 113 | q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection); 114 | WaitCommEvent(handle, &eventMask, &overlap); 115 | } 116 | return true; 117 | } 118 | return false; 119 | } 120 | 121 | bool QextSerialPortPrivate::close_sys() 122 | { 123 | flush_sys(); 124 | CancelIo(handle); 125 | if (CloseHandle(handle)) 126 | handle = INVALID_HANDLE_VALUE; 127 | if (winEventNotifier) { 128 | winEventNotifier->setEnabled(false); 129 | winEventNotifier->deleteLater(); 130 | winEventNotifier = 0; 131 | } 132 | 133 | foreach (OVERLAPPED *o, pendingWrites) { 134 | CloseHandle(o->hEvent); 135 | delete o; 136 | } 137 | pendingWrites.clear(); 138 | return true; 139 | } 140 | 141 | bool QextSerialPortPrivate::flush_sys() 142 | { 143 | FlushFileBuffers(handle); 144 | return true; 145 | } 146 | 147 | qint64 QextSerialPortPrivate::bytesAvailable_sys() const 148 | { 149 | DWORD Errors; 150 | COMSTAT Status; 151 | if (ClearCommError(handle, &Errors, &Status)) { 152 | return Status.cbInQue; 153 | } 154 | return (qint64)-1; 155 | } 156 | 157 | /* 158 | Translates a system-specific error code to a QextSerialPort error code. Used internally. 159 | */ 160 | void QextSerialPortPrivate::translateError(ulong error) 161 | { 162 | if (error & CE_BREAK) { 163 | lastErr = E_BREAK_CONDITION; 164 | } 165 | else if (error & CE_FRAME) { 166 | lastErr = E_FRAMING_ERROR; 167 | } 168 | else if (error & CE_IOE) { 169 | lastErr = E_IO_ERROR; 170 | } 171 | else if (error & CE_MODE) { 172 | lastErr = E_INVALID_FD; 173 | } 174 | else if (error & CE_OVERRUN) { 175 | lastErr = E_BUFFER_OVERRUN; 176 | } 177 | else if (error & CE_RXPARITY) { 178 | lastErr = E_RECEIVE_PARITY_ERROR; 179 | } 180 | else if (error & CE_RXOVER) { 181 | lastErr = E_RECEIVE_OVERFLOW; 182 | } 183 | else if (error & CE_TXFULL) { 184 | lastErr = E_TRANSMIT_OVERFLOW; 185 | } 186 | } 187 | 188 | /* 189 | Reads a block of data from the serial port. This function will read at most maxlen bytes from 190 | the serial port and place them in the buffer pointed to by data. Return value is the number of 191 | bytes actually read, or -1 on error. 192 | 193 | \warning before calling this function ensure that serial port associated with this class 194 | is currently open (use isOpen() function to check if port is open). 195 | */ 196 | qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize) 197 | { 198 | DWORD bytesRead = 0; 199 | bool failed = false; 200 | if (queryMode == QextSerialPort::EventDriven) { 201 | OVERLAPPED overlapRead; 202 | ZeroMemory(&overlapRead, sizeof(OVERLAPPED)); 203 | if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, &overlapRead)) { 204 | if (GetLastError() == ERROR_IO_PENDING) 205 | GetOverlappedResult(handle, &overlapRead, &bytesRead, true); 206 | else 207 | failed = true; 208 | } 209 | } else if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, NULL)) { 210 | failed = true; 211 | } 212 | if (!failed) 213 | return (qint64)bytesRead; 214 | 215 | lastErr = E_READ_FAILED; 216 | return -1; 217 | } 218 | 219 | /* 220 | Writes a block of data to the serial port. This function will write len bytes 221 | from the buffer pointed to by data to the serial port. Return value is the number 222 | of bytes actually written, or -1 on error. 223 | 224 | \warning before calling this function ensure that serial port associated with this class 225 | is currently open (use isOpen() function to check if port is open). 226 | */ 227 | qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize) 228 | { 229 | DWORD bytesWritten = 0; 230 | bool failed = false; 231 | if (queryMode == QextSerialPort::EventDriven) { 232 | OVERLAPPED *newOverlapWrite = new OVERLAPPED; 233 | ZeroMemory(newOverlapWrite, sizeof(OVERLAPPED)); 234 | newOverlapWrite->hEvent = CreateEvent(NULL, true, false, NULL); 235 | if (WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, newOverlapWrite)) { 236 | CloseHandle(newOverlapWrite->hEvent); 237 | delete newOverlapWrite; 238 | } 239 | else if (GetLastError() == ERROR_IO_PENDING) { 240 | // writing asynchronously...not an error 241 | QWriteLocker writelocker(bytesToWriteLock); 242 | pendingWrites.append(newOverlapWrite); 243 | } 244 | else { 245 | QESP_WARNING()<<"QextSerialPort write error:"<hEvent)) 248 | QESP_WARNING("QextSerialPort: couldn't cancel IO"); 249 | if (!CloseHandle(newOverlapWrite->hEvent)) 250 | QESP_WARNING("QextSerialPort: couldn't close OVERLAPPED handle"); 251 | delete newOverlapWrite; 252 | } 253 | } else if (!WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, NULL)) { 254 | failed = true; 255 | } 256 | 257 | if (!failed) 258 | return (qint64)bytesWritten; 259 | 260 | lastErr = E_WRITE_FAILED; 261 | return -1; 262 | } 263 | 264 | void QextSerialPortPrivate::setDtr_sys(bool set) { 265 | EscapeCommFunction(handle, set ? SETDTR : CLRDTR); 266 | } 267 | 268 | void QextSerialPortPrivate::setRts_sys(bool set) { 269 | EscapeCommFunction(handle, set ? SETRTS : CLRRTS); 270 | } 271 | 272 | ulong QextSerialPortPrivate::lineStatus_sys(void) { 273 | unsigned long Status = 0, Temp = 0; 274 | GetCommModemStatus(handle, &Temp); 275 | if (Temp & MS_CTS_ON) Status |= LS_CTS; 276 | if (Temp & MS_DSR_ON) Status |= LS_DSR; 277 | if (Temp & MS_RING_ON) Status |= LS_RI; 278 | if (Temp & MS_RLSD_ON) Status |= LS_DCD; 279 | return Status; 280 | } 281 | 282 | /* 283 | Triggered when there's activity on our HANDLE. 284 | */ 285 | void QextSerialPortPrivate::_q_onWinEvent(HANDLE h) 286 | { 287 | Q_Q(QextSerialPort); 288 | if (h == overlap.hEvent) { 289 | if (eventMask & EV_RXCHAR) { 290 | if (q->sender() != q && bytesAvailable_sys() > 0) 291 | _q_canRead(); 292 | } 293 | if (eventMask & EV_TXEMPTY) { 294 | /* 295 | A write completed. Run through the list of OVERLAPPED writes, and if 296 | they completed successfully, take them off the list and delete them. 297 | Otherwise, leave them on there so they can finish. 298 | */ 299 | qint64 totalBytesWritten = 0; 300 | QList overlapsToDelete; 301 | foreach (OVERLAPPED *o, pendingWrites) { 302 | DWORD numBytes = 0; 303 | if (GetOverlappedResult(handle, o, &numBytes, false)) { 304 | overlapsToDelete.append(o); 305 | totalBytesWritten += numBytes; 306 | } else if (GetLastError() != ERROR_IO_INCOMPLETE) { 307 | overlapsToDelete.append(o); 308 | QESP_WARNING()<<"CommEvent overlapped write error:" << GetLastError(); 309 | } 310 | } 311 | 312 | if (q->sender() != q && totalBytesWritten > 0) { 313 | QWriteLocker writelocker(bytesToWriteLock); 314 | Q_EMIT q->bytesWritten(totalBytesWritten); 315 | } 316 | 317 | foreach (OVERLAPPED *o, overlapsToDelete) { 318 | OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o)); 319 | CloseHandle(toDelete->hEvent); 320 | delete toDelete; 321 | } 322 | } 323 | if (eventMask & EV_DSR) { 324 | if (lineStatus_sys() & LS_DSR) 325 | Q_EMIT q->dsrChanged(true); 326 | else 327 | Q_EMIT q->dsrChanged(false); 328 | } 329 | } 330 | WaitCommEvent(handle, &eventMask, &overlap); 331 | } 332 | 333 | void QextSerialPortPrivate::updatePortSettings() 334 | { 335 | if (!q_ptr->isOpen() || !settingsDirtyFlags) 336 | return; 337 | 338 | //fill struct : COMMCONFIG 339 | if (settingsDirtyFlags & DFE_BaudRate) { 340 | commConfig.dcb.BaudRate = settings.BaudRate; 341 | } 342 | if (settingsDirtyFlags & DFE_Parity) { 343 | commConfig.dcb.Parity = (BYTE)settings.Parity; 344 | commConfig.dcb.fParity = (settings.Parity == PAR_NONE) ? FALSE : TRUE; 345 | } 346 | if (settingsDirtyFlags & DFE_DataBits) { 347 | commConfig.dcb.ByteSize = (BYTE)settings.DataBits; 348 | } 349 | if (settingsDirtyFlags & DFE_StopBits) { 350 | switch (settings.StopBits) { 351 | case STOP_1: 352 | commConfig.dcb.StopBits = ONESTOPBIT; 353 | break; 354 | case STOP_1_5: 355 | commConfig.dcb.StopBits = ONE5STOPBITS; 356 | break; 357 | case STOP_2: 358 | commConfig.dcb.StopBits = TWOSTOPBITS; 359 | break; 360 | } 361 | } 362 | if (settingsDirtyFlags & DFE_Flow) { 363 | switch(settings.FlowControl) { 364 | /*no flow control*/ 365 | case FLOW_OFF: 366 | commConfig.dcb.fOutxCtsFlow = FALSE; 367 | commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE; 368 | commConfig.dcb.fInX = FALSE; 369 | commConfig.dcb.fOutX = FALSE; 370 | break; 371 | /*software (XON/XOFF) flow control*/ 372 | case FLOW_XONXOFF: 373 | commConfig.dcb.fOutxCtsFlow = FALSE; 374 | commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE; 375 | commConfig.dcb.fInX = TRUE; 376 | commConfig.dcb.fOutX = TRUE; 377 | break; 378 | /*hardware flow control*/ 379 | case FLOW_HARDWARE: 380 | commConfig.dcb.fOutxCtsFlow = TRUE; 381 | commConfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; 382 | commConfig.dcb.fInX = FALSE; 383 | commConfig.dcb.fOutX = FALSE; 384 | break; 385 | } 386 | } 387 | 388 | //fill struct : COMMTIMEOUTS 389 | if (settingsDirtyFlags & DFE_TimeOut) { 390 | if (queryMode != QextSerialPort::EventDriven) { 391 | int millisec = settings.Timeout_Millisec; 392 | if (millisec == -1) { 393 | commTimeouts.ReadIntervalTimeout = MAXDWORD; 394 | commTimeouts.ReadTotalTimeoutConstant = 0; 395 | } else { 396 | commTimeouts.ReadIntervalTimeout = millisec; 397 | commTimeouts.ReadTotalTimeoutConstant = millisec; 398 | } 399 | commTimeouts.ReadTotalTimeoutMultiplier = 0; 400 | commTimeouts.WriteTotalTimeoutMultiplier = millisec; 401 | commTimeouts.WriteTotalTimeoutConstant = 0; 402 | } 403 | else { 404 | commTimeouts.ReadIntervalTimeout = MAXDWORD; 405 | commTimeouts.ReadTotalTimeoutMultiplier = 0; 406 | commTimeouts.ReadTotalTimeoutConstant = 0; 407 | commTimeouts.WriteTotalTimeoutMultiplier = 0; 408 | commTimeouts.WriteTotalTimeoutConstant = 0; 409 | } 410 | } 411 | 412 | 413 | if (settingsDirtyFlags & DFE_Settings_Mask) 414 | SetCommConfig(handle, &commConfig, sizeof(COMMCONFIG)); 415 | if ((settingsDirtyFlags & DFE_TimeOut)) 416 | SetCommTimeouts(handle, &commTimeouts); 417 | settingsDirtyFlags = 0; 418 | } 419 | -------------------------------------------------------------------------------- /qextserialport/src/qextserialport_unix.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Copyright (c) 2000-2003 Wayne Roth 3 | ** Copyright (c) 2004-2007 Stefan Sander 4 | ** Copyright (c) 2007 Michal Policht 5 | ** Copyright (c) 2008 Brandon Fosdick 6 | ** Copyright (c) 2009-2010 Liam Staskawicz 7 | ** Copyright (c) 2011 Debao Zhang 8 | ** All right reserved. 9 | ** Web: http://code.google.com/p/qextserialport/ 10 | ** 11 | ** Permission is hereby granted, free of charge, to any person obtaining 12 | ** a copy of this software and associated documentation files (the 13 | ** "Software"), to deal in the Software without restriction, including 14 | ** without limitation the rights to use, copy, modify, merge, publish, 15 | ** distribute, sublicense, and/or sell copies of the Software, and to 16 | ** permit persons to whom the Software is furnished to do so, subject to 17 | ** the following conditions: 18 | ** 19 | ** The above copyright notice and this permission notice shall be 20 | ** included in all copies or substantial portions of the Software. 21 | ** 22 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ** 30 | ****************************************************************************/ 31 | 32 | #include "qextserialport.h" 33 | #include "qextserialport_p.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | void QextSerialPortPrivate::platformSpecificInit() 46 | { 47 | fd = 0; 48 | readNotifier = 0; 49 | } 50 | 51 | /*! 52 | Standard destructor. 53 | */ 54 | void QextSerialPortPrivate::platformSpecificDestruct() 55 | { 56 | } 57 | 58 | static QString fullPortName(const QString &name) 59 | { 60 | if (name.startsWith(QLatin1Char('/'))) 61 | return name; 62 | return QLatin1String("/dev/")+name; 63 | } 64 | 65 | bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) 66 | { 67 | Q_Q(QextSerialPort); 68 | //note: linux 2.6.21 seems to ignore O_NDELAY flag 69 | if ((fd = ::open(fullPortName(port).toLatin1() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) { 70 | 71 | /*In the Private class, We can not call QIODevice::open()*/ 72 | q->setOpenMode(mode); // Flag the port as opened 73 | ::tcgetattr(fd, &oldTermios); // Save the old termios 74 | currentTermios = oldTermios; // Make a working copy 75 | ::cfmakeraw(¤tTermios); // Enable raw access 76 | 77 | /*set up other port settings*/ 78 | currentTermios.c_cflag |= CREAD|CLOCAL; 79 | currentTermios.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); 80 | currentTermios.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); 81 | currentTermios.c_oflag &= (~OPOST); 82 | currentTermios.c_cc[VMIN] = 0; 83 | #ifdef _POSIX_VDISABLE // Is a disable character available on this system? 84 | // Some systems allow for per-device disable-characters, so get the 85 | // proper value for the configured device 86 | const long vdisable = ::fpathconf(fd, _PC_VDISABLE); 87 | currentTermios.c_cc[VINTR] = vdisable; 88 | currentTermios.c_cc[VQUIT] = vdisable; 89 | currentTermios.c_cc[VSTART] = vdisable; 90 | currentTermios.c_cc[VSTOP] = vdisable; 91 | currentTermios.c_cc[VSUSP] = vdisable; 92 | #endif //_POSIX_VDISABLE 93 | settingsDirtyFlags = DFE_ALL; 94 | updatePortSettings(); 95 | 96 | if (queryMode == QextSerialPort::EventDriven) { 97 | readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q); 98 | q->connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_canRead())); 99 | } 100 | return true; 101 | } else { 102 | translateError(errno); 103 | return false; 104 | } 105 | } 106 | 107 | bool QextSerialPortPrivate::close_sys() 108 | { 109 | // Force a flush and then restore the original termios 110 | flush_sys(); 111 | // Using both TCSAFLUSH and TCSANOW here discards any pending input 112 | ::tcsetattr(fd, TCSAFLUSH | TCSANOW, &oldTermios); // Restore termios 113 | ::close(fd); 114 | if (readNotifier) { 115 | delete readNotifier; 116 | readNotifier = 0; 117 | } 118 | return true; 119 | } 120 | 121 | bool QextSerialPortPrivate::flush_sys() 122 | { 123 | ::tcdrain(fd); 124 | return true; 125 | } 126 | 127 | qint64 QextSerialPortPrivate::bytesAvailable_sys() const 128 | { 129 | int bytesQueued; 130 | if (::ioctl(fd, FIONREAD, &bytesQueued) == -1) { 131 | return (qint64)-1; 132 | } 133 | return bytesQueued; 134 | } 135 | 136 | /*! 137 | Translates a system-specific error code to a QextSerialPort error code. Used internally. 138 | */ 139 | void QextSerialPortPrivate::translateError(ulong error) 140 | { 141 | switch (error) { 142 | case EBADF: 143 | case ENOTTY: 144 | lastErr = E_INVALID_FD; 145 | break; 146 | case EINTR: 147 | lastErr = E_CAUGHT_NON_BLOCKED_SIGNAL; 148 | break; 149 | case ENOMEM: 150 | lastErr = E_NO_MEMORY; 151 | break; 152 | case EACCES: 153 | lastErr = E_PERMISSION_DENIED; 154 | break; 155 | case EAGAIN: 156 | lastErr = E_AGAIN; 157 | break; 158 | } 159 | } 160 | 161 | void QextSerialPortPrivate::setDtr_sys(bool set) 162 | { 163 | int status; 164 | ::ioctl(fd, TIOCMGET, &status); 165 | if (set) 166 | status |= TIOCM_DTR; 167 | else 168 | status &= ~TIOCM_DTR; 169 | ::ioctl(fd, TIOCMSET, &status); 170 | } 171 | 172 | void QextSerialPortPrivate::setRts_sys(bool set) 173 | { 174 | int status; 175 | ::ioctl(fd, TIOCMGET, &status); 176 | if (set) 177 | status |= TIOCM_RTS; 178 | else 179 | status &= ~TIOCM_RTS; 180 | ::ioctl(fd, TIOCMSET, &status); 181 | } 182 | 183 | unsigned long QextSerialPortPrivate::lineStatus_sys() 184 | { 185 | unsigned long Status=0, Temp=0; 186 | ::ioctl(fd, TIOCMGET, &Temp); 187 | if (Temp & TIOCM_CTS) Status |= LS_CTS; 188 | if (Temp & TIOCM_DSR) Status |= LS_DSR; 189 | if (Temp & TIOCM_RI) Status |= LS_RI; 190 | if (Temp & TIOCM_CD) Status |= LS_DCD; 191 | if (Temp & TIOCM_DTR) Status |= LS_DTR; 192 | if (Temp & TIOCM_RTS) Status |= LS_RTS; 193 | if (Temp & TIOCM_ST) Status |= LS_ST; 194 | if (Temp & TIOCM_SR) Status |= LS_SR; 195 | return Status; 196 | } 197 | 198 | /*! 199 | Reads a block of data from the serial port. This function will read at most maxSize bytes from 200 | the serial port and place them in the buffer pointed to by data. Return value is the number of 201 | bytes actually read, or -1 on error. 202 | 203 | \warning before calling this function ensure that serial port associated with this class 204 | is currently open (use isOpen() function to check if port is open). 205 | */ 206 | qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize) 207 | { 208 | int retVal = ::read(fd, data, maxSize); 209 | if (retVal == -1) 210 | lastErr = E_READ_FAILED; 211 | 212 | return retVal; 213 | } 214 | 215 | /*! 216 | Writes a block of data to the serial port. This function will write maxSize bytes 217 | from the buffer pointed to by data to the serial port. Return value is the number 218 | of bytes actually written, or -1 on error. 219 | 220 | \warning before calling this function ensure that serial port associated with this class 221 | is currently open (use isOpen() function to check if port is open). 222 | */ 223 | qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize) 224 | { 225 | int retVal = ::write(fd, data, maxSize); 226 | if (retVal == -1) 227 | lastErr = E_WRITE_FAILED; 228 | 229 | return (qint64)retVal; 230 | } 231 | 232 | static void setBaudRate2Termios(termios *config, int baudRate) 233 | { 234 | #ifdef CBAUD 235 | config->c_cflag &= (~CBAUD); 236 | config->c_cflag |= baudRate; 237 | #else 238 | ::cfsetispeed(config, baudRate); 239 | ::cfsetospeed(config, baudRate); 240 | #endif 241 | } 242 | 243 | /* 244 | All the platform settings was performed in this function. 245 | */ 246 | void QextSerialPortPrivate::updatePortSettings() 247 | { 248 | if (!q_func()->isOpen() || !settingsDirtyFlags) 249 | return; 250 | 251 | if (settingsDirtyFlags & DFE_BaudRate) { 252 | switch (settings.BaudRate) { 253 | case BAUD50: 254 | setBaudRate2Termios(¤tTermios, B50); 255 | break; 256 | case BAUD75: 257 | setBaudRate2Termios(¤tTermios, B75); 258 | break; 259 | case BAUD110: 260 | setBaudRate2Termios(¤tTermios, B110); 261 | break; 262 | case BAUD134: 263 | setBaudRate2Termios(¤tTermios, B134); 264 | break; 265 | case BAUD150: 266 | setBaudRate2Termios(¤tTermios, B150); 267 | break; 268 | case BAUD200: 269 | setBaudRate2Termios(¤tTermios, B200); 270 | break; 271 | case BAUD300: 272 | setBaudRate2Termios(¤tTermios, B300); 273 | break; 274 | case BAUD600: 275 | setBaudRate2Termios(¤tTermios, B600); 276 | break; 277 | case BAUD1200: 278 | setBaudRate2Termios(¤tTermios, B1200); 279 | break; 280 | case BAUD1800: 281 | setBaudRate2Termios(¤tTermios, B1800); 282 | break; 283 | case BAUD2400: 284 | setBaudRate2Termios(¤tTermios, B2400); 285 | break; 286 | case BAUD4800: 287 | setBaudRate2Termios(¤tTermios, B4800); 288 | break; 289 | case BAUD9600: 290 | setBaudRate2Termios(¤tTermios, B9600); 291 | break; 292 | case BAUD19200: 293 | setBaudRate2Termios(¤tTermios, B19200); 294 | break; 295 | case BAUD38400: 296 | setBaudRate2Termios(¤tTermios, B38400); 297 | break; 298 | case BAUD57600: 299 | setBaudRate2Termios(¤tTermios, B57600); 300 | break; 301 | #ifdef B76800 302 | case BAUD76800: 303 | setBaudRate2Termios(¤tTermios, B76800); 304 | break; 305 | #endif 306 | case BAUD115200: 307 | setBaudRate2Termios(¤tTermios, B115200); 308 | break; 309 | #if defined(B230400) && defined(B4000000) 310 | case BAUD230400: 311 | setBaudRate2Termios(¤tTermios, B230400); 312 | break; 313 | case BAUD460800: 314 | setBaudRate2Termios(¤tTermios, B460800); 315 | break; 316 | case BAUD500000: 317 | setBaudRate2Termios(¤tTermios, B500000); 318 | break; 319 | case BAUD576000: 320 | setBaudRate2Termios(¤tTermios, B576000); 321 | break; 322 | case BAUD921600: 323 | setBaudRate2Termios(¤tTermios, B921600); 324 | break; 325 | case BAUD1000000: 326 | setBaudRate2Termios(¤tTermios, B1000000); 327 | break; 328 | case BAUD1152000: 329 | setBaudRate2Termios(¤tTermios, B1152000); 330 | break; 331 | case BAUD1500000: 332 | setBaudRate2Termios(¤tTermios, B1500000); 333 | break; 334 | case BAUD2000000: 335 | setBaudRate2Termios(¤tTermios, B2000000); 336 | break; 337 | case BAUD2500000: 338 | setBaudRate2Termios(¤tTermios, B2500000); 339 | break; 340 | case BAUD3000000: 341 | setBaudRate2Termios(¤tTermios, B3000000); 342 | break; 343 | case BAUD3500000: 344 | setBaudRate2Termios(¤tTermios, B3500000); 345 | break; 346 | case BAUD4000000: 347 | setBaudRate2Termios(¤tTermios, B4000000); 348 | break; 349 | #endif 350 | #ifdef Q_OS_MAC 351 | default: 352 | setBaudRate2Termios(¤tTermios, settings.BaudRate); 353 | break; 354 | #endif 355 | } 356 | } 357 | if (settingsDirtyFlags & DFE_Parity) { 358 | switch (settings.Parity) { 359 | case PAR_SPACE: 360 | /*space parity not directly supported - add an extra data bit to simulate it*/ 361 | settingsDirtyFlags |= DFE_DataBits; 362 | break; 363 | case PAR_NONE: 364 | currentTermios.c_cflag &= (~PARENB); 365 | break; 366 | case PAR_EVEN: 367 | currentTermios.c_cflag &= (~PARODD); 368 | currentTermios.c_cflag |= PARENB; 369 | break; 370 | case PAR_ODD: 371 | currentTermios.c_cflag |= (PARENB|PARODD); 372 | break; 373 | } 374 | } 375 | /*must after Parity settings*/ 376 | if (settingsDirtyFlags & DFE_DataBits) { 377 | if (settings.Parity != PAR_SPACE) { 378 | currentTermios.c_cflag &= (~CSIZE); 379 | switch(settings.DataBits) { 380 | case DATA_5: 381 | currentTermios.c_cflag |= CS5; 382 | break; 383 | case DATA_6: 384 | currentTermios.c_cflag |= CS6; 385 | break; 386 | case DATA_7: 387 | currentTermios.c_cflag |= CS7; 388 | break; 389 | case DATA_8: 390 | currentTermios.c_cflag |= CS8; 391 | break; 392 | } 393 | } else { 394 | /*space parity not directly supported - add an extra data bit to simulate it*/ 395 | currentTermios.c_cflag &= ~(PARENB|CSIZE); 396 | switch(settings.DataBits) { 397 | case DATA_5: 398 | currentTermios.c_cflag |= CS6; 399 | break; 400 | case DATA_6: 401 | currentTermios.c_cflag |= CS7; 402 | break; 403 | case DATA_7: 404 | currentTermios.c_cflag |= CS8; 405 | break; 406 | case DATA_8: 407 | /*this will never happen, put here to Suppress an warning*/ 408 | break; 409 | } 410 | } 411 | } 412 | if (settingsDirtyFlags & DFE_StopBits) { 413 | switch (settings.StopBits) { 414 | case STOP_1: 415 | currentTermios.c_cflag &= (~CSTOPB); 416 | break; 417 | case STOP_2: 418 | currentTermios.c_cflag |= CSTOPB; 419 | break; 420 | } 421 | } 422 | if (settingsDirtyFlags & DFE_Flow) { 423 | switch(settings.FlowControl) { 424 | case FLOW_OFF: 425 | currentTermios.c_cflag &= (~CRTSCTS); 426 | currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); 427 | break; 428 | case FLOW_XONXOFF: 429 | /*software (XON/XOFF) flow control*/ 430 | currentTermios.c_cflag &= (~CRTSCTS); 431 | currentTermios.c_iflag |= (IXON|IXOFF|IXANY); 432 | break; 433 | case FLOW_HARDWARE: 434 | currentTermios.c_cflag |= CRTSCTS; 435 | currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); 436 | break; 437 | } 438 | } 439 | 440 | /*if any thing in currentTermios changed, flush*/ 441 | if (settingsDirtyFlags & DFE_Settings_Mask) 442 | ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); 443 | 444 | if (settingsDirtyFlags & DFE_TimeOut) { 445 | int millisec = settings.Timeout_Millisec; 446 | if (millisec == -1) { 447 | ::fcntl(fd, F_SETFL, O_NDELAY); 448 | } 449 | else { 450 | //O_SYNC should enable blocking ::write() 451 | //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) 452 | ::fcntl(fd, F_SETFL, O_SYNC); 453 | } 454 | ::tcgetattr(fd, ¤tTermios); 455 | currentTermios.c_cc[VTIME] = millisec/100; 456 | ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); 457 | } 458 | 459 | settingsDirtyFlags = 0; 460 | } 461 | -------------------------------------------------------------------------------- /main.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ProjectExplorer.Project.ActiveTarget 7 | 0 8 | 9 | 10 | ProjectExplorer.Project.EditorSettings 11 | 12 | true 13 | false 14 | true 15 | 16 | Cpp 17 | 18 | CppGlobal 19 | 20 | 21 | 22 | QmlJS 23 | 24 | QmlJSGlobal 25 | 26 | 27 | 2 28 | UTF-8 29 | false 30 | 4 31 | false 32 | true 33 | 1 34 | true 35 | 0 36 | true 37 | 0 38 | 8 39 | true 40 | 1 41 | true 42 | true 43 | true 44 | false 45 | 46 | 47 | 48 | ProjectExplorer.Project.PluginSettings 49 | 50 | 51 | 52 | ProjectExplorer.Project.Target.0 53 | 54 | Unnamed2 55 | Unnamed2 56 | {e3640aad-2ed0-4052-8ccd-d142f63e2d2e} 57 | 1 58 | 0 59 | 0 60 | 61 | 62 | 63 | true 64 | qmake 65 | 66 | QtProjectManager.QMakeBuildStep 67 | false 68 | true 69 | 70 | false 71 | 72 | 73 | true 74 | Make 75 | 76 | Qt4ProjectManager.MakeStep 77 | 78 | -w 79 | -r 80 | 81 | false 82 | 83 | 84 | 85 | 2 86 | Build 87 | 88 | ProjectExplorer.BuildSteps.Build 89 | 90 | 91 | 92 | true 93 | Make 94 | 95 | Qt4ProjectManager.MakeStep 96 | 97 | -w 98 | -r 99 | 100 | true 101 | clean 102 | 103 | 104 | 1 105 | Clean 106 | 107 | ProjectExplorer.BuildSteps.Clean 108 | 109 | 2 110 | false 111 | 112 | Debug 113 | 114 | Qt4ProjectManager.Qt4BuildConfiguration 115 | 2 116 | /home/cetec/Projects/Shock-Sensor-UI/MainUI/build 117 | true 118 | 119 | 120 | 121 | 122 | true 123 | qmake 124 | 125 | QtProjectManager.QMakeBuildStep 126 | false 127 | true 128 | 129 | false 130 | 131 | 132 | true 133 | Make 134 | 135 | Qt4ProjectManager.MakeStep 136 | 137 | -w 138 | -r 139 | 140 | false 141 | 142 | 143 | 144 | 2 145 | Build 146 | 147 | ProjectExplorer.BuildSteps.Build 148 | 149 | 150 | 151 | true 152 | Make 153 | 154 | Qt4ProjectManager.MakeStep 155 | 156 | -w 157 | -r 158 | 159 | true 160 | clean 161 | 162 | 163 | 1 164 | Clean 165 | 166 | ProjectExplorer.BuildSteps.Clean 167 | 168 | 2 169 | false 170 | 171 | Release 172 | 173 | Qt4ProjectManager.Qt4BuildConfiguration 174 | 0 175 | /home/cetec/Projects/gitHub/MainUI/build 176 | true 177 | 178 | 2 179 | 180 | 181 | 0 182 | Deploy 183 | 184 | ProjectExplorer.BuildSteps.Deploy 185 | 186 | 1 187 | Deploy locally 188 | 189 | ProjectExplorer.DefaultDeployConfiguration 190 | 191 | 1 192 | 193 | 194 | true 195 | 196 | false 197 | false 198 | false 199 | false 200 | true 201 | 0.01 202 | 10 203 | true 204 | 25 205 | 206 | true 207 | valgrind 208 | 209 | 0 210 | 1 211 | 2 212 | 3 213 | 4 214 | 5 215 | 6 216 | 7 217 | 8 218 | 9 219 | 10 220 | 11 221 | 12 222 | 13 223 | 14 224 | 225 | 2 226 | 227 | main 228 | 229 | Qt4ProjectManager.Qt4RunConfiguration:/home/cetec/Projects/gitHub/MainUI/main/main.pro 230 | 231 | main.pro 232 | false 233 | false 234 | 235 | 3768 236 | true 237 | false 238 | false 239 | false 240 | true 241 | 242 | 1 243 | 244 | 245 | 246 | ProjectExplorer.Project.TargetCount 247 | 1 248 | 249 | 250 | ProjectExplorer.Project.Updater.EnvironmentId 251 | {3d084ad8-4285-41eb-a7a8-33321b540c43} 252 | 253 | 254 | ProjectExplorer.Project.Updater.FileVersion 255 | 14 256 | 257 | 258 | --------------------------------------------------------------------------------