summaryrefslogtreecommitdiff
path: root/src/serialport/qserialport_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialport/qserialport_win.cpp')
-rw-r--r--src/serialport/qserialport_win.cpp198
1 files changed, 79 insertions, 119 deletions
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index e6e6924..a9687a2 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -77,8 +77,6 @@ QT_BEGIN_NAMESPACE
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
- Q_Q(QSerialPort);
-
DWORD desiredAccess = 0;
originalEventMask = EV_ERR;
@@ -93,7 +91,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
desiredAccess, 0, Q_NULLPTR, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, Q_NULLPTR);
if (handle == INVALID_HANDLE_VALUE) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -106,13 +104,18 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
void QSerialPortPrivate::close()
{
- Q_Q(QSerialPort);
-
if (!::CancelIo(handle))
- q->setError(decodeSystemError());
+ setError(getSystemError());
- if (notifier)
- notifier->deleteLater();
+ if (notifier) {
+ delete notifier;
+ notifier = Q_NULLPTR;
+ }
+
+ if (startAsyncWriteTimer) {
+ delete startAsyncWriteTimer;
+ startAsyncWriteTimer = Q_NULLPTR;
+ }
readStarted = false;
writeStarted = false;
@@ -123,25 +126,23 @@ void QSerialPortPrivate::close()
if (settingsRestoredOnClose) {
if (!::SetCommState(handle, &restoredDcb))
- q->setError(decodeSystemError());
+ setError(getSystemError());
else if (!::SetCommTimeouts(handle, &restoredCommTimeouts))
- q->setError(decodeSystemError());
+ setError(getSystemError());
}
if (!::CloseHandle(handle))
- q->setError(decodeSystemError());
+ setError(getSystemError());
handle = INVALID_HANDLE_VALUE;
}
QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
{
- Q_Q(QSerialPort);
-
DWORD modemStat = 0;
if (!::GetCommModemStatus(handle, &modemStat)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return QSerialPort::NoSignal;
}
@@ -160,7 +161,7 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
if (!::DeviceIoControl(handle, IOCTL_SERIAL_GET_DTRRTS, Q_NULLPTR, 0,
&modemStat, sizeof(modemStat),
&bytesReturned, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return ret;
}
@@ -174,10 +175,8 @@ QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals()
bool QSerialPortPrivate::setDataTerminalReady(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETDTR : CLRDTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -187,10 +186,8 @@ bool QSerialPortPrivate::setDataTerminalReady(bool set)
bool QSerialPortPrivate::setRequestToSend(bool set)
{
- Q_Q(QSerialPort);
-
if (!::EscapeCommFunction(handle, set ? SETRTS : CLRRTS)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -204,8 +201,6 @@ bool QSerialPortPrivate::flush()
bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
DWORD flags = 0;
if (directions & QSerialPort::Input)
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
@@ -214,7 +209,7 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
actualBytesToWrite = 0;
}
if (!::PurgeComm(handle, flags)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -242,32 +237,14 @@ bool QSerialPortPrivate::sendBreak(int duration)
bool QSerialPortPrivate::setBreakEnabled(bool set)
{
- Q_Q(QSerialPort);
-
if (set ? !::SetCommBreak(handle) : !::ClearCommBreak(handle)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-qint64 QSerialPortPrivate::readData(char *data, qint64 maxSize)
-{
- Q_UNUSED(data);
- Q_UNUSED(maxSize);
-
- // We need try to start async reading to read a remainder from a driver's queue
- // in case we have a limited read buffer size. Because the read notification can
- // be stalled since Windows do not re-triggered an EV_RXCHAR event if a driver's
- // buffer has a remainder of data ready to read until a new data will be received.
- if (readBufferMaxSize || flowControl == QSerialPort::HardwareControl)
- startAsyncRead();
-
- // return 0 indicating there may be more data in the future
- return qint64(0);
-}
-
bool QSerialPortPrivate::waitForReadyRead(int msecs)
{
if (!writeStarted && !_q_startAsyncWrite())
@@ -331,10 +308,8 @@ bool QSerialPortPrivate::setBaudRate()
bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions directions)
{
- Q_Q(QSerialPort);
-
if (directions != QSerialPort::AllDirections) {
- q->setError(QSerialPort::UnsupportedOperationError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnsupportedOperationError, QSerialPort::tr("Custom baud rate direction is unsupported")));
return false;
}
currentDcb.BaudRate = baudRate;
@@ -442,18 +417,20 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
if (bytesTransferred > 0) {
char *ptr = buffer.reserve(bytesTransferred);
::memcpy(ptr, readChunkBuffer.constData(), bytesTransferred);
- if (!emulateErrorPolicy())
- emitReadyRead();
}
readStarted = false;
+ bool result = true;
if ((bytesTransferred == ReadChunkSize) && (policy == QSerialPort::IgnorePolicy))
- return startAsyncRead();
+ result = startAsyncRead();
else if (readBufferMaxSize == 0 || readBufferMaxSize > buffer.size())
- return startAsyncCommunication();
- else
- return true;
+ result = startAsyncCommunication();
+
+ if ((bytesTransferred > 0) && !emulateErrorPolicy())
+ emitReadyRead();
+
+ return result;
}
bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
@@ -476,15 +453,13 @@ bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
bool QSerialPortPrivate::startAsyncCommunication()
{
- Q_Q(QSerialPort);
-
::ZeroMemory(&communicationOverlapped, sizeof(communicationOverlapped));
if (!::WaitCommEvent(handle, &triggeredEventMask, &communicationOverlapped)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error == QSerialPort::PermissionError)
- error = QSerialPort::ResourceError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode == QSerialPort::PermissionError)
+ error.errorCode = QSerialPort::ResourceError;
+ setError(error);
return false;
}
}
@@ -493,8 +468,6 @@ bool QSerialPortPrivate::startAsyncCommunication()
bool QSerialPortPrivate::startAsyncRead()
{
- Q_Q(QSerialPort);
-
if (readStarted)
return true;
@@ -515,13 +488,13 @@ bool QSerialPortPrivate::startAsyncRead()
return true;
}
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error == QSerialPort::PermissionError)
- error = QSerialPort::ResourceError;
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::ReadError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode == QSerialPort::PermissionError)
+ error.errorCode = QSerialPort::ResourceError;
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::ReadError;
+ setError(error);
return false;
}
@@ -531,8 +504,6 @@ bool QSerialPortPrivate::startAsyncRead()
bool QSerialPortPrivate::_q_startAsyncWrite()
{
- Q_Q(QSerialPort);
-
if (writeBuffer.isEmpty() || writeStarted)
return true;
@@ -541,11 +512,11 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
if (!::WriteFile(handle, writeBuffer.readPointer(),
writeBytes, Q_NULLPTR, &writeCompletionOverlapped)) {
- QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- if (error != QSerialPort::ResourceError)
- error = QSerialPort::WriteError;
- q->setError(error);
+ QSerialPortErrorInfo error = getSystemError();
+ if (error.errorCode != QSerialPort::NoError) {
+ if (error.errorCode != QSerialPort::ResourceError)
+ error.errorCode = QSerialPort::WriteError;
+ setError(error);
return false;
}
}
@@ -557,11 +528,9 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
void QSerialPortPrivate::_q_notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped)
{
- Q_Q(QSerialPort);
-
- const QSerialPort::SerialPortError error = decodeSystemError(errorCode);
- if (error != QSerialPort::NoError) {
- q->setError(error);
+ const QSerialPortErrorInfo error = getSystemError(errorCode);
+ if (error.errorCode != QSerialPort::NoError) {
+ setError(error);
return;
}
@@ -610,11 +579,6 @@ void QSerialPortPrivate::emitReadyRead()
emit q->readyRead();
}
-qint64 QSerialPortPrivate::bytesToWrite() const
-{
- return actualBytesToWrite;
-}
-
qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
Q_Q(QSerialPort);
@@ -635,33 +599,29 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
void QSerialPortPrivate::handleLineStatusErrors()
{
- Q_Q(QSerialPort);
-
DWORD errors = 0;
if (!::ClearCommError(handle, &errors, Q_NULLPTR)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return;
}
if (errors & CE_FRAME) {
- q->setError(QSerialPort::FramingError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("Framing error detected while reading")));
} else if (errors & CE_RXPARITY) {
- q->setError(QSerialPort::ParityError);
+ setError(QSerialPortErrorInfo(QSerialPort::FramingError, QSerialPort::tr("ParityError error detected while reading")));
parityErrorOccurred = true;
} else if (errors & CE_BREAK) {
- q->setError(QSerialPort::BreakConditionError);
+ setError(QSerialPortErrorInfo(QSerialPort::BreakConditionError, QSerialPort::tr("Break condition detected while reading")));
} else {
- q->setError(QSerialPort::UnknownError);
+ setError(QSerialPortErrorInfo(QSerialPort::UnknownError, QSerialPort::tr("Unknown streaming error")));
}
}
OVERLAPPED *QSerialPortPrivate::waitForNotified(int msecs)
{
- Q_Q(QSerialPort);
-
OVERLAPPED *overlapped = notifier->waitForAnyNotified(msecs);
if (!overlapped) {
- q->setError(decodeSystemError(WAIT_TIMEOUT));
+ setError(getSystemError(WAIT_TIMEOUT));
return 0;
}
return overlapped;
@@ -675,7 +635,7 @@ inline bool QSerialPortPrivate::initialize()
restoredDcb.DCBlength = sizeof(restoredDcb);
if (!::GetCommState(handle, &restoredDcb)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -690,11 +650,13 @@ inline bool QSerialPortPrivate::initialize()
if (currentDcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
currentDcb.fDtrControl = DTR_CONTROL_DISABLE;
+ currentDcb.BaudRate = inputBaudRate;
+
if (!updateDcb())
return false;
if (!::GetCommTimeouts(handle, &restoredCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -705,7 +667,7 @@ inline bool QSerialPortPrivate::initialize()
return false;
if (!::SetCommMask(handle, originalEventMask)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
@@ -723,10 +685,8 @@ inline bool QSerialPortPrivate::initialize()
bool QSerialPortPrivate::updateDcb()
{
- Q_Q(QSerialPort);
-
if (!::SetCommState(handle, &currentDcb)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
@@ -734,60 +694,60 @@ bool QSerialPortPrivate::updateDcb()
bool QSerialPortPrivate::updateCommTimeouts()
{
- Q_Q(QSerialPort);
-
if (!::SetCommTimeouts(handle, &currentCommTimeouts)) {
- q->setError(decodeSystemError());
+ setError(getSystemError());
return false;
}
return true;
}
-QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError(int systemErrorCode) const
+QSerialPortErrorInfo QSerialPortPrivate::getSystemError(int systemErrorCode) const
{
if (systemErrorCode == -1)
systemErrorCode = ::GetLastError();
- QSerialPort::SerialPortError error;
+ QSerialPortErrorInfo error;
+ error.errorString = qt_error_string(systemErrorCode);
+
switch (systemErrorCode) {
case ERROR_SUCCESS:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_IO_PENDING:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_MORE_DATA:
- error = QSerialPort::NoError;
+ error.errorCode = QSerialPort::NoError;
break;
case ERROR_FILE_NOT_FOUND:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_INVALID_NAME:
- error = QSerialPort::DeviceNotFoundError;
+ error.errorCode = QSerialPort::DeviceNotFoundError;
break;
case ERROR_ACCESS_DENIED:
- error = QSerialPort::PermissionError;
+ error.errorCode = QSerialPort::PermissionError;
break;
case ERROR_INVALID_HANDLE:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_INVALID_PARAMETER:
- error = QSerialPort::UnsupportedOperationError;
+ error.errorCode = QSerialPort::UnsupportedOperationError;
break;
case ERROR_BAD_COMMAND:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_DEVICE_REMOVED:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case ERROR_OPERATION_ABORTED:
- error = QSerialPort::ResourceError;
+ error.errorCode = QSerialPort::ResourceError;
break;
case WAIT_TIMEOUT:
- error = QSerialPort::TimeoutError;
+ error.errorCode = QSerialPort::TimeoutError;
break;
default:
- error = QSerialPort::UnknownError;
+ error.errorCode = QSerialPort::UnknownError;
break;
}
return error;