123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- /****************************************************************************
- ** Copyright (c) 2000-2003 Wayne Roth
- ** Copyright (c) 2004-2007 Stefan Sander
- ** Copyright (c) 2007 Michal Policht
- ** Copyright (c) 2008 Brandon Fosdick
- ** Copyright (c) 2009-2010 Liam Staskawicz
- ** Copyright (c) 2011 Debao Zhang
- ** All right reserved.
- ** Web: http://code.google.com/p/qextserialport/
- **
- ** Permission is hereby granted, free of charge, to any person obtaining
- ** a copy of this software and associated documentation files (the
- ** "Software"), to deal in the Software without restriction, including
- ** without limitation the rights to use, copy, modify, merge, publish,
- ** distribute, sublicense, and/or sell copies of the Software, and to
- ** permit persons to whom the Software is furnished to do so, subject to
- ** the following conditions:
- **
- ** The above copyright notice and this permission notice shall be
- ** included in all copies or substantial portions of the Software.
- **
- ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- **
- ****************************************************************************/
-
- #include "qextserialport.h"
- #include "qextserialport_p.h"
- #include <stdio.h>
- #include <QtCore/QDebug>
- #include <QtCore/QReadLocker>
- #include <QtCore/QWriteLocker>
-
- /*!
- \class PortSettings
-
- \brief The PortSettings class contain port settings
-
- Structure to contain port settings.
-
- \code
- BaudRateType BaudRate;
- DataBitsType DataBits;
- ParityType Parity;
- StopBitsType StopBits;
- FlowType FlowControl;
- long Timeout_Millisec;
- \endcode
- */
-
- QextSerialPortPrivate::QextSerialPortPrivate(QextSerialPort *q)
- :lock(QReadWriteLock::Recursive), q_ptr(q)
- {
- lastErr = E_NO_ERROR;
- settings.BaudRate = BAUD9600;
- settings.Parity = PAR_NONE;
- settings.FlowControl = FLOW_OFF;
- settings.DataBits = DATA_8;
- settings.StopBits = STOP_1;
- settings.Timeout_Millisec = 10;
- settingsDirtyFlags = DFE_ALL;
-
- platformSpecificInit();
- }
-
- QextSerialPortPrivate::~QextSerialPortPrivate()
- {
- platformSpecificDestruct();
- }
-
- void QextSerialPortPrivate::setBaudRate(BaudRateType baudRate, bool update)
- {
- switch (baudRate) {
- #ifdef Q_OS_WIN
- //Windows Special
- case BAUD14400:
- case BAUD56000:
- case BAUD128000:
- case BAUD256000:
- QESP_PORTABILITY_WARNING()<<"QextSerialPort Portability Warning: POSIX does not support baudRate:"<<baudRate;
- #elif defined(Q_OS_UNIX)
- //Unix Special
- case BAUD50:
- case BAUD75:
- case BAUD134:
- case BAUD150:
- case BAUD200:
- case BAUD1800:
- # ifdef B76800
- case BAUD76800:
- # endif
- # if defined(B230400) && defined(B4000000)
- case BAUD230400:
- case BAUD460800:
- case BAUD500000:
- case BAUD576000:
- case BAUD921600:
- case BAUD1000000:
- case BAUD1152000:
- case BAUD1500000:
- case BAUD2000000:
- case BAUD2500000:
- case BAUD3000000:
- case BAUD3500000:
- case BAUD4000000:
- # endif
- QESP_PORTABILITY_WARNING()<<"QextSerialPort Portability Warning: Windows does not support baudRate:"<<baudRate;
- #endif
- case BAUD110:
- case BAUD300:
- case BAUD600:
- case BAUD1200:
- case BAUD2400:
- case BAUD4800:
- case BAUD9600:
- case BAUD19200:
- case BAUD38400:
- case BAUD57600:
- case BAUD115200:
- #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
- default:
- #endif
- settings.BaudRate = baudRate;
- settingsDirtyFlags |= DFE_BaudRate;
- if (update && q_func()->isOpen())
- updatePortSettings();
- break;
- #if !(defined(Q_OS_WIN) || defined(Q_OS_MAC))
- default:
- QESP_WARNING()<<"QextSerialPort does not support baudRate:"<<baudRate;
- #endif
- }
- }
-
- void QextSerialPortPrivate::setParity(ParityType parity, bool update)
- {
- switch (parity) {
- case PAR_SPACE:
- if (settings.DataBits == DATA_8) {
- #ifdef Q_OS_WIN
- QESP_PORTABILITY_WARNING("QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
- #else
- QESP_WARNING("Space parity with 8 data bits is not supported by POSIX systems.");
- #endif
- }
- break;
-
- #ifdef Q_OS_WIN
- /*mark parity - WINDOWS ONLY*/
- case PAR_MARK:
- QESP_PORTABILITY_WARNING("QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems");
- break;
- #endif
-
- case PAR_NONE:
- case PAR_EVEN:
- case PAR_ODD:
- break;
- default:
- QESP_WARNING()<<"QextSerialPort does not support Parity:" << parity;
- }
-
- settings.Parity = parity;
- settingsDirtyFlags |= DFE_Parity;
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
- void QextSerialPortPrivate::setDataBits(DataBitsType dataBits, bool update)
- {
- switch(dataBits) {
-
- case DATA_5:
- if (settings.StopBits == STOP_2) {
- QESP_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
- } else {
- settings.DataBits = dataBits;
- settingsDirtyFlags |= DFE_DataBits;
- }
- break;
-
- case DATA_6:
- #ifdef Q_OS_WIN
- if (settings.StopBits == STOP_1_5) {
- QESP_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
- }
- else
- #endif
- {
- settings.DataBits = dataBits;
- settingsDirtyFlags |= DFE_DataBits;
- }
- break;
-
- case DATA_7:
- #ifdef Q_OS_WIN
- if (settings.StopBits == STOP_1_5) {
- QESP_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
- }
- else
- #endif
- {
- settings.DataBits = dataBits;
- settingsDirtyFlags |= DFE_DataBits;
- }
- break;
-
- case DATA_8:
- #ifdef Q_OS_WIN
- if (settings.StopBits == STOP_1_5) {
- QESP_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
- }
- else
- #endif
- {
- settings.DataBits = dataBits;
- settingsDirtyFlags |= DFE_DataBits;
- }
- break;
- default:
- QESP_WARNING()<<"QextSerialPort does not support Data bits:"<<dataBits;
- }
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
- void QextSerialPortPrivate::setStopBits(StopBitsType stopBits, bool update)
- {
- switch (stopBits) {
-
- /*one stop bit*/
- case STOP_1:
- settings.StopBits = stopBits;
- settingsDirtyFlags |= DFE_StopBits;
- break;
-
- #ifdef Q_OS_WIN
- /*1.5 stop bits*/
- case STOP_1_5:
- QESP_PORTABILITY_WARNING("QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
- if (settings.DataBits != DATA_5) {
- QESP_WARNING("QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
- } else {
- settings.StopBits = stopBits;
- settingsDirtyFlags |= DFE_StopBits;
- }
- break;
- #endif
-
- /*two stop bits*/
- case STOP_2:
- if (settings.DataBits == DATA_5) {
- QESP_WARNING("QextSerialPort: 2 stop bits cannot be used with 5 data bits");
- } else {
- settings.StopBits = stopBits;
- settingsDirtyFlags |= DFE_StopBits;
- }
- break;
- default:
- QESP_WARNING()<<"QextSerialPort does not support stop bits: "<<stopBits;
- }
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
- void QextSerialPortPrivate::setFlowControl(FlowType flow, bool update)
- {
- settings.FlowControl = flow;
- settingsDirtyFlags |= DFE_Flow;
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
- void QextSerialPortPrivate::setTimeout(long millisec, bool update)
- {
- settings.Timeout_Millisec = millisec;
- settingsDirtyFlags |= DFE_TimeOut;
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
- void QextSerialPortPrivate::setPortSettings(const PortSettings &settings, bool update)
- {
- setBaudRate(settings.BaudRate, false);
- setDataBits(settings.DataBits, false);
- setStopBits(settings.StopBits, false);
- setParity(settings.Parity, false);
- setFlowControl(settings.FlowControl, false);
- setTimeout(settings.Timeout_Millisec, false);
- settingsDirtyFlags = DFE_ALL;
- if (update && q_func()->isOpen())
- updatePortSettings();
- }
-
-
- void QextSerialPortPrivate::_q_canRead()
- {
- qint64 maxSize = bytesAvailable_sys();
- if (maxSize > 0) {
- char *writePtr = readBuffer.reserve(size_t(maxSize));
- qint64 bytesRead = readData_sys(writePtr, maxSize);
- if (bytesRead < maxSize)
- readBuffer.chop(maxSize - bytesRead);
- Q_Q(QextSerialPort);
- Q_EMIT q->readyRead();
- }
- }
-
- /*! \class QextSerialPort
-
- \brief The QextSerialPort class encapsulates a serial port on both POSIX and Windows systems.
-
- \section1 Usage
- QextSerialPort offers both a polling and event driven API. Event driven
- is typically easier to use, since you never have to worry about checking
- for new data.
-
- \bold Example
- \code
- QextSerialPort *port = new QextSerialPort("COM1");
- connect(port, SIGNAL(readyRead()), myClass, SLOT(onDataAvailable()));
- port->open();
-
- void MyClass::onDataAvailable()
- {
- QByteArray data = port->readAll();
- processNewData(usbdata);
- }
- \endcode
-
- \section1 Compatibility
- The user will be notified of errors and possible portability conflicts at run-time
- by default.
-
- For example, if a application has used BAUD1800, when it is runing under unix, you
- will get following message.
-
- \code
- QextSerialPort Portability Warning: Windows does not support baudRate:1800
- \endcode
-
- This behavior can be turned off by defining macro QESP_NO_WARN (to turn off all warnings)
- or QESP_NO_PORTABILITY_WARN (to turn off portability warnings) in the project.
-
-
- \bold Author: Stefan Sander, Michal Policht, Brandon Fosdick, Liam Staskawicz, Debao Zhang
- */
-
- /*!
- \enum QextSerialPort::QueryMode
-
- This enum type specifies query mode used in a serial port:
-
- \value Polling
- asynchronously read and write
- \value EventDriven
- synchronously read and write
- */
-
- /*!
- \fn void QextSerialPort::dsrChanged(bool status)
- This signal is emitted whenever dsr line has changed its state. You may
- use this signal to check if device is connected.
-
- \a status true when DSR signal is on, false otherwise.
- */
-
-
- /*!
- \fn QueryMode QextSerialPort::queryMode() const
- Get query mode.
- */
-
- /*!
- Default constructor. Note that the name of the device used by a QextSerialPort is dependent on
- your OS. Possible naming conventions and their associated OS are:
-
- \code
-
- OS Constant Used By Naming Convention
- ------------- ------------- ------------------------
- Q_OS_WIN Windows COM1, COM2
- Q_OS_IRIX SGI/IRIX /dev/ttyf1, /dev/ttyf2
- Q_OS_HPUX HP-UX /dev/tty1p0, /dev/tty2p0
- Q_OS_SOLARIS SunOS/Slaris /dev/ttya, /dev/ttyb
- Q_OS_OSF Digital UNIX /dev/tty01, /dev/tty02
- Q_OS_FREEBSD FreeBSD /dev/ttyd0, /dev/ttyd1
- Q_OS_OPENBSD OpenBSD /dev/tty00, /dev/tty01
- Q_OS_LINUX Linux /dev/ttyS0, /dev/ttyS1
- <none> /dev/ttyS0, /dev/ttyS1
- \endcode
-
- This constructor assigns the device name to the name of the first port on the specified system.
- See the other constructors if you need to open a different port. Default \a mode is EventDriven.
- As a subclass of QObject, \a parent can be specified.
- */
-
- QextSerialPort::QextSerialPort(QextSerialPort::QueryMode mode, QObject *parent)
- : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this))
- {
- #ifdef Q_OS_WIN
- setPortName(QLatin1String("COM1"));
-
- #elif defined(Q_OS_IRIX)
- setPortName(QLatin1String("/dev/ttyf1"));
-
- #elif defined(Q_OS_HPUX)
- setPortName(QLatin1String("/dev/tty1p0"));
-
- #elif defined(Q_OS_SOLARIS)
- setPortName(QLatin1String("/dev/ttya"));
-
- #elif defined(Q_OS_OSF) //formally DIGITAL UNIX
- setPortName(QLatin1String("/dev/tty01"));
-
- #elif defined(Q_OS_FREEBSD)
- setPortName(QLatin1String("/dev/ttyd1"));
-
- #elif defined(Q_OS_OPENBSD)
- setPortName(QLatin1String("/dev/tty00"));
-
- #else
- setPortName(QLatin1String("/dev/ttyS0"));
- #endif
- setQueryMode(mode);
- }
-
- /*!
- Constructs a serial port attached to the port specified by name.
- \a name is the name of the device, which is windowsystem-specific,
- e.g."COM1" or "/dev/ttyS0". \a mode
- */
- QextSerialPort::QextSerialPort(const QString &name, QextSerialPort::QueryMode mode, QObject *parent)
- : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this))
- {
- setQueryMode(mode);
- setPortName(name);
- }
-
- /*!
- Constructs a port with default name and specified \a settings.
- */
- QextSerialPort::QextSerialPort(const PortSettings &settings, QextSerialPort::QueryMode mode, QObject *parent)
- : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this))
- {
- Q_D(QextSerialPort);
- setQueryMode(mode);
- d->setPortSettings(settings);
- }
-
- /*!
- Constructs a port with specified \a name , \a mode and \a settings.
- */
- QextSerialPort::QextSerialPort(const QString &name, const PortSettings &settings, QextSerialPort::QueryMode mode, QObject *parent)
- : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this))
- {
- Q_D(QextSerialPort);
- setPortName(name);
- setQueryMode(mode);
- d->setPortSettings(settings);
- }
-
- /*!
- Opens a serial port and sets its OpenMode to \a mode.
- Note that this function does not specify which device to open.
- Returns true if successful; otherwise returns false.This function has no effect
- if the port associated with the class is already open. The port is also
- configured to the current settings, as stored in the settings structure.
- */
- bool QextSerialPort::open(OpenMode mode)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (mode != QIODevice::NotOpen && !isOpen())
- d->open_sys(mode);
-
- return isOpen();
- }
-
-
- /*! \reimp
- Closes a serial port. This function has no effect if the serial port associated with the class
- is not currently open.
- */
- void QextSerialPort::close()
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (isOpen()) {
- // Be a good QIODevice and call QIODevice::close() before really close()
- // so the aboutToClose() signal is emitted at the proper time
- QIODevice::close(); // mark ourselves as closed
- d->close_sys();
- d->readBuffer.clear();
- }
- }
-
- /*!
- Flushes all pending I/O to the serial port. This function has no effect if the serial port
- associated with the class is not currently open.
- */
- void QextSerialPort::flush()
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (isOpen())
- d->flush_sys();
- }
-
- /*! \reimp
- Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
- the port is not currently open, or -1 on error.
- */
- qint64 QextSerialPort::bytesAvailable() const
- {
- QWriteLocker locker(&d_func()->lock);
- if (isOpen()) {
- qint64 bytes = d_func()->bytesAvailable_sys();
- if (bytes != -1) {
- return bytes + d_func()->readBuffer.size()
- + QIODevice::bytesAvailable();
- }
- return -1;
- }
- return 0;
- }
-
- /*! \reimp
-
- */
- bool QextSerialPort::canReadLine() const
- {
- QReadLocker locker(&d_func()->lock);
- return QIODevice::canReadLine() || d_func()->readBuffer.canReadLine();
- }
-
- /*!
- * Set desired serial communication handling style. You may choose from polling
- * or event driven approach. This function does nothing when port is open; to
- * apply changes port must be reopened.
- *
- * In event driven approach read() and write() functions are acting
- * asynchronously. They return immediately and the operation is performed in
- * the background, so they doesn't freeze the calling thread.
- * To determine when operation is finished, QextSerialPort runs separate thread
- * and monitors serial port events. Whenever the event occurs, adequate signal
- * is emitted.
- *
- * When polling is set, read() and write() are acting synchronously. Signals are
- * not working in this mode and some functions may not be available. The advantage
- * of polling is that it generates less overhead due to lack of signals emissions
- * and it doesn't start separate thread to monitor events.
- *
- * Generally event driven approach is more capable and friendly, although some
- * applications may need as low overhead as possible and then polling comes.
- *
- * \a mode query mode.
- */
- void QextSerialPort::setQueryMode(QueryMode mode)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (mode != d->queryMode)
- d->queryMode = mode;
- }
-
- /*!
- Sets the \a name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0".
- */
- void QextSerialPort::setPortName(const QString &name)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- d->port = name;
- }
-
- /*!
- Returns the name set by setPortName().
- */
- QString QextSerialPort::portName() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->port;
- }
-
- QextSerialPort::QueryMode QextSerialPort::queryMode() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->queryMode;
- }
-
- /*!
- Reads all available data from the device, and returns it as a QByteArray.
- This function has no way of reporting errors; returning an empty QByteArray()
- can mean either that no data was currently available for reading, or that an error occurred.
- */
- QByteArray QextSerialPort::readAll()
- {
- int avail = this->bytesAvailable();
- return (avail > 0) ? this->read(avail) : QByteArray();
- }
-
- /*!
- Returns the baud rate of the serial port. For a list of possible return values see
- the definition of the enum BaudRateType.
- */
- BaudRateType QextSerialPort::baudRate() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->settings.BaudRate;
- }
-
- /*!
- Returns the number of data bits used by the port. For a list of possible values returned by
- this function, see the definition of the enum DataBitsType.
- */
- DataBitsType QextSerialPort::dataBits() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->settings.DataBits;
- }
-
- /*!
- Returns the type of parity used by the port. For a list of possible values returned by
- this function, see the definition of the enum ParityType.
- */
- ParityType QextSerialPort::parity() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->settings.Parity;
- }
-
- /*!
- Returns the number of stop bits used by the port. For a list of possible return values, see
- the definition of the enum StopBitsType.
- */
- StopBitsType QextSerialPort::stopBits() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->settings.StopBits;
- }
-
- /*!
- Returns the type of flow control used by the port. For a list of possible values returned
- by this function, see the definition of the enum FlowType.
- */
- FlowType QextSerialPort::flowControl() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->settings.FlowControl;
- }
-
- /*!
- \reimp
- Returns true if device is sequential, otherwise returns false. Serial port is sequential device
- so this function always returns true. Check QIODevice::isSequential() documentation for more
- information.
- */
- bool QextSerialPort::isSequential() const
- {
- return true;
- }
-
- /*!
- Return the error number, or 0 if no error occurred.
- */
- ulong QextSerialPort::lastError() const
- {
- QReadLocker locker(&d_func()->lock);
- return d_func()->lastErr;
- }
-
- /*!
- Returns the line status as stored by the port function. This function will retrieve the states
- of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
- can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
- long with specific bits indicating which lines are high. The following constants should be used
- to examine the states of individual lines:
-
- \code
- Mask Line
- ------ ----
- LS_CTS CTS
- LS_DSR DSR
- LS_DCD DCD
- LS_RI RI
- LS_RTS RTS (POSIX only)
- LS_DTR DTR (POSIX only)
- LS_ST Secondary TXD (POSIX only)
- LS_SR Secondary RXD (POSIX only)
- \endcode
-
- This function will return 0 if the port associated with the class is not currently open.
- */
- unsigned long QextSerialPort::lineStatus()
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (isOpen())
- return d->lineStatus_sys();
- return 0;
- }
-
- /*!
- Returns a human-readable description of the last device error that occurred.
- */
- QString QextSerialPort::errorString()
- {
- Q_D(QextSerialPort);
- QReadLocker locker(&d->lock);
- switch(d->lastErr) {
- case E_NO_ERROR:
- return tr("No Error has occurred");
- case E_INVALID_FD:
- return tr("Invalid file descriptor (port was not opened correctly)");
- case E_NO_MEMORY:
- return tr("Unable to allocate memory tables (POSIX)");
- case E_CAUGHT_NON_BLOCKED_SIGNAL:
- return tr("Caught a non-blocked signal (POSIX)");
- case E_PORT_TIMEOUT:
- return tr("Operation timed out (POSIX)");
- case E_INVALID_DEVICE:
- return tr("The file opened by the port is not a valid device");
- case E_BREAK_CONDITION:
- return tr("The port detected a break condition");
- case E_FRAMING_ERROR:
- return tr("The port detected a framing error (usually caused by incorrect baud rate settings)");
- case E_IO_ERROR:
- return tr("There was an I/O error while communicating with the port");
- case E_BUFFER_OVERRUN:
- return tr("Character buffer overrun");
- case E_RECEIVE_OVERFLOW:
- return tr("Receive buffer overflow");
- case E_RECEIVE_PARITY_ERROR:
- return tr("The port detected a parity error in the received data");
- case E_TRANSMIT_OVERFLOW:
- return tr("Transmit buffer overflow");
- case E_READ_FAILED:
- return tr("General read operation failure");
- case E_WRITE_FAILED:
- return tr("General write operation failure");
- case E_FILE_NOT_FOUND:
- return tr("The %1 file doesn't exists").arg(this->portName());
- case E_PERMISSION_DENIED:
- return tr("Permission denied");
- case E_AGAIN:
- return tr("Device is already locked");
- default:
- return tr("Unknown error: %1").arg(d->lastErr);
- }
- }
-
- /*!
- Destructs the QextSerialPort object.
- */
- QextSerialPort::~QextSerialPort()
- {
- if (isOpen())
- close();
-
- delete d_ptr;
- }
-
- /*!
- Sets the flow control used by the port to \a flow. Possible values of flow are:
- \code
- FLOW_OFF No flow control
- FLOW_HARDWARE Hardware (RTS/CTS) flow control
- FLOW_XONXOFF Software (XON/XOFF) flow control
- \endcode
- */
- void QextSerialPort::setFlowControl(FlowType flow)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.FlowControl != flow)
- d->setFlowControl(flow, true);
- }
-
- /*!
- Sets the parity associated with the serial port to \a parity. The possible values of parity are:
- \code
- PAR_SPACE Space Parity
- PAR_MARK Mark Parity
- PAR_NONE No Parity
- PAR_EVEN Even Parity
- PAR_ODD Odd Parity
- \endcode
- */
- void QextSerialPort::setParity(ParityType parity)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.Parity != parity)
- d->setParity(parity, true);
- }
-
- /*!
- Sets the number of data bits used by the serial port to \a dataBits. Possible values of dataBits are:
- \code
- DATA_5 5 data bits
- DATA_6 6 data bits
- DATA_7 7 data bits
- DATA_8 8 data bits
- \endcode
-
- \bold note:
- This function is subject to the following restrictions:
- \list
- \o 5 data bits cannot be used with 2 stop bits.
- \o 1.5 stop bits can only be used with 5 data bits.
- \o 8 data bits cannot be used with space parity on POSIX systems.
- \endlist
- */
- void QextSerialPort::setDataBits(DataBitsType dataBits)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.DataBits != dataBits)
- d->setDataBits(dataBits, true);
- }
-
- /*!
- Sets the number of stop bits used by the serial port to \a stopBits. Possible values of stopBits are:
- \code
- STOP_1 1 stop bit
- STOP_1_5 1.5 stop bits
- STOP_2 2 stop bits
- \endcode
-
- \bold note:
- This function is subject to the following restrictions:
- \list
- \o 2 stop bits cannot be used with 5 data bits.
- \o 1.5 stop bits cannot be used with 6 or more data bits.
- \o POSIX does not support 1.5 stop bits.
- \endlist
- */
- void QextSerialPort::setStopBits(StopBitsType stopBits)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.StopBits != stopBits)
- d->setStopBits(stopBits, true);
- }
-
- /*!
- Sets the baud rate of the serial port to \a baudRate. Note that not all rates are applicable on
- all platforms. The following table shows translations of the various baud rate
- constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
- are speeds that are usable on both Windows and POSIX.
- \code
-
- RATE Windows Speed POSIX Speed
- ----------- ------------- -----------
- BAUD50 X 50
- BAUD75 X 75
- *BAUD110 110 110
- BAUD134 X 134.5
- BAUD150 X 150
- BAUD200 X 200
- *BAUD300 300 300
- *BAUD600 600 600
- *BAUD1200 1200 1200
- BAUD1800 X 1800
- *BAUD2400 2400 2400
- *BAUD4800 4800 4800
- *BAUD9600 9600 9600
- BAUD14400 14400 X
- *BAUD19200 19200 19200
- *BAUD38400 38400 38400
- BAUD56000 56000 X
- *BAUD57600 57600 57600
- BAUD76800 X 76800
- *BAUD115200 115200 115200
- BAUD128000 128000 X
- BAUD230400 X 230400
- BAUD256000 256000 X
- BAUD460800 X 460800
- BAUD500000 X 500000
- BAUD576000 X 576000
- BAUD921600 X 921600
- BAUD1000000 X 1000000
- BAUD1152000 X 1152000
- BAUD1500000 X 1500000
- BAUD2000000 X 2000000
- BAUD2500000 X 2500000
- BAUD3000000 X 3000000
- BAUD3500000 X 3500000
- BAUD4000000 X 4000000
- \endcode
- */
-
- void QextSerialPort::setBaudRate(BaudRateType baudRate)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.BaudRate != baudRate)
- d->setBaudRate(baudRate, true);
- }
-
- /*!
- For Unix:
-
- Sets the read and write timeouts for the port to \a millisec milliseconds.
- Note that this is a per-character timeout, i.e. the port will wait this long for each
- individual character, not for the whole read operation. This timeout also applies to the
- bytesWaiting() function.
-
- \bold note:
- POSIX does not support millisecond-level control for I/O timeout values. Any
- timeout set using this function will be set to the next lowest tenth of a second for
- the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds
- will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
- writing the port. However millisecond-level control is allowed by the select() system call,
- so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
- the purpose of detecting available bytes in the read buffer.
-
- For Windows:
-
- Sets the read and write timeouts for the port to \a millisec milliseconds.
- Setting 0 indicates that timeouts are not used for read nor write operations;
- however read() and write() functions will still block. Set -1 to provide
- non-blocking behaviour (read() and write() will return immediately).
-
- \bold note: this function does nothing in event driven mode.
- */
- void QextSerialPort::setTimeout(long millisec)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (d->settings.Timeout_Millisec != millisec)
- d->setTimeout(millisec, true);
- }
-
- /*!
- Sets DTR line to the requested state (\a set default to high). This function will have no effect if
- the port associated with the class is not currently open.
- */
- void QextSerialPort::setDtr(bool set)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (isOpen())
- d->setDtr_sys(set);
- }
-
- /*!
- Sets RTS line to the requested state \a set (high by default).
- This function will have no effect if
- the port associated with the class is not currently open.
- */
- void QextSerialPort::setRts(bool set)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- if (isOpen())
- d->setRts_sys(set);
- }
-
- /*! \reimp
- Reads a block of data from the serial port. This function will read at most maxlen bytes from
- the serial port and place them in the buffer pointed to by data. Return value is the number of
- bytes actually read, or -1 on error.
-
- \warning before calling this function ensure that serial port associated with this class
- is currently open (use isOpen() function to check if port is open).
- */
- qint64 QextSerialPort::readData(char *data, qint64 maxSize)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- qint64 bytesFromBuffer = 0;
- if (!d->readBuffer.isEmpty()) {
- bytesFromBuffer = d->readBuffer.read(data, maxSize);
- if (bytesFromBuffer == maxSize)
- return bytesFromBuffer;
- }
- qint64 bytesFromDevice = d->readData_sys(data+bytesFromBuffer, maxSize-bytesFromBuffer);
- if (bytesFromDevice < 0)
- return -1;
- return bytesFromBuffer + bytesFromDevice;
- }
-
- /*! \reimp
- Writes a block of data to the serial port. This function will write len bytes
- from the buffer pointed to by data to the serial port. Return value is the number
- of bytes actually written, or -1 on error.
-
- \warning before calling this function ensure that serial port associated with this class
- is currently open (use isOpen() function to check if port is open).
- */
- qint64 QextSerialPort::writeData(const char *data, qint64 maxSize)
- {
- Q_D(QextSerialPort);
- QWriteLocker locker(&d->lock);
- return d->writeData_sys(data, maxSize);
- }
-
- #include "moc_qextserialport.cpp"
|