diff options
author | Andre Hartmann <aha_1980@gmx.de> | 2018-09-09 12:51:30 +0200 |
---|---|---|
committer | Andre Hartmann <aha_1980@gmx.de> | 2019-07-31 09:02:46 +0200 |
commit | fd9b9c73ca60c66d01376ddbd6d36e9ea2dfa95c (patch) | |
tree | 35d6eabd19cff707f34571d1e719edff43456c0f /src | |
parent | b8dbe5524bd15ea0acc03dc5c5c4bf9f0d912f42 (diff) |
QCanBusDevice: More error codes and messages on failures
More error messages can now be logged with the logging framework
or directly accessed with the errorOccurred() signal.
The new error codes QCanBusDevice::OperationError and
QCanBusDevice::TimeoutError were introduced to signal situations
where the device is not able to perform a specific operation
respectively when an operation timed out.
[ChangeLog][QCanBusDevice] Added the QCanBusDevice::OperationError
and QCanBusDevice::TimeoutError codes to signal wrong operation
respectively timeout errors.
Task-number: QTBUG-70449
Change-Id: Ifa0831bd0947b624579ae8662df10a2a9ce38714
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/serialbus/qcanbusdevice.cpp | 104 | ||||
-rw-r--r-- | src/serialbus/qcanbusdevice.h | 5 |
2 files changed, 92 insertions, 17 deletions
diff --git a/src/serialbus/qcanbusdevice.cpp b/src/serialbus/qcanbusdevice.cpp index 713dc52..cb9dd69 100644 --- a/src/serialbus/qcanbusdevice.cpp +++ b/src/serialbus/qcanbusdevice.cpp @@ -73,6 +73,11 @@ Q_LOGGING_CATEGORY(QT_CANBUS, "qt.canbus") \value ConfigurationError An error occurred when attempting to set a configuration parameter. \value UnknownError An unknown error occurred. + \value OperationError An operation was attempted while the device was in + a state that did not permit it. This enum was introduced + in Qt 5.14. + \value TimeoutError An timeout occurred while waiting for frames written or + received. This enum was introduced in Qt 5.14. */ /*! @@ -248,7 +253,7 @@ QCanBusDevice::QCanBusDevice(QObject *parent) : CAN bus implementations must use this function to update the device's error state. - \sa error(), errorOccurred() + \sa error(), errorOccurred(), clearError() */ void QCanBusDevice::setError(const QString &errorText, CanBusError errorId) { @@ -261,6 +266,24 @@ void QCanBusDevice::setError(const QString &errorText, CanBusError errorId) } /*! + \since 5.14 + Clears the error id and the human readable description of the last + device error. + + CAN bus implementations must use this function to update the device's + error state. + + \sa error(), errorOccurred(), setError() +*/ +void QCanBusDevice::clearError() +{ + Q_D(QCanBusDevice); + + d->errorText.clear(); + d->lastError = NoError; +} + +/*! Appends \a newFrames to the internal list of frames which can be accessed using \l readFrame() and emits the \l framesReceived() signal. @@ -569,8 +592,14 @@ void QCanBusDevice::clear(QCanBusDevice::Directions direction) { Q_D(QCanBusDevice); - if (Q_UNLIKELY(d->state != ConnectedState)) + if (Q_UNLIKELY(d->state != ConnectedState)) { + const QString error = tr("Cannot clear buffers as device is not connected."); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + setError(error, CanBusError::OperationError); return; + } + + clearError(); if (direction & Direction::Input) { QMutexLocker(&d->incomingFramesGuard); @@ -607,31 +636,46 @@ bool QCanBusDevice::waitForFramesWritten(int msecs) "recursively. Check that no slot containing waitForFramesReceived() " "is called in response to framesWritten(qint64) or " "errorOccurred(CanBusError) signals."); + setError(tr("QCanBusDevice::waitForFramesWritten() must not be called recursively."), + CanBusError::OperationError); return false; } QScopedValueRollback<bool> guard(d_func()->waitForWrittenEntered); d_func()->waitForWrittenEntered = true; - if (d_func()->state != ConnectedState) + if (Q_UNLIKELY(d_func()->state != ConnectedState)) { + const QString error = tr("Cannot wait for frames written as device is not connected."); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + setError(error, CanBusError::OperationError); return false; + } if (!framesToWrite()) return false; // nothing pending, nothing to wait upon + enum { Written = 0, Error, Timeout }; QEventLoop loop; - connect(this, &QCanBusDevice::framesWritten, &loop, [&]() { loop.exit(0); }); - connect(this, &QCanBusDevice::errorOccurred, &loop, [&]() { loop.exit(1); }); + connect(this, &QCanBusDevice::framesWritten, &loop, [&]() { loop.exit(Written); }); + connect(this, &QCanBusDevice::errorOccurred, &loop, [&]() { loop.exit(Error); }); if (msecs >= 0) - QTimer::singleShot(msecs, &loop, [&]() { loop.exit(2); }); + QTimer::singleShot(msecs, &loop, [&]() { loop.exit(Timeout); }); - int result = 0; + int result = Written; while (framesToWrite() > 0) { // wait till all written or time out result = loop.exec(QEventLoop::ExcludeUserInputEvents); - if (result > 0) + if (Q_UNLIKELY(result == Timeout)) { + const QString error = tr("Timeout (%1 ms) during wait for frames written.").arg(msecs); + setError(error, CanBusError::TimeoutError); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + } + + if (result > Written) return false; } + + clearError(); return true; } @@ -660,25 +704,39 @@ bool QCanBusDevice::waitForFramesReceived(int msecs) "recursively. Check that no slot containing waitForFramesReceived() " "is called in response to framesReceived() or " "errorOccurred(CanBusError) signals."); + setError(tr("QCanBusDevice::waitForFramesReceived() must not be called recursively."), + CanBusError::OperationError); return false; } QScopedValueRollback<bool> guard(d_func()->waitForReceivedEntered); d_func()->waitForReceivedEntered = true; - if (d_func()->state != ConnectedState) + if (Q_UNLIKELY(d_func()->state != ConnectedState)) { + const QString error = tr("Cannot wait for frames received as device is not connected."); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + setError(error, CanBusError::OperationError); return false; + } + enum { Received = 0, Error, Timeout }; QEventLoop loop; - - connect(this, &QCanBusDevice::framesReceived, &loop, [&]() { loop.exit(0); }); - connect(this, &QCanBusDevice::errorOccurred, &loop, [&]() { loop.exit(1); }); + connect(this, &QCanBusDevice::framesReceived, &loop, [&]() { loop.exit(Received); }); + connect(this, &QCanBusDevice::errorOccurred, &loop, [&]() { loop.exit(Error); }); if (msecs >= 0) - QTimer::singleShot(msecs, &loop, [&]() { loop.exit(2); }); + QTimer::singleShot(msecs, &loop, [&]() { loop.exit(Timeout); }); int result = loop.exec(QEventLoop::ExcludeUserInputEvents); - return result == 0; + if (Q_UNLIKELY(result == Timeout)) { + const QString error = tr("Timeout (%1 ms) during wait for frames received.").arg(msecs); + setError(error, CanBusError::TimeoutError); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + } + + if (result == Received) + clearError(); + return result == Received; } /*! @@ -734,8 +792,14 @@ QCanBusFrame QCanBusDevice::readFrame() { Q_D(QCanBusDevice); - if (Q_UNLIKELY(d->state != ConnectedState)) + if (Q_UNLIKELY(d->state != ConnectedState)) { + const QString error = tr("Cannot read frame as device is not connected."); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + setError(error, CanBusError::OperationError); return QCanBusFrame(QCanBusFrame::InvalidFrame); + } + + clearError(); QMutexLocker locker(&d->incomingFramesGuard); @@ -758,8 +822,14 @@ QVector<QCanBusFrame> QCanBusDevice::readAllFrames() { Q_D(QCanBusDevice); - if (Q_UNLIKELY(d->state != ConnectedState)) + if (Q_UNLIKELY(d->state != ConnectedState)) { + const QString error = tr("Cannot read frame as device is not connected."); + qCWarning(QT_CANBUS, "%ls", qUtf16Printable(error)); + setError(error, CanBusError::OperationError); return QVector<QCanBusFrame>(); + } + + clearError(); QMutexLocker locker(&d->incomingFramesGuard); @@ -835,6 +905,8 @@ bool QCanBusDevice::connectDevice() return false; } + clearError(); + //Connected is set by backend -> might be delayed by event loop return true; } diff --git a/src/serialbus/qcanbusdevice.h b/src/serialbus/qcanbusdevice.h index 8457b08..1844f4b 100644 --- a/src/serialbus/qcanbusdevice.h +++ b/src/serialbus/qcanbusdevice.h @@ -60,7 +60,9 @@ public: WriteError, ConnectionError, ConfigurationError, - UnknownError + UnknownError, + OperationError, + TimeoutError }; Q_ENUM(CanBusError) @@ -167,6 +169,7 @@ Q_SIGNALS: protected: void setState(QCanBusDevice::CanBusDeviceState newState); void setError(const QString &errorText, QCanBusDevice::CanBusError); + void clearError(); void enqueueReceivedFrames(const QVector<QCanBusFrame> &newFrames); |