summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/opcua/freeopcua/qfreeopcuaclient.cpp8
-rw-r--r--src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.cpp97
-rw-r--r--src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.h1
3 files changed, 105 insertions, 1 deletions
diff --git a/src/plugins/opcua/freeopcua/qfreeopcuaclient.cpp b/src/plugins/opcua/freeopcua/qfreeopcuaclient.cpp
index a84aceb..9afe4ff 100644
--- a/src/plugins/opcua/freeopcua/qfreeopcuaclient.cpp
+++ b/src/plugins/opcua/freeopcua/qfreeopcuaclient.cpp
@@ -36,6 +36,7 @@
#include "qfreeopcuaclient.h"
#include "qfreeopcuanode.h"
+#include "qfreeopcuavalueconverter.h"
#include "qfreeopcuaworker.h"
#include <private/qopcuaclient_p.h>
@@ -79,8 +80,13 @@ QOpcUaNode *QFreeOpcUaClientImpl::node(const QString &nodeId)
if (!m_opcuaWorker)
return nullptr;
+ OpcUa::NodeId id = QFreeOpcUaValueConverter::stringToNodeId(nodeId);
+
+ if (id.IsNull())
+ return nullptr;
+
try {
- OpcUa::Node node = m_opcuaWorker->GetNode(nodeId.toStdString());
+ OpcUa::Node node = m_opcuaWorker->GetNode(id);
QFreeOpcUaNode *n = new QFreeOpcUaNode(node, this);
return new QOpcUaNode(n, m_client);
} catch (const std::exception &ex) {
diff --git a/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.cpp b/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.cpp
index 4591c9d..d1dd6f8 100644
--- a/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.cpp
+++ b/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.cpp
@@ -418,6 +418,103 @@ QOpcUa::UaStatusCode exceptionToStatusCode(const std::exception &ex)
return statusCode;
}
+OpcUa::NodeId stringToNodeId(const QString &id)
+{
+ const int semicolonIndex = id.indexOf(';');
+
+ if (semicolonIndex <= 0) {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "Unable to split node id string:" << qUtf8Printable(id);
+ return OpcUa::NodeId();
+ }
+
+ QStringRef namespaceString = id.leftRef(semicolonIndex);
+ if (namespaceString.length() <= 3 || !namespaceString.startsWith(QLatin1String("ns="))) {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "Not a valid index string in node id string:" << id;
+ return OpcUa::NodeId();
+ }
+ namespaceString = namespaceString.mid(3); // Remove "ns="
+
+ QStringRef identifierString = id.midRef(semicolonIndex + 1);
+
+ if (identifierString.length() <= 2) {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "There is no identifier in node id string:" << id;
+ return OpcUa::NodeId();
+ }
+
+ char identifierType;
+ if (identifierString.startsWith(QLatin1String("s=")))
+ identifierType = 's';
+ else if (identifierString.startsWith(QLatin1String("i=")))
+ identifierType = 'i';
+ else if (identifierString.startsWith(QLatin1String("g=")))
+ identifierType = 'g';
+ else if (identifierString.startsWith(QLatin1String("b=")))
+ identifierType = 'b';
+ else {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "There is no valid identifier type in node id string:" << id;
+ return OpcUa::NodeId();
+ }
+ identifierString = identifierString.mid(2); // Remove identifier type
+
+ bool ok = false;
+ quint16 index = static_cast<quint16>(namespaceString.toUInt(&ok));
+
+ if (!ok) {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "Not a valid namespace index in node id string:" << id;
+ return OpcUa::NodeId();
+ }
+
+ switch (identifierType) {
+ case 'i': {
+ bool isNumber;
+ quint32 identifier = static_cast<quint32>(identifierString.toUInt(&isNumber));
+ if (isNumber)
+ return OpcUa::NumericNodeId(identifier, index);
+ else
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << id << "does not contain a valid numeric identifier";
+ break;
+ }
+ case 's': {
+ if (identifierString.length() > 0) {
+ return OpcUa::StringNodeId(identifierString.toString().toStdString(), index);
+ }
+ else
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << id << "does not contain a valid string identifier";
+ break;
+ }
+ case 'g': {
+ QUuid uuid(identifierString.toString());
+
+ if (uuid.isNull()) {
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << id << "does not contain a valid guid identifier";
+ }
+
+ OpcUa::Guid guid;
+ guid.Data1 = uuid.data1;
+ guid.Data2 = uuid.data2;
+ guid.Data3 = uuid.data3;
+ std::memcpy(guid.Data4, uuid.data4, sizeof(uuid.data4));
+ return OpcUa::GuidNodeId(guid, index);
+ }
+ case 'b': {
+ const QByteArray temp = QByteArray::fromBase64(identifierString.toLocal8Bit());
+ if (temp.size() > 0) {
+ OpcUa::NodeId result;
+ result.Encoding = OpcUa::NodeIdEncoding::EV_BYTE_STRING;
+ result.BinaryData.NamespaceIndex = index;
+ result.BinaryData.Identifier.assign(temp.data(), temp.data() + temp.size());
+ return result;
+ }
+ else
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << id << "does not contain a valid byte string identifier";
+ break;
+ }
+ default:
+ qCWarning(QT_OPCUA_PLUGINS_FREEOPCUA) << "Could not parse node id:" << id;
+ }
+ return OpcUa::NodeId();
+}
+
}
QT_END_NAMESPACE
diff --git a/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.h b/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.h
index 13fb368..0c6962e 100644
--- a/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.h
+++ b/src/plugins/opcua/freeopcua/qfreeopcuavalueconverter.h
@@ -56,6 +56,7 @@ namespace QFreeOpcUaValueConverter
QVariant toQVariant(const OpcUa::Variant &variant);
OpcUa::Variant toTypedVariant(const QVariant &variant, QOpcUa::Types type);
QString nodeIdToString(const OpcUa::NodeId &id);
+ OpcUa::NodeId stringToNodeId(const QString &id);
QOpcUa::UaStatusCode exceptionToStatusCode(const std::exception &ex);