summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Hartmann <aha_1980@gmx.de>2017-02-02 15:21:04 +0100
committerAndré Hartmann <aha_1980@gmx.de>2017-07-04 05:49:54 +0000
commite23f4ced90381925406bd854dd3b3d1eeb478d87 (patch)
tree9dfc9fd27982c42e76fbdc9816cc6e00932a6e77
parente257664ae65ce5c51c7edac0a1a9ffaba4baea70 (diff)
QCanBusFrame: Introduce local echo flag
Inspiration for change after reading the SocketCAN mailing list thread: https://marc.info/?l=linux-can&m=147438437202356&w=2 The main usage is, to verify at application stage, that and when a frame was really sent on the bus. For architectures like SocketCAN, where multiple applications can connect to one CAN bus on the same system, this flag also indicates frames that are sent by an other local running application (i.e. not coming from the real bus). Implementations done for SystecCAN, VectorCAN and SocketCAN plugin. PCAN Basic does not seem to have support for this flag. For SocketCAN, see section "4.1.7 RAW socket returned message flags" in https://www.kernel.org/doc/Documentation/networking/can.txt for reference. [ChangeLog][QCanBusFrame] Added local echo flag to mark all echo frames that are generated by the hardware on successful transmission to CAN bus as such. Change-Id: I66d4ce1ec6dfd0a0b994a7b7a9de1a5f503fcb70 Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--examples/serialbus/can/mainwindow.cpp13
-rw-r--r--src/plugins/canbus/socketcan/socketcanbackend.cpp42
-rw-r--r--src/plugins/canbus/socketcan/socketcanbackend.h13
-rw-r--r--src/plugins/canbus/systeccan/systeccanbackend.cpp1
-rw-r--r--src/plugins/canbus/vectorcan/vectorcanbackend.cpp1
-rw-r--r--src/serialbus/doc/src/socketcan.qdoc5
-rw-r--r--src/serialbus/doc/src/systeccan.qdoc3
-rw-r--r--src/serialbus/doc/src/vectorcan.qdoc3
-rw-r--r--src/serialbus/qcanbusframe.cpp37
-rw-r--r--src/serialbus/qcanbusframe.h17
-rw-r--r--tests/auto/qcanbusframe/tst_qcanbusframe.cpp55
11 files changed, 152 insertions, 38 deletions
diff --git a/examples/serialbus/can/mainwindow.cpp b/examples/serialbus/can/mainwindow.cpp
index 19ed560..b0d6972 100644
--- a/examples/serialbus/can/mainwindow.cpp
+++ b/examples/serialbus/can/mainwindow.cpp
@@ -190,13 +190,16 @@ void MainWindow::closeEvent(QCloseEvent *event)
static QString frameFlags(const QCanBusFrame &frame)
{
- if (frame.hasBitrateSwitch() && frame.hasErrorStateIndicator())
- return QStringLiteral(" B E ");
+ QString result = QLatin1String(" --- ");
+
if (frame.hasBitrateSwitch())
- return QStringLiteral(" B - ");
+ result[1] = QLatin1Char('B');
if (frame.hasErrorStateIndicator())
- return QStringLiteral(" - E ");
- return QStringLiteral(" - - ");
+ result[2] = QLatin1Char('E');
+ if (frame.hasLocalEcho())
+ result[3] = QLatin1Char('L');
+
+ return result;
}
void MainWindow::checkMessages()
diff --git a/src/plugins/canbus/socketcan/socketcanbackend.cpp b/src/plugins/canbus/socketcan/socketcanbackend.cpp
index 27a847d..a26070a 100644
--- a/src/plugins/canbus/socketcan/socketcanbackend.cpp
+++ b/src/plugins/canbus/socketcan/socketcanbackend.cpp
@@ -325,7 +325,6 @@ bool SocketCanBackend::applyConfigurationParameter(int key, const QVariant &valu
bool SocketCanBackend::connectSocket()
{
- struct sockaddr_can address;
struct ifreq interface;
if (Q_UNLIKELY((canSocket = socket(PF_CAN, SOCK_RAW | SOCK_NONBLOCK, CAN_RAW)) < 0)) {
@@ -341,15 +340,21 @@ bool SocketCanBackend::connectSocket()
return false;
}
- address.can_family = AF_CAN;
- address.can_ifindex = interface.ifr_ifindex;
+ m_address.can_family = AF_CAN;
+ m_address.can_ifindex = interface.ifr_ifindex;
- if (Q_UNLIKELY(bind(canSocket, reinterpret_cast<struct sockaddr *>(&address), sizeof(address)) < 0)) {
+ if (Q_UNLIKELY(bind(canSocket, reinterpret_cast<struct sockaddr *>(&m_address), sizeof(m_address)) < 0)) {
setError(qt_error_string(errno),
QCanBusDevice::CanBusError::ConnectionError);
return false;
}
+ m_iov.iov_base = &m_frame;
+ m_msg.msg_name = &m_address;
+ m_msg.msg_iov = &m_iov;
+ m_msg.msg_iovlen = 1;
+ m_msg.msg_control = &m_ctrlmsg;
+
delete notifier;
notifier = new QSocketNotifier(canSocket, QSocketNotifier::Read, this);
@@ -637,10 +642,13 @@ void SocketCanBackend::readSocket()
QVector<QCanBusFrame> newFrames;
for (;;) {
- struct canfd_frame frame;
- int bytesReceived;
+ memset(&m_frame, 0, sizeof(m_frame));
+ m_iov.iov_len = sizeof(m_frame);
+ m_msg.msg_namelen = sizeof(m_addr);
+ m_msg.msg_controllen = sizeof(m_ctrlmsg);
+ m_msg.msg_flags = 0;
- bytesReceived = ::read(canSocket, &frame, sizeof(frame));
+ const int bytesReceived = ::recvmsg(canSocket, &m_msg, 0);
if (bytesReceived <= 0) {
break;
@@ -648,7 +656,7 @@ void SocketCanBackend::readSocket()
setError(tr("ERROR SocketCanBackend: incomplete CAN frame"),
QCanBusDevice::CanBusError::ReadError);
continue;
- } else if (Q_UNLIKELY(frame.len > bytesReceived - offsetof(canfd_frame, data))) {
+ } else if (Q_UNLIKELY(m_frame.len > bytesReceived - offsetof(canfd_frame, data))) {
setError(tr("ERROR SocketCanBackend: invalid CAN frame length"),
QCanBusDevice::CanBusError::ReadError);
continue;
@@ -666,21 +674,23 @@ void SocketCanBackend::readSocket()
bufferedFrame.setTimeStamp(stamp);
bufferedFrame.setFlexibleDataRateFormat(bytesReceived == CANFD_MTU);
- bufferedFrame.setExtendedFrameFormat(frame.can_id & CAN_EFF_FLAG);
- Q_ASSERT(frame.len <= CANFD_MAX_DLEN);
+ bufferedFrame.setExtendedFrameFormat(m_frame.can_id & CAN_EFF_FLAG);
+ Q_ASSERT(m_frame.len <= CANFD_MAX_DLEN);
- if (frame.can_id & CAN_RTR_FLAG)
+ if (m_frame.can_id & CAN_RTR_FLAG)
bufferedFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
- if (frame.can_id & CAN_ERR_FLAG)
+ if (m_frame.can_id & CAN_ERR_FLAG)
bufferedFrame.setFrameType(QCanBusFrame::ErrorFrame);
- if (frame.flags & CANFD_BRS)
+ if (m_frame.flags & CANFD_BRS)
bufferedFrame.setBitrateSwitch(true);
- if (frame.flags & CANFD_ESI)
+ if (m_frame.flags & CANFD_ESI)
bufferedFrame.setErrorStateIndicator(true);
+ if (m_msg.msg_flags & MSG_CONFIRM)
+ bufferedFrame.setLocalEcho(true);
- bufferedFrame.setFrameId(frame.can_id & CAN_EFF_MASK);
+ bufferedFrame.setFrameId(m_frame.can_id & CAN_EFF_MASK);
- const QByteArray load(reinterpret_cast<char *>(frame.data), frame.len);
+ const QByteArray load(reinterpret_cast<char *>(m_frame.data), m_frame.len);
bufferedFrame.setPayload(load);
newFrames.append(std::move(bufferedFrame));
diff --git a/src/plugins/canbus/socketcan/socketcanbackend.h b/src/plugins/canbus/socketcan/socketcanbackend.h
index 70c47c8..50976b1 100644
--- a/src/plugins/canbus/socketcan/socketcanbackend.h
+++ b/src/plugins/canbus/socketcan/socketcanbackend.h
@@ -45,6 +45,12 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
+// The order of the following includes is mandatory, because some
+// distributions use sa_family_t in can.h without including socket.h
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <linux/can.h>
+
QT_BEGIN_NAMESPACE
class SocketCanBackend : public QCanBusDevice
@@ -73,6 +79,13 @@ private:
bool connectSocket();
bool applyConfigurationParameter(int key, const QVariant &value);
+ canfd_frame m_frame;
+ sockaddr_can m_address;
+ msghdr m_msg;
+ iovec m_iov;
+ sockaddr_can m_addr;
+ char m_ctrlmsg[CMSG_SPACE(sizeof(timeval)) + CMSG_SPACE(sizeof(__u32))];
+
qint64 canSocket = -1;
QSocketNotifier *notifier = nullptr;
QString canSocketName;
diff --git a/src/plugins/canbus/systeccan/systeccanbackend.cpp b/src/plugins/canbus/systeccan/systeccanbackend.cpp
index 652c8cb..a1db866 100644
--- a/src/plugins/canbus/systeccan/systeccanbackend.cpp
+++ b/src/plugins/canbus/systeccan/systeccanbackend.cpp
@@ -394,6 +394,7 @@ void SystecCanBackendPrivate::readAllReceivedMessages()
// TODO: Timestamp can also be set to 100 us resolution with kUcanModeHighResTimer
frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(message.m_dwTime * 1000));
frame.setExtendedFrameFormat(message.m_bFF & USBCAN_MSG_FF_EXT);
+ frame.setLocalEcho(message.m_bFF & USBCAN_MSG_FF_ECHO);
frame.setFrameType((message.m_bFF & USBCAN_MSG_FF_RTR)
? QCanBusFrame::RemoteRequestFrame
: QCanBusFrame::DataFrame);
diff --git a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
index 6c455da..c84658b 100644
--- a/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
+++ b/src/plugins/canbus/vectorcan/vectorcanbackend.cpp
@@ -359,6 +359,7 @@ void VectorCanBackendPrivate::startRead()
QByteArray(reinterpret_cast<const char *>(msg.data), int(msg.dlc)));
frame.setTimeStamp(QCanBusFrame::TimeStamp::fromMicroSeconds(event.timeStamp / 1000));
frame.setExtendedFrameFormat(msg.id & XL_CAN_EXT_MSG_ID);
+ frame.setLocalEcho(msg.flags & XL_CAN_MSG_FLAG_TX_COMPLETED);
frame.setFrameType((msg.flags & XL_CAN_MSG_FLAG_REMOTE_FRAME)
? QCanBusFrame::RemoteRequestFrame
: (msg.flags & XL_CAN_MSG_FLAG_ERROR_FRAME)
diff --git a/src/serialbus/doc/src/socketcan.qdoc b/src/serialbus/doc/src/socketcan.qdoc
index 12f96fd..d300e46 100644
--- a/src/serialbus/doc/src/socketcan.qdoc
+++ b/src/serialbus/doc/src/socketcan.qdoc
@@ -149,12 +149,15 @@
\li To meet the multiple-user needs, the local loopback is enabled by default.
This means, whenever a CAN frame is transmitted on the CAN bus, a local
echo of this frame is sent to all applications connected to this CAN device.
+ If this option is enabled, the therefore received frames are marked with
+ QCanBusFrame::hasLocalEcho()
\row
\li QCanBusDevice::ReceiveOwnKey
\li The reception of the CAN frames on the same socket that was sending the CAN frame
is disabled by default. When enabling this option, all CAN frames sent to the CAN
bus immediately appear in the receive buffer. This can be used to check if sending
- was successful.
+ was successful. If this option is enabled, the therefore received frames are marked
+ with QCanBusFrame::hasLocalEcho()
\row
\li QCanBusDevice::ErrorFilterKey
\li A CAN interface driver can generate so called \e {Error Message Frames} that can
diff --git a/src/serialbus/doc/src/systeccan.qdoc b/src/serialbus/doc/src/systeccan.qdoc
index dda9dd5..58bb70a 100644
--- a/src/serialbus/doc/src/systeccan.qdoc
+++ b/src/serialbus/doc/src/systeccan.qdoc
@@ -98,6 +98,7 @@
\row
\li QCanBusDevice::ReceiveOwnKey
\li The reception of CAN frames on the same channel that was sending the CAN frame
- is disabled by default.
+ is disabled by default. If this option is enabled, the therefore received frames
+ are marked with QCanBusFrame::hasLocalEcho()
\endtable
*/
diff --git a/src/serialbus/doc/src/vectorcan.qdoc b/src/serialbus/doc/src/vectorcan.qdoc
index 5b95a83..f243bb8 100644
--- a/src/serialbus/doc/src/vectorcan.qdoc
+++ b/src/serialbus/doc/src/vectorcan.qdoc
@@ -96,6 +96,7 @@
\li The reception of the CAN frames on the same device that was sending the CAN frame
is disabled by default. When enabling this option, all CAN frames sent to the CAN
bus immediately appear in the receive buffer. This can be used to check if sending
- was successful.
+ was successful. If this option is enabled, the therefore received frames are marked
+ with QCanBusFrame::hasLocalEcho()
\endtable
*/
diff --git a/src/serialbus/qcanbusframe.cpp b/src/serialbus/qcanbusframe.cpp
index 6ef0f11..d1ce3b0 100644
--- a/src/serialbus/qcanbusframe.cpp
+++ b/src/serialbus/qcanbusframe.cpp
@@ -312,6 +312,36 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn QCanBusFrame::hasLocalEcho() const
+ \since 5.10
+
+ Returns \c true if the frame is a local echo frame, i.e. a frame that is received as echo when
+ the frame with the same content was successfully sent to the CAN bus. This flag is set for
+ frames sent by the application itself as well as for frames sent by other applications running
+ on the same system.
+
+ QCanBusDevice::ReceiveOwnKey must be set to true to receive echo frames.
+
+ \sa setLocalEcho()
+ \sa QCanBusDevice::ReceiveOwnKey
+ \sa QCanBusDevice::LoopbackKey
+*/
+
+/*!
+ \fn void QCanBusFrame::setLocalEcho(bool echo)
+ \since 5.10
+
+ Marks the frame as local echo frame.
+
+ When sending CAN bus frames with QCanBusDevice::ReceiveOwnKey enabled, all successfully sent
+ frames are echoed to the receive queue and marked as local echo frames.
+ \c QCanBusFrame::setLocalEcho should therefore only be used for application testing,
+ e.g. on virtual CAN busses.
+
+ \sa hasLocalEcho()
+*/
+
+/*!
\class QCanBusFrame::TimeStamp
\inmodule QtSerialBus
\since 5.8
@@ -422,6 +452,8 @@ QDataStream &operator<<(QDataStream &out, const QCanBusFrame &frame)
out << stamp.microSeconds();
if (frame.version >= QCanBusFrame::Version::Qt_5_9)
out << frame.hasBitrateSwitch() << frame.hasErrorStateIndicator();
+ if (frame.version >= QCanBusFrame::Version::Qt_5_10)
+ out << frame.hasLocalEcho();
return out;
}
@@ -439,6 +471,7 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame)
bool flexibleDataRate;
bool bitrateSwitch = false;
bool errorStateIndicator = false;
+ bool localEcho = false;
QByteArray payload;
qint64 seconds;
qint64 microSeconds;
@@ -449,6 +482,9 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame)
if (version >= QCanBusFrame::Version::Qt_5_9)
in >> bitrateSwitch >> errorStateIndicator;
+ if (version >= QCanBusFrame::Version::Qt_5_10)
+ in >> localEcho;
+
frame.setFrameId(frameId);
frame.version = version;
@@ -457,6 +493,7 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame)
frame.setFlexibleDataRateFormat(flexibleDataRate);
frame.setBitrateSwitch(bitrateSwitch);
frame.setErrorStateIndicator(errorStateIndicator);
+ frame.setLocalEcho(localEcho);
frame.setPayload(payload);
frame.setTimeStamp(QCanBusFrame::TimeStamp(seconds, microSeconds));
diff --git a/src/serialbus/qcanbusframe.h b/src/serialbus/qcanbusframe.h
index 5e285c1..7468816 100644
--- a/src/serialbus/qcanbusframe.h
+++ b/src/serialbus/qcanbusframe.h
@@ -74,10 +74,11 @@ public:
explicit QCanBusFrame(FrameType type = DataFrame) Q_DECL_NOTHROW :
isExtendedFrame(0x0),
- version(Qt_5_9),
+ version(Qt_5_10),
isFlexibleDataRate(0x0),
isBitrateSwitch(0x0),
isErrorStateIndicator(0x0),
+ isLocalEcho(0x0),
reserved0(0x0)
{
Q_UNUSED(reserved0);
@@ -107,10 +108,11 @@ public:
explicit QCanBusFrame(quint32 identifier, const QByteArray &data) :
format(DataFrame),
isExtendedFrame(0x0),
- version(Qt_5_9),
+ version(Qt_5_10),
isFlexibleDataRate(data.length() > 8 ? 0x1 : 0x0),
isBitrateSwitch(0x0),
isErrorStateIndicator(0x0),
+ isLocalEcho(0x0),
reserved0(0x0),
load(data)
{
@@ -249,6 +251,11 @@ public:
if (errorStateIndicator)
isFlexibleDataRate = 0x1;
}
+ bool hasLocalEcho() const Q_DECL_NOTHROW { return (isLocalEcho & 0x1); }
+ void setLocalEcho(bool localEcho) Q_DECL_NOTHROW
+ {
+ isLocalEcho = (localEcho & 0x1);
+ }
#ifndef QT_NO_DATASTREAM
friend Q_SERIALBUS_EXPORT QDataStream &operator<<(QDataStream &, const QCanBusFrame &);
@@ -258,7 +265,8 @@ public:
private:
enum Version {
Qt_5_8 = 0x0,
- Qt_5_9 = 0x1
+ Qt_5_9 = 0x1,
+ Qt_5_10 = 0x2
};
quint32 canId:29; // acts as container for error codes too
@@ -271,7 +279,8 @@ private:
quint8 isBitrateSwitch:1;
quint8 isErrorStateIndicator:1;
- quint8 reserved0:6;
+ quint8 isLocalEcho:1;
+ quint8 reserved0:5;
// reserved for future use
quint8 reserved[2];
diff --git a/tests/auto/qcanbusframe/tst_qcanbusframe.cpp b/tests/auto/qcanbusframe/tst_qcanbusframe.cpp
index 043d89e..38c3784 100644
--- a/tests/auto/qcanbusframe/tst_qcanbusframe.cpp
+++ b/tests/auto/qcanbusframe/tst_qcanbusframe.cpp
@@ -50,6 +50,7 @@ private slots:
void timeStamp();
void bitRateSwitch();
void errorStateIndicator();
+ void localEcho();
void tst_isValid_data();
void tst_isValid();
@@ -264,6 +265,21 @@ void tst_QCanBusFrame::errorStateIndicator()
QVERIFY(!frame2.hasErrorStateIndicator());
}
+void tst_QCanBusFrame::localEcho()
+{
+ QCanBusFrame frame(QCanBusFrame::DataFrame);
+ QVERIFY(!frame.hasLocalEcho());
+
+ frame.setLocalEcho(true);
+ QVERIFY(frame.hasLocalEcho());
+
+ frame.setLocalEcho(false);
+ QVERIFY(!frame.hasLocalEcho());
+
+ const QCanBusFrame frame2(0x123, QByteArray());
+ QVERIFY(!frame2.hasLocalEcho());
+}
+
void tst_QCanBusFrame::tst_isValid_data()
{
QTest::addColumn<QCanBusFrame::FrameType>("frameType");
@@ -432,39 +448,54 @@ void tst_QCanBusFrame::streaming_data()
QTest::addColumn<bool>("isFlexibleDataRate");
QTest::addColumn<bool>("isBitrateSwitch");
QTest::addColumn<bool>("isErrorStateIndicator");
+ QTest::addColumn<bool>("isLocalEcho");
QTest::addColumn<QCanBusFrame::FrameType>("frameType");
QTest::newRow("emptyFrame") << quint32(0) << QByteArray()
<< qint64(0) << qint64(0)
- << false << false << false << false << QCanBusFrame::DataFrame;
+ << false << false << false << false << false
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrame1") << quint32(123) << QByteArray("abcde1")
<< qint64(456) << qint64(784)
- << true << false << false << false << QCanBusFrame::DataFrame;
+ << true << false << false << false << false
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrame2") << quint32(123) << QByteArray("abcde2")
<< qint64(457) << qint64(785)
- << false << false << false << false << QCanBusFrame::DataFrame;
+ << false << false << false << false << false
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrameFD") << quint32(123) << QByteArray("abcdfd")
<< qint64(457) << qint64(785)
- << false << true << false << false << QCanBusFrame::DataFrame;
+ << false << true << false << false << false
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrameBRS") << quint32(123) << QByteArray("abcdfd")
<< qint64(457) << qint64(785)
- << false << true << true << false << QCanBusFrame::DataFrame;
+ << false << true << true << false << false
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrameESI") << quint32(123) << QByteArray("abcdfd")
<< qint64(457) << qint64(785)
- << false << true << false << true << QCanBusFrame::DataFrame;
+ << false << true << false << true << false
+ << QCanBusFrame::DataFrame;
+ QTest::newRow("echoFrame") << quint32(123) << QByteArray("abcde7")
+ << qint64(888) << qint64(777)
+ << false << false << false << false << true
+ << QCanBusFrame::DataFrame;
QTest::newRow("fullFrame3") << quint32(123) << QByteArray("abcde3")
<< qint64(458) << qint64(786)
- << true << false << false << false << QCanBusFrame::RemoteRequestFrame;
+ << true << false << false << false << false
+ << QCanBusFrame::RemoteRequestFrame;
QTest::newRow("fullFrame4") << quint32(123) << QByteArray("abcde4")
<< qint64(459) << qint64(787)
- << false << false << false << false << QCanBusFrame::RemoteRequestFrame;
+ << false << false << false << false << false
+ << QCanBusFrame::RemoteRequestFrame;
QTest::newRow("fullFrame5") << quint32(123) << QByteArray("abcde5")
<< qint64(460) << qint64(789)
- << true << false << false << false << QCanBusFrame::ErrorFrame;
+ << true << false << false << false << false
+ << QCanBusFrame::ErrorFrame;
QTest::newRow("fullFrame6") << quint32(123) << QByteArray("abcde6")
<< qint64(453) << qint64(788)
- << false << false << false << false << QCanBusFrame::ErrorFrame;
+ << false << false << false << false << false
+ << QCanBusFrame::ErrorFrame;
}
void tst_QCanBusFrame::streaming()
@@ -477,6 +508,7 @@ void tst_QCanBusFrame::streaming()
QFETCH(bool, isFlexibleDataRate);
QFETCH(bool, isBitrateSwitch);
QFETCH(bool, isErrorStateIndicator);
+ QFETCH(bool, isLocalEcho);
QFETCH(QCanBusFrame::FrameType, frameType);
QCanBusFrame originalFrame(frameId, payload);
@@ -487,6 +519,7 @@ void tst_QCanBusFrame::streaming()
originalFrame.setFlexibleDataRateFormat(isFlexibleDataRate);
originalFrame.setBitrateSwitch(isBitrateSwitch);
originalFrame.setErrorStateIndicator(isErrorStateIndicator);
+ originalFrame.setLocalEcho(isLocalEcho);
originalFrame.setFrameType(frameType);
QByteArray buffer;
@@ -513,6 +546,8 @@ void tst_QCanBusFrame::streaming()
originalFrame.hasBitrateSwitch());
QCOMPARE(restoredFrame.hasErrorStateIndicator(),
originalFrame.hasErrorStateIndicator());
+ QCOMPARE(restoredFrame.hasLocalEcho(),
+ originalFrame.hasLocalEcho());
}
void tst_QCanBusFrame::tst_error()