diff options
-rw-r--r-- | dependencies.yaml | 4 | ||||
-rw-r--r-- | examples/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/opcuaviewer/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/waterpump/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/waterpump/simulationserver/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/waterpump/waterpump-qml/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/waterpump/waterpump-qmlcpp/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/opcua/x509/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/opcua/client/qopcuagenericstructhandlerprivate.cpp | 6 | ||||
-rw-r--r-- | src/plugins/opcua/open62541/qopen62541subscription.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qopcuaclient/tst_client.cpp | 35 | ||||
-rw-r--r-- | tests/open62541-testserver/main.cpp | 2 | ||||
-rw-r--r-- | tests/open62541-testserver/testserver.cpp | 27 | ||||
-rw-r--r-- | tests/open62541-testserver/testserver.h | 2 |
15 files changed, 83 insertions, 11 deletions
diff --git a/dependencies.yaml b/dependencies.yaml index 7fc98bb..e24cf63 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,7 +1,7 @@ dependencies: ../qtbase: - ref: def07f630605f7014e4f80c511be4d8f9eca8d95 + ref: e7362764d4931f255d2377462df8ac7a0d4e7c84 required: true ../qtdeclarative: - ref: 655ff8592be71b726f39d3b1a178c3ca57944715 + ref: 330fa93d6e9003c0ea188b9e703f2b3f0448f8c8 required: true diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2e8bd82..3977325 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause qt_examples_build_begin(EXTERNAL_BUILD) diff --git a/examples/opcua/CMakeLists.txt b/examples/opcua/CMakeLists.txt index 86e9a9b..3001b6b 100644 --- a/examples/opcua/CMakeLists.txt +++ b/examples/opcua/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause if(TARGET Qt6::Widgets) qt_internal_add_example(opcuaviewer) diff --git a/examples/opcua/opcuaviewer/CMakeLists.txt b/examples/opcua/opcuaviewer/CMakeLists.txt index 1445a85..1b8aae9 100644 --- a/examples/opcua/opcuaviewer/CMakeLists.txt +++ b/examples/opcua/opcuaviewer/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(opcuaviewer LANGUAGES CXX) diff --git a/examples/opcua/waterpump/CMakeLists.txt b/examples/opcua/waterpump/CMakeLists.txt index 218d5bd..0119ac2 100644 --- a/examples/opcua/waterpump/CMakeLists.txt +++ b/examples/opcua/waterpump/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause if(NOT ANDROID) qt_internal_add_example(simulationserver) diff --git a/examples/opcua/waterpump/simulationserver/CMakeLists.txt b/examples/opcua/waterpump/simulationserver/CMakeLists.txt index 0a35e62..8f8cd6d 100644 --- a/examples/opcua/waterpump/simulationserver/CMakeLists.txt +++ b/examples/opcua/waterpump/simulationserver/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(simulationserver LANGUAGES CXX C) diff --git a/examples/opcua/waterpump/waterpump-qml/CMakeLists.txt b/examples/opcua/waterpump/waterpump-qml/CMakeLists.txt index 3d8bd92..ca6ed06 100644 --- a/examples/opcua/waterpump/waterpump-qml/CMakeLists.txt +++ b/examples/opcua/waterpump/waterpump-qml/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(waterpump-qml LANGUAGES CXX) diff --git a/examples/opcua/waterpump/waterpump-qmlcpp/CMakeLists.txt b/examples/opcua/waterpump/waterpump-qmlcpp/CMakeLists.txt index 4cd865e..98c5f22 100644 --- a/examples/opcua/waterpump/waterpump-qmlcpp/CMakeLists.txt +++ b/examples/opcua/waterpump/waterpump-qmlcpp/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(waterpump-qmlcpp LANGUAGES CXX) diff --git a/examples/opcua/x509/CMakeLists.txt b/examples/opcua/x509/CMakeLists.txt index 1159788..a40c35e 100644 --- a/examples/opcua/x509/CMakeLists.txt +++ b/examples/opcua/x509/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(x509 LANGUAGES CXX) diff --git a/src/opcua/client/qopcuagenericstructhandlerprivate.cpp b/src/opcua/client/qopcuagenericstructhandlerprivate.cpp index 0f74655..a0f8e1f 100644 --- a/src/opcua/client/qopcuagenericstructhandlerprivate.cpp +++ b/src/opcua/client/qopcuagenericstructhandlerprivate.cpp @@ -302,6 +302,9 @@ QVariant QOpcUaGenericStructHandlerPrivate::decodeKnownTypesInternal(QOpcUaBinar if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::NodeId)) return decodeArrayOrScalar<QString, QOpcUa::Types::NodeId>(decoder, valueRank, success); + if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::ByteString)) + return decodeArrayOrScalar<QByteArray>(decoder, valueRank, success); + if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::XmlElement)) return decodeArrayOrScalar<QByteArray>(decoder, valueRank, success); @@ -576,6 +579,9 @@ bool QOpcUaGenericStructHandlerPrivate::encodeKnownTypesInternal(QOpcUaBinaryDat if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::NodeId)) return encodeArrayOrScalar<QString, QOpcUa::Types::NodeId>(encoder, valueRank, value); + if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::ByteString)) + return encodeArrayOrScalar<QByteArray>(encoder, valueRank, value); + if (dataTypeId == QOpcUa::namespace0Id(QOpcUa::NodeIds::Namespace0::XmlElement)) return encodeArrayOrScalar<QByteArray>(encoder, valueRank, value); diff --git a/src/plugins/opcua/open62541/qopen62541subscription.cpp b/src/plugins/opcua/open62541/qopen62541subscription.cpp index 0128de3..f8a533d 100644 --- a/src/plugins/opcua/open62541/qopen62541subscription.cpp +++ b/src/plugins/opcua/open62541/qopen62541subscription.cpp @@ -470,7 +470,7 @@ void QOpen62541Subscription::monitoredValueUpdated(UA_UInt32 monId, UA_DataValue res.setServerTimestamp(QOpen62541ValueConverter::scalarToQt<QDateTime, UA_DateTime>(&value->serverTimestamp)); if (value->hasSourceTimestamp) res.setSourceTimestamp(QOpen62541ValueConverter::scalarToQt<QDateTime, UA_DateTime>(&value->sourceTimestamp)); - res.setStatusCode(QOpcUa::UaStatusCode::Good); + res.setStatusCode(value->hasStatus ? QOpcUa::UaStatusCode(value->status) : QOpcUa::UaStatusCode::Good); emit m_backend->dataChangeOccurred(item.value()->handle, res); } diff --git a/tests/auto/qopcuaclient/tst_client.cpp b/tests/auto/qopcuaclient/tst_client.cpp index a42e5d8..a1e3f22 100644 --- a/tests/auto/qopcuaclient/tst_client.cpp +++ b/tests/auto/qopcuaclient/tst_client.cpp @@ -606,6 +606,8 @@ private slots: void modifyMonitoredItem(); defineDataMethod(addDuplicateMonitoredItem_data) void addDuplicateMonitoredItem(); + defineDataMethod(subscriptionUnreadableNode_data); + void subscriptionUnreadableNode(); defineDataMethod(checkMonitoredItemCleanup_data); void checkMonitoredItemCleanup(); defineDataMethod(checkAttributeUpdated_data); @@ -4433,6 +4435,39 @@ void Tst_QOpcUaClient::addDuplicateMonitoredItem() QCOMPARE(monitoringDisabledSpy.at(0).at(1).value<QOpcUa::UaStatusCode>(), QOpcUa::UaStatusCode::Good); } +void Tst_QOpcUaClient::subscriptionUnreadableNode() +{ + QFETCH(QOpcUaClient *, opcuaClient); + OpcuaConnector connector(opcuaClient, m_endpoint); + + QScopedPointer<QOpcUaNode> unreadableNode(opcuaClient->node("ns=3;s=VariableWithoutReadPermission")); + QVERIFY(unreadableNode != nullptr); + + QOpcUaMonitoringParameters p(100); + p.setIndexRange(QStringLiteral("1")); + QSignalSpy monitoringEnabledSpy(unreadableNode.data(), &QOpcUaNode::enableMonitoringFinished); + QSignalSpy monitoringDisabledSpy(unreadableNode.data(), &QOpcUaNode::disableMonitoringFinished); + QSignalSpy dataChangeSpy(unreadableNode.data(), &QOpcUaNode::dataChangeOccurred); + + unreadableNode->enableMonitoring(QOpcUa::NodeAttribute::Value, p); + monitoringEnabledSpy.wait(signalSpyTimeout); + QCOMPARE(monitoringEnabledSpy.size(), 1); + QCOMPARE(monitoringEnabledSpy.at(0).at(0).value<QOpcUa::NodeAttribute>(), QOpcUa::NodeAttribute::Value); + QCOMPARE(monitoringEnabledSpy.at(0).at(1).value<QOpcUa::UaStatusCode>(), QOpcUa::UaStatusCode::Good); + + // Wait for the initial data change + dataChangeSpy.wait(signalSpyTimeout); + QCOMPARE(dataChangeSpy.size(), 1); + QCOMPARE(dataChangeSpy.at(0).at(0).value<QOpcUa::NodeAttribute>(), QOpcUa::NodeAttribute::Value); + QCOMPARE(dataChangeSpy.at(0).at(1), QVariant()); + QCOMPARE(unreadableNode->valueAttribute(), QVariant()); + QCOMPARE(unreadableNode->valueAttributeError(), QOpcUa::UaStatusCode::BadNotReadable); + + unreadableNode->disableMonitoring(QOpcUa::NodeAttribute::Value); + monitoringDisabledSpy.wait(signalSpyTimeout); + QCOMPARE(monitoringDisabledSpy.size(), 1); +} + void Tst_QOpcUaClient::checkMonitoredItemCleanup() { QFETCH(QOpcUaClient *, opcuaClient); diff --git a/tests/open62541-testserver/main.cpp b/tests/open62541-testserver/main.cpp index 7d40f26..947bcbe 100644 --- a/tests/open62541-testserver/main.cpp +++ b/tests/open62541-testserver/main.cpp @@ -306,6 +306,8 @@ int main() server.addServerStatusTypeTestNodes(testFolder); + server.addUnreadableVariableNode(testFolder); + // Add test nodes for the generic type decoder auto result = server.addEncoderTestModel(); diff --git a/tests/open62541-testserver/testserver.cpp b/tests/open62541-testserver/testserver.cpp index 860eb0b..ea0ddbe 100644 --- a/tests/open62541-testserver/testserver.cpp +++ b/tests/open62541-testserver/testserver.cpp @@ -1374,6 +1374,33 @@ UA_StatusCode TestServer::addEncoderTestModel() return result; } +UA_StatusCode TestServer::addUnreadableVariableNode(const UA_NodeId &parent) +{ + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.value = QOpen62541ValueConverter::toOpen62541Variant(42, QOpcUa::Int32); + attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", "VariableWithoutReadPermission"); + attr.dataType = attr.value.type->typeId; + attr.accessLevel = UA_ACCESSLEVELMASK_WRITE; // Write only + + UA_QualifiedName variableName; + variableName.namespaceIndex = parent.namespaceIndex; + variableName.name = attr.displayName.text; + + auto nodeId = UA_NODEID_STRING_ALLOC(parent.namespaceIndex, "VariableWithoutReadPermission"); + UA_StatusCode result = UA_Server_addVariableNode(m_server, + nodeId, + parent, + UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), + variableName, + UA_NODEID_NULL, + attr, + nullptr, + nullptr); + UA_NodeId_clear(&nodeId); + UA_VariableAttributes_clear(&attr); + return result; +} + UA_StatusCode TestServer::addEventHistorian(const UA_NodeId &parent) { UA_ObjectAttributes attr = UA_ObjectAttributes_default; diff --git a/tests/open62541-testserver/testserver.h b/tests/open62541-testserver/testserver.h index cd59289..be5a012 100644 --- a/tests/open62541-testserver/testserver.h +++ b/tests/open62541-testserver/testserver.h @@ -50,6 +50,8 @@ public: UA_StatusCode addEncoderTestModel(); + UA_StatusCode addUnreadableVariableNode(const UA_NodeId &parent); + static UA_StatusCode multiplyMethod(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle, const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId, void *objectContext, |