summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Keller <Rainer.Keller@qt.io>2019-09-13 12:41:49 +0200
committerRainer Keller <Rainer.Keller@qt.io>2019-10-02 11:43:21 +0200
commit2611803da202d9bfade0249ff07bd0d1fd669046 (patch)
treecbcae1126506141e9ae4c335c6c574529bc1e942
parentccf05a36efeb9f50c23283c5f9f2fefcfde4180a (diff)
Fix GUID binary encoder endianness
The OPC-UA standard defines in part 6 chapter 5.2.2.6 that integer parts of a GUID have to be transferred in little endian order. Change-Id: I2082ecef414572d87cd5586fc4ea9f5f8887a4aa Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com>
-rw-r--r--src/opcua/client/qopcuabinarydataencoding.h33
-rw-r--r--tests/auto/qopcuaclient/tst_client.cpp29
2 files changed, 58 insertions, 4 deletions
diff --git a/src/opcua/client/qopcuabinarydataencoding.h b/src/opcua/client/qopcuabinarydataencoding.h
index 3526614..e613a0d 100644
--- a/src/opcua/client/qopcuabinarydataencoding.h
+++ b/src/opcua/client/qopcuabinarydataencoding.h
@@ -339,8 +339,27 @@ inline QUuid QOpcUaBinaryDataEncoding::decode<QUuid>(bool &success)
return QUuid();
}
- const QUuid temp = QUuid::fromRfc4122(QByteArray::fromRawData(m_data->constData() + m_offset, uuidSize));
- m_offset += uuidSize;
+ const auto data1 = decode<quint32>(success);
+ if (!success)
+ return QUuid();
+
+ const auto data2 = decode<quint16>(success);
+ if (!success)
+ return QUuid();
+
+ const auto data3 = decode<quint16>(success);
+ if (!success)
+ return QUuid();
+
+ const auto data4 = QByteArray::fromRawData(m_data->constData() + m_offset, 8);
+ if (!success)
+ return QUuid();
+
+ m_offset += 8;
+
+ const QUuid temp = QUuid(data1, data2, data3, data4[0], data4[1], data4[2],
+ data4[3], data4[4], data4[5], data4[6], data4[7]);
+
success = true;
return temp;
}
@@ -700,10 +719,16 @@ inline bool QOpcUaBinaryDataEncoding::encode<QOpcUaXValue>(const QOpcUaXValue &s
template <>
inline bool QOpcUaBinaryDataEncoding::encode<QUuid>(const QUuid &src)
{
- if (!m_data)
+ if (!encode<quint32>(src.data1))
+ return false;
+ if (!encode<quint16>(src.data2))
return false;
+ if (!encode<quint16>(src.data3))
+ return false;
+
+ auto data = QByteArray::fromRawData(reinterpret_cast<const char *>(src.data4), sizeof(src.data4));
+ m_data->append(data);
- m_data->append(src.toRfc4122());
return true;
}
diff --git a/tests/auto/qopcuaclient/tst_client.cpp b/tests/auto/qopcuaclient/tst_client.cpp
index c80d3c6..bfb7eb4 100644
--- a/tests/auto/qopcuaclient/tst_client.cpp
+++ b/tests/auto/qopcuaclient/tst_client.cpp
@@ -476,6 +476,9 @@ private slots:
defineDataMethod(resolveBrowsePath_data)
void resolveBrowsePath();
+ defineDataMethod(extensionObjectWithGuid_data)
+ void extensionObjectWithGuid();
+
void statusStrings();
// This test case restarts the server. It must be run last to avoid
@@ -3593,6 +3596,32 @@ void Tst_QOpcUaClient::resolveBrowsePath()
QCOMPARE(spy.at(0).at(2).value<QOpcUa::UaStatusCode>(), QOpcUa::UaStatusCode::Good);
}
+void Tst_QOpcUaClient::extensionObjectWithGuid()
+{
+ const QByteArray uuidWireData = QByteArray::fromHex("f827ce6cbeb61f48a5a888fd2bbc4fb7");
+ const QByteArray opcuaWireData = QByteArray::fromHex("040400") + uuidWireData;
+ const QString uuidId = QString::fromLatin1("6cce27f8-b6be-481f-a5a8-88fd2bbc4fb7");
+ const QString sampleNodeId = QString::fromLatin1("ns=4;g=") + uuidId;
+
+ const auto uuid = QUuid::fromString(uuidId);
+ QCOMPARE(uuid.toString(QUuid::WithoutBraces), uuidId);
+
+ QOpcUaExtensionObject obj;
+ obj.setEncoding(QOpcUaExtensionObject::Encoding::ByteString);
+ obj.setEncodingTypeId(QStringLiteral("ns=2;s=MyEncoding1"));
+ QOpcUaBinaryDataEncoding encoder(obj);
+ encoder.encode<QString, QOpcUa::Types::NodeId>(sampleNodeId);
+ QCOMPARE(obj.encodedBody().toHex(), opcuaWireData.toHex());
+
+ QByteArray buffer = obj.encodedBody();
+ QOpcUaBinaryDataEncoding decoder(&buffer);
+
+ bool success = false;
+ const auto decodedNodeId = decoder.decode<QString, QOpcUa::Types::NodeId>(success);
+ QVERIFY(success);
+ QCOMPARE(decodedNodeId, sampleNodeId);
+}
+
void Tst_QOpcUaClient::statusStrings()
{
QCOMPARE(statusToString(QOpcUa::Good), "Good");