summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/EMPTYFILE0
-rw-r--r--include/serialport.h8
-rw-r--r--qserialdevice.pro6
-rw-r--r--src/serialport.cpp6
-rw-r--r--src/serialport_p.h168
-rw-r--r--src/serialport_p_win.cpp431
-rw-r--r--src/serialport_p_win.h26
-rw-r--r--src/serialportinfo.cpp11
-rw-r--r--src/serialportinfo_p.h10
-rw-r--r--src/serialportinfo_p_win.cpp16
-rw-r--r--src/src.pri30
-rw-r--r--tests/EMPTYFILE0
12 files changed, 591 insertions, 121 deletions
diff --git a/examples/EMPTYFILE b/examples/EMPTYFILE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/EMPTYFILE
diff --git a/include/serialport.h b/include/serialport.h
index f2f1963..e3ca603 100644
--- a/include/serialport.h
+++ b/include/serialport.h
@@ -20,7 +20,7 @@
class SerialPortInfo;
class SerialPortPrivate;
-class QSERIALDEVICE_EXPORT SerialPort : public QIODevice
+class SERIALPORT_EXPORT SerialPort : public QIODevice
{
Q_OBJECT
@@ -145,10 +145,10 @@ public:
bool setFlowControl(FlowControl flow);
FlowControl flowControl() const;
- void setDataInterval(int usecs);
+ bool setDataInterval(int usecs);
int dataInterval() const;
- void setReadTimeout(int msecs);
+ bool setReadTimeout(int msecs);
int readTimeout() const;
bool dtr() const;
@@ -159,7 +159,7 @@ public:
bool flush();
virtual bool reset();
- void setDataErrorPolicy(DataErrorPolicy policy = IgnorePolicy);
+ bool setDataErrorPolicy(DataErrorPolicy policy = IgnorePolicy);
DataErrorPolicy dataErrorPolicy() const;
PortError error() const;
diff --git a/qserialdevice.pro b/qserialdevice.pro
index 04dcfc2..f0a9cb0 100644
--- a/qserialdevice.pro
+++ b/qserialdevice.pro
@@ -4,10 +4,14 @@ QT -= gui
OBJECTS_DIR = build/obj
MOC_DIR = build/moc
-win32:DEFINES += QSERIALDEVICE_SHARED
+win32:DEFINES += SERIALPORT_BUILD SERIALPORT_SHARED
INCLUDEPATH += src include
+HEADERS += \
+ include/serialport.h \
+ include/serialportinfo.h
+
include(src/src.pri)
CONFIG(debug, debug|release) {
diff --git a/src/serialport.cpp b/src/serialport.cpp
index 73f6928..0e31631 100644
--- a/src/serialport.cpp
+++ b/src/serialport.cpp
@@ -113,7 +113,7 @@ SerialPort::FlowControl SerialPort::flowControl() const
}
-void SerialPort::setDataInterval(int usecs)
+bool SerialPort::setDataInterval(int usecs)
{
}
@@ -123,7 +123,7 @@ int SerialPort::dataInterval() const
}
-void SerialPort::setReadTimeout(int msecs)
+bool SerialPort::setReadTimeout(int msecs)
{
}
@@ -158,7 +158,7 @@ bool SerialPort::reset()
}
-void SerialPort::setDataErrorPolicy(DataErrorPolicy policy)
+bool SerialPort::setDataErrorPolicy(DataErrorPolicy policy)
{
}
diff --git a/src/serialport_p.h b/src/serialport_p.h
index 786e901..00ba929 100644
--- a/src/serialport_p.h
+++ b/src/serialport_p.h
@@ -11,143 +11,175 @@ class SerialPortPrivate
{
public:
SerialPortPrivate()
- : mInRate(SerialPort::UnknownRate)
- , mOutRate(SerialPort::UnknownRate)
- , mDataBits(SerialPort::UnknownDataBits)
- , mParity(SerialPort::UnknownParity)
- , mStopBits(SerialPort::UnknownStopBits)
- , mFlow(SerialPort::UnknownFlowControl)
- , mDataInterval(0)
- , mReadTimeout(0)
- , mPolicy(SerialPort::IgnorePolicy)
- , mError(SerialPort::NoError)
+ : m_inRate(SerialPort::UnknownRate)
+ , m_outRate(SerialPort::UnknownRate)
+ , m_dataBits(SerialPort::UnknownDataBits)
+ , m_parity(SerialPort::UnknownParity)
+ , m_stopBits(SerialPort::UnknownStopBits)
+ , m_flow(SerialPort::UnknownFlowControl)
+ , m_dataInterval(0)
+ , m_readTimeout(0)
+ , m_policy(SerialPort::IgnorePolicy)
+ , m_portError(SerialPort::NoError)
+ , m_oldSettingsIsSaved(false)
{}
- void setPort(const QString &port) { mPort = port; }
- const QString& port() const { return mPort; }
+ SerialPortPrivate(const QString &port)
+ : m_inRate(SerialPort::UnknownRate)
+ , m_outRate(SerialPort::UnknownRate)
+ , m_dataBits(SerialPort::UnknownDataBits)
+ , m_parity(SerialPort::UnknownParity)
+ , m_stopBits(SerialPort::UnknownStopBits)
+ , m_flow(SerialPort::UnknownFlowControl)
+ , m_dataInterval(0)
+ , m_readTimeout(0)
+ , m_policy(SerialPort::IgnorePolicy)
+ , m_portError(SerialPort::NoError)
+ , m_oldSettingsIsSaved(false)
+ {
- virtual bool open(QIODevice::OpenMode mode) = 0;
- virtual void close() = 0;
+ }
+
+ void setPort(const QString &port) { m_systemLocation = nativeToSystemLocation(port); }
+ QString port() const { return nativeFromSystemLocation(m_systemLocation); }
+
+ virtual bool open(QIODevice::OpenMode mode) {}
+ virtual void close() {}
bool setRate(qint32 rate, SerialPort::Directions dir) {
if (setNativeRate(rate, dir)) {
- mRate = rate;
+ if (SerialPort::Input & dir)
+ m_inRate = rate;
+ if (SerialPort::Output & dir)
+ m_outRate = rate;
return true;
}
return false;
}
qint32 rate(SerialPort::Directions dir) const {
- if (dir & Input)
- return (dir & Output) ? ((mInRate + mOutRate)/2) : mInRate;
- return mOutRate;
+ if (SerialPort::AllDirections == dir)
+ return (m_inRate == m_outRate) ? (m_inRate) : SerialPort::UnknownRate;
+ return (SerialPort::Input & dir) ? (m_inRate) : (m_outRate);
}
+
bool setDataBits(SerialPort::DataBits dataBits) {
if (setNativeDataBits(dataBits)) {
- mDataBits = dataBits;
+ m_dataBits = dataBits;
return true;
}
return false;
}
- SerialPort::DataBits dataBits() const { return mDataBits; }
+ SerialPort::DataBits dataBits() const { return m_dataBits; }
bool setParity(SerialPort::Parity parity) {
if (setNativeParity(parity)) {
- mParity = parity;
+ m_parity = parity;
return true;
}
return false;
}
- SerialPort::Parity parity() const { return mParity; }
+ SerialPort::Parity parity() const { return m_parity; }
bool setStopBits(SerialPort::StopBits stopBits) {
if (setNativeStopBits(stopBits)) {
- mStopBits = stopBits;
+ m_stopBits = stopBits;
return true;
}
return false;
}
- SerialPort::StopBits stopBits() const { return mStopBits; }
+ SerialPort::StopBits stopBits() const { return m_stopBits; }
bool setFlowControl(SerialPort::FlowControl flow) {
if (setNativeFlowControl(flow)) {
- mFlow = flow;
+ m_flow = flow;
return true;
}
return false;
}
- SerialPort::FlowControl flowControl() const { return mFlow; }
+ SerialPort::FlowControl flowControl() const { return m_flow; }
- void setDataInterval(int usecs) {
+ bool setDataInterval(int usecs) {
if (setNativeDataInterval(usecs)) {
- mDataInterval = usecs;
+ m_dataInterval = usecs;
return true;
}
return false;
}
- int dataInterval() const { return mDataInterval; }
+ int dataInterval() const { return m_dataInterval; }
- void setReadTimeout(int msecs) {
+ bool setReadTimeout(int msecs) {
if (setNativeReadTimeout(msecs)) {
- mReadTimeout = msecs;
+ m_readTimeout = msecs;
return true;
}
return false;
}
- int readTimeout() const { return mReadTimeout; }
+ int readTimeout() const { return m_readTimeout; }
- virtual bool dtr() const = 0;
- virtual bool rts() const = 0;
+ virtual bool dtr() const {}
+ virtual bool rts() const {}
- virtual SerialPort::Lines lines() const = 0;
+ virtual SerialPort::Lines lines() const {}
- virtual bool flush() = 0;
- virtual bool reset() = 0;
+ virtual bool flush() {}
+ virtual bool reset() {}
- void setDataErrorPolicy(SerialPort::DataErrorPolicy policy) {
+ bool setDataErrorPolicy(SerialPort::DataErrorPolicy policy) {
if (setNativeDataErrorPolicy(policy)) {
- mPolicy = policy;
+ m_policy = policy;
return true;
}
return false;
}
- SerialPort::DataErrorPolicy dataErrorPolicy() const { return mPolicy; }
+ SerialPort::DataErrorPolicy dataErrorPolicy() const { return m_policy; }
+
+ SerialPort::PortError error() const { return m_portError; }
+ void unsetError() { m_portError = SerialPort::NoError; }
- SerialPort::PortError error() const { return mError; }
- void unsetError() { mError = SerialPort::NoError; }
+ void setError(SerialPort::PortError error) { m_portError = error; }
- void setError(SerialPort::PortError error) { mError = error; }
+ virtual qint64 bytesAvailable() const {}
- virtual qint64 bytesAvailable() const = 0;
+ virtual qint64 read(char *data, qint64 len) {}
+ virtual qint64 write(const char *data, qint64 len) {}
+ virtual bool waitForReadOrWrite(int timeout,
+ bool checkRead, bool checkWrite,
+ bool *selectForRead, bool *selectForWrite) {}
- virtual qint64 read(char *data, qint64 len) = 0;
- virtual qint64 write(const char *data, qint64 len) = 0;
- virtual bool waitForReadyRead(int msec) = 0;
- virtual bool waitForBytesWritten(int msec) = 0;
protected:
//General (for any OS) private parameters
- QString mPort;
- qint32 mInRate;
- qint32 mOutRate;
- SerialPort::DataBits mDataBits;
- SerialPort::Parity mParity;
- SerialPort::StopBits mStopBits;
- SerialPort::FlowControl mFlow;
- int mDataInterval;
- int mReadTimeout;
- SerialPort::DataErrorPolicy mPolicy;
- SerialPort::PortError mError;
-
- virtual bool setNativeRate(int rate, SerialPort::Directions dir) = 0;
- virtual bool setNativeDataBits(SerialPort::DataBits dataBits) = 0;
- virtual bool setNativeParity(SerialPort::Parity parity) = 0;
- virtual bool setNativeStopBits(SerialPort::StopBits stopBits) = 0;
- virtual bool setNativeFlowControl(SerialPort::FlowControl flowControl) = 0;
- virtual bool setNativeDataErrorPolicy(SerialPort::DataErrorPolicy policy) = 0;
+ QString m_systemLocation;
+ qint32 m_inRate;
+ qint32 m_outRate;
+ SerialPort::DataBits m_dataBits;
+ SerialPort::Parity m_parity;
+ SerialPort::StopBits m_stopBits;
+ SerialPort::FlowControl m_flow;
+ int m_dataInterval;
+ int m_readTimeout;
+ SerialPort::DataErrorPolicy m_policy;
+ SerialPort::PortError m_portError;
+
+ bool m_oldSettingsIsSaved;
+
+ virtual QString nativeToSystemLocation(const QString &port) const {}
+ virtual QString nativeFromSystemLocation(const QString &location) const {}
+
+ virtual bool setNativeRate(qint32 rate, SerialPort::Directions dir) {}
+ virtual bool setNativeDataBits(SerialPort::DataBits dataBits) {}
+ virtual bool setNativeParity(SerialPort::Parity parity) {}
+ virtual bool setNativeStopBits(SerialPort::StopBits stopBits) {}
+ virtual bool setNativeFlowControl(SerialPort::FlowControl flowControl) {}
+
+ virtual bool setNativeDataInterval(int usecs) {}
+ virtual bool setNativeReadTimeout(int msecs) {}
+
+ virtual bool setNativeDataErrorPolicy(SerialPort::DataErrorPolicy policy) {}
virtual void detectDefaultSettings() {}
- virtual bool saveOldsettings() = 0;
- virtual bool restoreOldsettings() = 0;
+ virtual bool saveOldsettings() {}
+ virtual bool restoreOldsettings() {}
};
#endif // SERIALPORT_P_H
diff --git a/src/serialport_p_win.cpp b/src/serialport_p_win.cpp
index a236cad..96fbb5a 100644
--- a/src/serialport_p_win.cpp
+++ b/src/serialport_p_win.cpp
@@ -4,12 +4,43 @@
#include "serialport_p_win.h"
+#include <QtCore/QRegExp>
+
+#ifndef Q_CC_MSVC
+# include <ddk/ntddser.h>
+#else
+#ifndef IOCTL_SERIAL_GET_DTRRTS
+#define IOCTL_SERIAL_GET_DTRRTS \
+ CTL_CODE (FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#endif //Q_CC_MSVC
+
+#ifndef SERIAL_DTR_STATE
+# define SERIAL_DTR_STATE 0x00000001
+#endif
+
+#ifndef SERIAL_RTS_STATE
+# define SERIAL_RTS_STATE 0x00000002
+#endif
+
+#endif
+
/* Public */
SerialPortPrivateWin::SerialPortPrivateWin()
: SerialPortPrivate()
+ , m_descriptor(INVALID_HANDLE_VALUE)
{
+ size_t size = sizeof(DCB);
+ ::memset((void *)(&m_currDCB), 0, size);
+ ::memset((void *)(&m_oldDCB), 0, size);
+ size = sizeof(COMMTIMEOUTS);
+ ::memset((void *)(&m_currCommTimeouts), 0, size);
+ ::memset((void *)(&m_oldCommTimeouts), 0, size);
+ size = sizeof(OVERLAPPED);
+ ::memset((void *)(&m_ovRead), 0, size);
+ ::memset((void *)(&m_ovWrite), 0, size);
+ ::memset((void *)(&m_ovSelect), 0, size);
}
SerialPortPrivateWin::~SerialPortPrivateWin()
@@ -18,27 +49,122 @@ SerialPortPrivateWin::~SerialPortPrivateWin()
bool SerialPortPrivateWin::open(QIODevice::OpenMode mode)
{
-
+ DWORD access = 0;
+ DWORD sharing = 0;
+ bool rxflag = false;
+ bool txflag = false;
+
+ if (QIODevice::ReadOnly & mode) {
+ access |= GENERIC_READ; //sharing = FILE_SHARE_READ;
+ rxflag = true;
+ }
+ if (QIODevice::WriteOnly & mode) {
+ access |= GENERIC_WRITE; //sharing = FILE_SHARE_WRITE;
+ txflag = true;
+ }
+
+ QByteArray nativeFilePath = QByteArray((const char *)m_systemLocation.utf16(), m_systemLocation.size() * 2 + 1);
+ m_descriptor = ::CreateFile((const wchar_t*)nativeFilePath.constData(),
+ access,
+ sharing,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ 0);
+
+ if (INVALID_HANDLE_VALUE == m_descriptor) {
+ //
+ return false;
+ }
+
+ if (!saveOldsettings()) {
+ //
+ return false;
+ }
+
+ // prepareOtherOptions();
+
+ if (!updateDcb()) {
+ //
+ return false;
+ }
+
+ // Prepare timeouts.
+ /*
+ prepareCommTimeouts(SerialPortPrivateWin::ReadIntervalTimeout, MAXWORD);
+ prepareCommTimeouts(SerialPortPrivateWin::ReadTotalTimeoutMultiplier, 0);
+ prepareCommTimeouts(SerialPortPrivateWin::ReadTotalTimeoutConstant, 0);
+ prepareCommTimeouts(SerialPortPrivateWin::WriteTotalTimeoutMultiplier, 0);
+ prepareCommTimeouts(SerialPortPrivateWin::WriteTotalTimeoutConstant, 0);
+ */
+
+ if (!updateCommTimeouts()) {
+ //
+ return false;
+ }
+
+ // Disable autocalculate total read interval.
+ //this->isAutoCalcReadTimeoutConstant = false;
+
+ if (!createEvents(rxflag, txflag)) {
+ //
+ return false;
+ }
+
+ detectDefaultSettings();
+ return true;
}
void SerialPortPrivateWin::close()
{
-
+ restoreOldsettings();
+ ::CancelIo(m_descriptor);
+ ::CloseHandle(m_descriptor);
+ closeEvents();
+ m_descriptor = INVALID_HANDLE_VALUE;
}
bool SerialPortPrivateWin::dtr() const
{
-
+ return (SerialPort::Dtr && lines());
}
bool SerialPortPrivateWin::rts() const
{
-
+ return (SerialPort::Rts && lines());
}
SerialPort::Lines SerialPortPrivateWin::lines() const
{
-
+ DWORD modemStat = 0;
+ SerialPort::Lines result = 0;
+
+ if (0 == ::GetCommModemStatus(m_descriptor, &modemStat)) {
+ // Print error?
+ return result;
+ }
+
+ if (modemStat & MS_CTS_ON)
+ result |= SerialPort::Cts;
+ if (modemStat & MS_DSR_ON)
+ result |= SerialPort::Dsr;
+ if (modemStat & MS_RING_ON)
+ result |= SerialPort::Ri;
+ if (modemStat & MS_RLSD_ON)
+ result |= SerialPort::Dcd;
+
+ DWORD bytesReturned = 0;
+ if (::DeviceIoControl(m_descriptor, IOCTL_SERIAL_GET_DTRRTS, 0, 0,
+ &modemStat, sizeof(DWORD),
+ &bytesReturned, 0)) {
+
+ if (modemStat & SERIAL_DTR_STATE)
+ result |= SerialPort::Dtr;
+ if (modemStat & SERIAL_RTS_STATE)
+ result |= SerialPort::Rts;
+ }
+
+ return result;
}
bool SerialPortPrivateWin::flush()
@@ -63,7 +189,42 @@ qint64 SerialPortPrivateWin::read(char *data, qint64 len)
qint64 SerialPortPrivateWin::write(const char *data, qint64 len)
{
-
+ //if (!clear_overlapped(&m_ovWrite))
+ // return qint64(-1);
+
+ DWORD writeBytes = 0;
+ bool sucessResult = false;
+
+ if (::WriteFile(m_descriptor, (LPCVOID)data, (DWORD)len, &writeBytes, &m_ovWrite))
+ sucessResult = true;
+ else {
+ if (ERROR_IO_PENDING == ::GetLastError()) {
+ //not to loop the function, instead of setting INFINITE put 5000 milliseconds wait!
+ switch (::WaitForSingleObject(m_ovWrite.hEvent, 5000)) {
+ case WAIT_OBJECT_0: {
+ if (::GetOverlappedResult(m_descriptor, &m_ovWrite, &writeBytes, false))
+ sucessResult = true;
+ else {
+ // Print error?
+ ;
+ }
+ }
+ break;//WAIT_OBJECT_0
+ default:
+ //Print error ?
+ ;
+ }//switch (rc)
+ }
+ else {
+#if defined (NATIVESERIALENGINE_WIN_DEBUG)
+ qDebug() << "Windows: NativeSerialEnginePrivate::nativeWrite(const char *data, qint64 len) \n"
+ " -> function: ::GetLastError() returned: " << rc << ". Error! \n";
+#endif
+ ;
+ }
+ }
+
+ return (sucessResult) ? quint64(writeBytes) : qint64(-1);
}
bool SerialPortPrivateWin::waitForReadyRead(int msec)
@@ -76,73 +237,297 @@ bool SerialPortPrivateWin::waitForBytesWritten(int msec)
}
-// protected
+/* Protected */
-bool SerialPortPrivateWin::setNativeRate(qint32 rate, SerialPort::Directions dir)
+static const QString defaultPathPrefix = "\\\\.\\";
+
+QString SerialPortPrivateWin::nativeToSystemLocation(const QString &port) const
{
+ QString result;
+ if (!port.contains(defaultPathPrefix))
+ result.append(defaultPathPrefix);
+ result.append(port);
+ return result;
+}
+QString SerialPortPrivateWin::nativeFromSystemLocation(const QString &location) const
+{
+ QString result = location;
+ if (result.contains(defaultPathPrefix))
+ result.remove(defaultPathPrefix);
+ return result;
}
-bool SerialPortPrivateWin::setNativeDataBits(SerialPort::DataBits dataBits)
+bool SerialPortPrivateWin::setNativeRate(qint32 rate, SerialPort::Directions dir)
{
+ if ((SerialPort::UnknownRate == rate)
+ || (SerialPort::AllDirections != dir)) {
+ return false;
+ }
+ m_currDCB.BaudRate = DWORD(rate);
+ return (updateDcb());
+}
+bool SerialPortPrivateWin::setNativeDataBits(SerialPort::DataBits dataBits)
+{
+ if (SerialPort::UnknownDataBits == dataBits)
+ return false;
+
+ if ((SerialPort::Data5 == dataBits)
+ && (SerialPort::TwoStop == m_stopBits)) {
+ //
+ return false;
+ }
+ if ((SerialPort::Data6 == dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ //
+ return false;
+ }
+ if ((SerialPort::Data7 == dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ //
+ return false;
+ }
+ if ((SerialPort::Data8 == dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ //
+ return false;
+ }
+ m_currDCB.ByteSize = BYTE(dataBits);
+ return (updateDcb());
}
bool SerialPortPrivateWin::setNativeParity(SerialPort::Parity parity)
{
-
+ if (SerialPort::UnknownParity == parity)
+ return false;
+
+ m_currDCB.fParity = true;
+ switch (parity) {
+ case SerialPort::NoParity: {
+ m_currDCB.Parity = NOPARITY;
+ m_currDCB.fParity = false;
+ }
+ break;
+ case SerialPort::SpaceParity: m_currDCB.Parity = SPACEPARITY; break;
+ case SerialPort::MarkParity: m_currDCB.Parity = MARKPARITY; break;
+ case SerialPort::EvenParity: m_currDCB.Parity = EVENPARITY; break;
+ case SerialPort::OddParity: m_currDCB.Parity = ODDPARITY; break;
+ default: return false;
+ }
+ return (updateDcb());
}
bool SerialPortPrivateWin::setNativeStopBits(SerialPort::StopBits stopBits)
{
-
+ if (SerialPort::UnknownStopBits == stopBits)
+ return false;
+
+ if ((SerialPort::Data5 == m_dataBits)
+ && (SerialPort::TwoStop == m_stopBits)) {
+ return false;
+ }
+ if ((SerialPort::Data6 == m_dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ return false;
+ }
+ if ((SerialPort::Data7 == m_dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ return false;
+ }
+ if ((SerialPort::Data8 == m_dataBits)
+ && (SerialPort::OneAndHalfStop == m_stopBits)) {
+ return false;
+ }
+
+ switch (stopBits) {
+ case SerialPort::OneStop: m_currDCB.StopBits = ONESTOPBIT; break;
+ case SerialPort::OneAndHalfStop: m_currDCB.StopBits = ONE5STOPBITS; break;
+ case SerialPort::TwoStop: m_currDCB.StopBits = TWOSTOPBITS; break;
+ default: return false;
+ }
+ return (updateDcb());
}
bool SerialPortPrivateWin::setNativeFlowControl(SerialPort::FlowControl flow)
{
-
+ if (SerialPort::UnknownFlowControl == flow)
+ return false;
+
+ switch (flow) {
+ case SerialPort::NoFlowControl: {
+ m_currDCB.fOutxCtsFlow = false;
+ m_currDCB.fRtsControl = RTS_CONTROL_DISABLE;
+ m_currDCB.fInX = m_currDCB.fOutX = false;
+ }
+ break;
+ case SerialPort::SoftwareControl: {
+ m_currDCB.fOutxCtsFlow = false;
+ m_currDCB.fRtsControl = RTS_CONTROL_DISABLE;
+ m_currDCB.fInX = m_currDCB.fOutX = true;
+ }
+ break;
+ case SerialPort::HardwareControl: {
+ m_currDCB.fOutxCtsFlow = true;
+ m_currDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
+ m_currDCB.fInX = m_currDCB.fOutX = false;
+ }
+ break;
+ default: return false;
+ }
+ return (updateDcb());
}
-void SerialPortPrivateWin::setNativeDataInterval(int usecs)
+bool SerialPortPrivateWin::setNativeDataInterval(int usecs)
{
}
-void SerialPortPrivateWin::setNativeReadTimeout(int msecs)
+bool SerialPortPrivateWin::setNativeReadTimeout(int msecs)
{
}
-void SerialPortPrivateWin::setNativeDataErrorPolicy(SerialPort::DataErrorPolicy policy)
+bool SerialPortPrivateWin::setNativeDataErrorPolicy(SerialPort::DataErrorPolicy policy)
{
}
+bool SerialPortPrivateWin::waitForReadOrWrite(int timeout,
+ bool checkRead, bool checkWrite,
+ bool *selectForRead, bool *selectForWrite)
+{
+ if (checkRead && (bytesAvailable() > 0)) {
+ *selectForRead = true;
+ return 1;
+ }
+
+ //if (!clear_overlapped(&m_ovSelect))
+ // return int(-1);
+
+ DWORD oldEventMask = 0;
+ DWORD currEventMask = 0;
+
+ if (checkRead)
+ currEventMask |= EV_RXCHAR;
+ if (checkWrite)
+ currEventMask |= EV_TXEMPTY;
+
+ //save old mask
+ if (0 == ::GetCommMask(m_descriptor, &oldEventMask)) {
+ //Print error?
+ return -1;
+ }
+
+ if (currEventMask != (oldEventMask & currEventMask)) {
+ currEventMask |= oldEventMask;
+ //set mask
+ if(0 == ::SetCommMask(m_descriptor, currEventMask)) {
+ //Print error?
+ return -1;
+ }
+ }
+
+ currEventMask = 0;
+ bool selectResult = false;
+
+ if (::WaitCommEvent(m_descriptor, &currEventMask, &m_ovSelect))
+ selectResult = true;
+ else {
+ if (ERROR_IO_PENDING == ::GetLastError()) {
+ DWORD bytesTransferred = 0;
+ switch (::WaitForSingleObject(m_ovSelect.hEvent, (timeout < 0) ? 0 : timeout)) {
+ case WAIT_OBJECT_0: {
+ if (::GetOverlappedResult(m_descriptor, &m_ovSelect, &bytesTransferred, false))
+ selectResult = true;
+ else {
+ //Print error?
+ ;
+ }
+ }
+ break;
+ case WAIT_TIMEOUT:
+ //Print error?
+ ;
+ break;
+ default:
+ //Print error?
+ ;
+ }
+ }
+ else {
+ //Print error?
+ ;
+ }
+ }
+
+ if (selectResult) {
+ *selectForRead = (currEventMask & EV_RXCHAR)
+ && (checkRead)
+ && (bytesAvailable());
+ *selectForWrite = (currEventMask & EV_TXEMPTY) && (checkWrite);
+ }
+ ::SetCommMask(m_descriptor, oldEventMask); //rerair old mask
+ return int(selectResult);
+}
+
void SerialPortPrivateWin::detectDefaultSettings()
{
}
+// Used only in method SerialPortPrivateWin::open(SerialPort::OpenMode mode).
bool SerialPortPrivateWin::saveOldsettings()
{
-
+ DWORD confSize = sizeof(DCB);
+ if (0 == ::GetCommState(m_descriptor, &m_oldDCB))
+ return false;
+ ::memcpy((void *)(&m_currDCB), (const void *)(&m_oldDCB), confSize);
+
+ confSize = sizeof(COMMTIMEOUTS);
+ if (0 == ::GetCommTimeouts(m_descriptor, &m_oldCommTimeouts))
+ return false;
+ ::memcpy((void *)(&m_currCommTimeouts), (const void *)(&m_oldCommTimeouts), confSize);
+
+ m_oldSettingsIsSaved = true;
+ return true;
}
+// Used only in method SerialPortPrivateWin::close().
bool SerialPortPrivateWin::restoreOldsettings()
{
-
+ bool restoreResult = true;
+ if (m_oldSettingsIsSaved) {
+ m_oldSettingsIsSaved = false;
+ if (0 != ::GetCommState(m_descriptor, &m_oldDCB))
+ restoreResult = false;
+ if (0 == ::SetCommTimeouts(m_descriptor, &m_oldCommTimeouts))
+ restoreResult = false;
+ }
+ return restoreResult;
}
/* Private */
bool SerialPortPrivateWin::createEvents(bool rx, bool tx)
{
+ if (rx) { m_ovRead.hEvent = ::CreateEvent(0, false, false, 0); }
+ if (tx) { m_ovWrite.hEvent = ::CreateEvent(0, false, false, 0); }
+ m_ovSelect.hEvent = ::CreateEvent(0, false, false, 0);
+ return ((rx && (0 == m_ovRead.hEvent))
+ || (tx && (0 == m_ovWrite.hEvent))
+ || (0 == m_ovSelect.hEvent)) ? false : true;
}
-bool SerialPortPrivateWin::closeEvents() const
+void SerialPortPrivateWin::closeEvents() const
{
-
+ if (m_ovRead.hEvent)
+ ::CloseHandle(m_ovRead.hEvent);
+ if (m_ovWrite.hEvent)
+ ::CloseHandle(m_ovWrite.hEvent);
+ if (m_ovSelect.hEvent)
+ ::CloseHandle(m_ovSelect.hEvent);
}
void SerialPortPrivateWin::recalcTotalReadTimeoutConstant()
@@ -155,14 +540,14 @@ void SerialPortPrivateWin::prepareCommTimeouts(CommTimeouts cto, DWORD msecs)
}
-bool SerialPortPrivateWin::updateDcb()
+inline bool SerialPortPrivateWin::updateDcb()
{
-
+ return (0 != ::SetCommState(m_descriptor, &m_currDCB));
}
-bool SerialPortPrivateWin::updateCommTimeouts()
+inline bool SerialPortPrivateWin::updateCommTimeouts()
{
-
+ return (0 != ::SetCommTimeouts(m_descriptor, &m_currCommTimeouts));
}
diff --git a/src/serialport_p_win.h b/src/serialport_p_win.h
index 1712fba..9618e73 100644
--- a/src/serialport_p_win.h
+++ b/src/serialport_p_win.h
@@ -32,15 +32,23 @@ public:
virtual qint64 read(char *data, qint64 len);
virtual qint64 write(const char *data, qint64 len);
- virtual bool waitForReadyRead(int msec);
- virtual bool waitForBytesWritten(int msec);
+ virtual bool waitForReadOrWrite(int timeout,
+ bool checkRead, bool checkWrite,
+ bool *selectForRead, bool *selectForWrite);
protected:
+ virtual QString nativeToSystemLocation(const QString &port) const;
+ virtual QString nativeFromSystemLocation(const QString &location) const;
+
virtual bool setNativeRate(int rate, SerialPort::Directions dir);
virtual bool setNativeDataBits(SerialPort::DataBits dataBits);
virtual bool setNativeParity(SerialPort::Parity parity);
virtual bool setNativeStopBits(SerialPort::StopBits stopBits);
virtual bool setNativeFlowControl(SerialPort::FlowControl flowControl);
+
+ virtual bool setNativeDataInterval(int usecs);
+ virtual bool setNativeReadTimeout(int msecs);
+
virtual bool setNativeDataErrorPolicy(SerialPort::DataErrorPolicy policy);
virtual void detectDefaultSettings();
@@ -55,14 +63,16 @@ private:
WriteTotalTimeoutConstant
};
- DCB mDCB, mOldDCB;
- COMMTIMEOUTS mCommTimeouts, mOldCommTimeouts;
- OVERLAPPED mOvRead;
- OVERLAPPED mOvWrite;
- OVERLAPPED mOvSelect;
+ DCB m_currDCB, m_oldDCB;
+ COMMTIMEOUTS m_currCommTimeouts, m_oldCommTimeouts;
+ OVERLAPPED m_ovRead;
+ OVERLAPPED m_ovWrite;
+ OVERLAPPED m_ovSelect;
+
+ HANDLE m_descriptor;
bool createEvents(bool rx, bool tx);
- bool closeEvents() const;
+ void closeEvents() const;
void recalcTotalReadTimeoutConstant();
void prepareCommTimeouts(CommTimeouts cto, DWORD msecs);
bool updateDcb();
diff --git a/src/serialportinfo.cpp b/src/serialportinfo.cpp
index 8e1ed73..4ef35c0 100644
--- a/src/serialportinfo.cpp
+++ b/src/serialportinfo.cpp
@@ -12,8 +12,8 @@ SerialPortInfo::SerialPortInfo()
: d_ptr(0)
{}
-SerialPortInfo(const QString &port)
- : d_ptr(new SerialPortInfoPrivate(port)
+SerialPortInfo::SerialPortInfo(const QString &port)
+ : d_ptr(new SerialPortInfoPrivate(port))
{}
SerialPortInfo::SerialPortInfo(const SerialPortInfo &other)
@@ -21,7 +21,7 @@ SerialPortInfo::SerialPortInfo(const SerialPortInfo &other)
{}
SerialPortInfo::SerialPortInfo(const SerialPort &port)
- : d_ptr(new SerialPortInfoPrivate(port.portName())
+ : d_ptr(new SerialPortInfoPrivate(port.portName()))
{}
SerialPortInfo::~SerialPortInfo()
@@ -78,10 +78,11 @@ bool SerialPortInfo::isBusy() const
bool SerialPortInfo::isValid() const
{
Q_D(const SerialPortInfo);
+ /*
if (d != 0)
return SerialPort(d->portName).open();
-
return false;
+ */
}
QList<int> SerialPortInfo::standardRates() const
@@ -89,7 +90,7 @@ QList<int> SerialPortInfo::standardRates() const
QList<int> ret;
Q_D(const SerialPortInfo);
if (d != 0) {
-
+ //
}
return ret;
}
diff --git a/src/serialportinfo_p.h b/src/serialportinfo_p.h
index 39fd1cd..3f0dbc6 100644
--- a/src/serialportinfo_p.h
+++ b/src/serialportinfo_p.h
@@ -4,11 +4,21 @@
#ifndef SERIALPORTINFO_P_H
#define SERIALPORTINFO_P_H
+#include <QtCore/QString>
+#include "serialportinfo.h"
+
class SerialPortInfoPrivate
{
public:
+ SerialPortInfoPrivate(const QString &port);
+
+ QString portName;
+ QString device;
+ QString description;
+ QString manufacturer;
+ bool isBusy() const;
};
#endif // SERIALPORTINFO_P_H
diff --git a/src/serialportinfo_p_win.cpp b/src/serialportinfo_p_win.cpp
index 03408a1..fb0799b 100644
--- a/src/serialportinfo_p_win.cpp
+++ b/src/serialportinfo_p_win.cpp
@@ -1,3 +1,17 @@
/*
License...
-*/ \ No newline at end of file
+*/
+
+#include "serialportinfo_p.h"
+
+
+
+SerialPortInfoPrivate::SerialPortInfoPrivate(const QString &port)
+{
+
+}
+
+bool SerialPortInfoPrivate::isBusy() const
+{
+
+}
diff --git a/src/src.pri b/src/src.pri
index 3c1cb75..51698d6 100644
--- a/src/src.pri
+++ b/src/src.pri
@@ -1,14 +1,28 @@
-HEADERS += include/serialport.h \
- src/abstractserialport_p.h \
- src/serialport_p.h \
- src/qserialdevice_global.h \
-
+HEADERS += \
+ serialport_p.h \
+ serialportinfo_p.h
-SOURCES += src/serialport.cpp
+SOURCES += \
+ src/serialport.cpp \
+ src/serialportinfo.cpp
win32 {
- SOURCES += src/serialport_p_win.cpp
+ HEADERS += \
+ serialport_p_win.h
+ SOURCES += \
+ src/serialport_p_win.cpp \
+ src/serialportinfo_p_win.cpp
}
unix {
- SOURCES += src/serialport_p_unix.cpp
+ HEADERS += \
+ serialport_p_unix.h
+ SOURCES += \
+ src/serialport_p_unix.cpp
+
+ macx {
+ SOURCES += src/serialportinfo_p_mac.cpp
+ }
+ !macx {
+ SOURCES += src/serialportinfo_p_unix.cpp
+ }
}
diff --git a/tests/EMPTYFILE b/tests/EMPTYFILE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/EMPTYFILE