summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJannis Voelker <jannis.voelker@basyskom.com>2018-04-06 08:15:23 +0200
committerFrank Meerkoetter <frank.meerkoetter@basyskom.com>2018-08-17 08:25:15 +0000
commit363e423d86039fecdb750dda15c680a2fcef5e4c (patch)
treef76e07ce1ce1e6622329297011993c9d0f693302 /src
parentd76b4776ebace5627e02361aa636c88d5f9e790c (diff)
Add node management
This patch adds a node management API to Qt OPC UA. The support is open62541 only for now. - addNode() - deleteNode() - addReference() - deleteReference() Change-Id: I60631346a1a4a097ba4555e4bb3cbc93c71efee8 Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com>
Diffstat (limited to 'src')
-rw-r--r--src/opcua/client/client.pri13
-rw-r--r--src/opcua/client/qopcuaaddnodeitem.cpp215
-rw-r--r--src/opcua/client/qopcuaaddnodeitem.h84
-rw-r--r--src/opcua/client/qopcuaaddreferenceitem.cpp189
-rw-r--r--src/opcua/client/qopcuaaddreferenceitem.h80
-rw-r--r--src/opcua/client/qopcuabackend_p.h7
-rw-r--r--src/opcua/client/qopcuaclient.cpp162
-rw-r--r--src/opcua/client/qopcuaclient.h15
-rw-r--r--src/opcua/client/qopcuaclientimpl.cpp4
-rw-r--r--src/opcua/client/qopcuaclientimpl_p.h12
-rw-r--r--src/opcua/client/qopcuaclientprivate.cpp22
-rw-r--r--src/opcua/client/qopcuadeletereferenceitem.cpp169
-rw-r--r--src/opcua/client/qopcuadeletereferenceitem.h77
-rw-r--r--src/opcua/client/qopcuanodecreationattributes.cpp776
-rw-r--r--src/opcua/client/qopcuanodecreationattributes.h146
-rw-r--r--src/opcua/client/qopcuanodecreationattributes_p.h124
-rw-r--r--src/opcua/client/qopcuatype.cpp59
-rw-r--r--src/opcua/client/qopcuatype.h62
-rw-r--r--src/opcua/core/qopcuaprovider.cpp4
-rw-r--r--src/opcua/doc/src/qtopcua.qdoc3
-rw-r--r--src/plugins/opcua/open62541/qopen62541backend.cpp277
-rw-r--r--src/plugins/opcua/open62541/qopen62541backend.h9
-rw-r--r--src/plugins/opcua/open62541/qopen62541client.cpp25
-rw-r--r--src/plugins/opcua/open62541/qopen62541client.h6
-rw-r--r--src/plugins/opcua/uacpp/quacppclient.cpp33
-rw-r--r--src/plugins/opcua/uacpp/quacppclient.h6
26 files changed, 2577 insertions, 2 deletions
diff --git a/src/opcua/client/client.pri b/src/opcua/client/client.pri
index 44eb9fc..c6167d3 100644
--- a/src/opcua/client/client.pri
+++ b/src/opcua/client/client.pri
@@ -21,7 +21,11 @@ SOURCES += \
client/qopcuareadresult.cpp \
client/qopcuanodeids.cpp \
client/qopcuawriteitem.cpp \
- client/qopcuawriteresult.cpp
+ client/qopcuawriteresult.cpp \
+ client/qopcuanodecreationattributes.cpp \
+ client/qopcuaaddreferenceitem.cpp \
+ client/qopcuadeletereferenceitem.cpp \
+ client/qopcuaaddnodeitem.cpp
HEADERS += \
client/qopcuaclient_p.h \
@@ -38,4 +42,9 @@ HEADERS += \
client/qopcuareadresult.h \
client/qopcuanodeids.h \
client/qopcuawriteitem.h \
- client/qopcuawriteresult.h
+ client/qopcuawriteresult.h \
+ client/qopcuanodecreationattributes.h \
+ client/qopcuanodecreationattributes_p.h \
+ client/qopcuaaddnodeitem.h \
+ client/qopcuaaddreferenceitem.h \
+ client/qopcuadeletereferenceitem.h
diff --git a/src/opcua/client/qopcuaaddnodeitem.cpp b/src/opcua/client/qopcuaaddnodeitem.cpp
new file mode 100644
index 0000000..62eea3e
--- /dev/null
+++ b/src/opcua/client/qopcuaaddnodeitem.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopcuanodecreationattributes.h"
+#include "qopcuaaddnodeitem.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpcUaAddNodeItem
+ \inmodule QtOpcUa
+ \brief This class stores the necessary information to create a new node on the server.
+
+ \sa QOpcUaClient::addNode()
+*/
+
+class QOpcUaAddNodeItemData : public QSharedData
+{
+public:
+ QOpcUa::QExpandedNodeId parentNodeId;
+ QString referenceTypeId;
+ QOpcUa::QExpandedNodeId requestedNewNodeId;
+ QOpcUa::QQualifiedName browseName;
+ QOpcUa::NodeClass nodeClass {QOpcUa::NodeClass::Object};
+ QOpcUaNodeCreationAttributes nodeAttributes;
+ QOpcUa::QExpandedNodeId typeDefinition;
+};
+
+QOpcUaAddNodeItem::QOpcUaAddNodeItem()
+ : data(new QOpcUaAddNodeItemData)
+{
+}
+
+/*!
+ Constructs a add node item from \a other.
+*/
+QOpcUaAddNodeItem::QOpcUaAddNodeItem(const QOpcUaAddNodeItem &other)
+ : data(other.data)
+{
+}
+
+/*!
+ Assigns the values from \a rhs to this add node item.
+*/
+QOpcUaAddNodeItem &QOpcUaAddNodeItem::operator=(const QOpcUaAddNodeItem &rhs)
+{
+ if (this != &rhs)
+ data.operator=(rhs.data);
+ return *this;
+}
+
+QOpcUaAddNodeItem::~QOpcUaAddNodeItem()
+{
+}
+
+/*!
+ Returns the node id of the type definition node.
+*/
+QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::typeDefinition() const
+{
+ return data->typeDefinition;
+}
+
+/*!
+ Sets the node id of the type definition node to \a typeDefinition. This value shall be set if the node class
+ is not Object or Variable.
+*/
+void QOpcUaAddNodeItem::setTypeDefinition(const QOpcUa::QExpandedNodeId &typeDefinition)
+{
+ data->typeDefinition = typeDefinition;
+}
+
+/*!
+ Returns the values for the node attributes of the new node.
+*/
+QOpcUaNodeCreationAttributes QOpcUaAddNodeItem::nodeAttributes() const
+{
+ return data->nodeAttributes;
+}
+
+/*!
+ Returns a reference to the values for the node attributes of the new node.
+*/
+QOpcUaNodeCreationAttributes &QOpcUaAddNodeItem::nodeAttributesRef()
+{
+ return data->nodeAttributes;
+}
+
+/*!
+ Sets the values for the node attributes of the new node to \a nodeAttributes.
+ Only the attributes supported by the node class of the new node will be used.
+*/
+void QOpcUaAddNodeItem::setNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes)
+{
+ data->nodeAttributes = nodeAttributes;
+}
+
+/*!
+ Returns the node class of the new node.
+*/
+QOpcUa::NodeClass QOpcUaAddNodeItem::nodeClass() const
+{
+ return data->nodeClass;
+}
+
+/*!
+ Sets the node class of the new node to \a nodeClass.
+*/
+void QOpcUaAddNodeItem::setNodeClass(const QOpcUa::NodeClass &nodeClass)
+{
+ data->nodeClass = nodeClass;
+}
+
+/*!
+ Returns the browse name of the new node.
+*/
+QOpcUa::QQualifiedName QOpcUaAddNodeItem::browseName() const
+{
+ return data->browseName;
+}
+
+/*!
+ Sets the browse name of the new node to \a browseName.
+*/
+void QOpcUaAddNodeItem::setBrowseName(const QOpcUa::QQualifiedName &browseName)
+{
+ data->browseName = browseName;
+}
+
+/*!
+ Returns the requested new node id.
+*/
+QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::requestedNewNodeId() const
+{
+ return data->requestedNewNodeId;
+}
+
+/*!
+ Sets the requested new node id to \a requestedNewNodeId.
+*/
+void QOpcUaAddNodeItem::setRequestedNewNodeId(const QOpcUa::QExpandedNodeId &requestedNewNodeId)
+{
+ data->requestedNewNodeId = requestedNewNodeId;
+}
+
+/*!
+ Returns the reference type id.
+*/
+QString QOpcUaAddNodeItem::referenceTypeId() const
+{
+ return data->referenceTypeId;
+}
+
+/*!
+ Sets the reference type id to \a referenceTypeId. A reference of this type will be used to connect
+ the node to the parent node.
+*/
+void QOpcUaAddNodeItem::setReferenceTypeId(const QString &referenceTypeId)
+{
+ data->referenceTypeId = referenceTypeId;
+}
+
+/*!
+ Returns the parent node id.
+*/
+QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::parentNodeId() const
+{
+ return data->parentNodeId;
+}
+
+/*!
+ Sets the parent node id to \a parentNodeId. A reference of the type set in \l setReferenceTypeId()
+ from this node to the newly added node will be created.
+
+ \sa setReferenceTypeId()
+*/
+void QOpcUaAddNodeItem::setParentNodeId(const QOpcUa::QExpandedNodeId &parentNodeId)
+{
+ data->parentNodeId = parentNodeId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opcua/client/qopcuaaddnodeitem.h b/src/opcua/client/qopcuaaddnodeitem.h
new file mode 100644
index 0000000..188dba7
--- /dev/null
+++ b/src/opcua/client/qopcuaaddnodeitem.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPCUADDNODEITEM_H
+#define QOPCUADDNODEITEM_H
+
+#include <QtOpcUa/qopcuanodecreationattributes.h>
+#include <QtOpcUa/qopcuatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaAddNodeItemData;
+class Q_OPCUA_EXPORT QOpcUaAddNodeItem
+{
+public:
+ QOpcUaAddNodeItem();
+ QOpcUaAddNodeItem(const QOpcUaAddNodeItem &);
+ QOpcUaAddNodeItem &operator=(const QOpcUaAddNodeItem &);
+ ~QOpcUaAddNodeItem();
+
+ QOpcUa::QExpandedNodeId parentNodeId() const;
+ void setParentNodeId(const QOpcUa::QExpandedNodeId &parentNodeId);
+
+ QString referenceTypeId() const;
+ void setReferenceTypeId(const QString &referenceTypeId);
+
+ QOpcUa::QExpandedNodeId requestedNewNodeId() const;
+ void setRequestedNewNodeId(const QOpcUa::QExpandedNodeId &requestedNewNodeId);
+
+ QOpcUa::QQualifiedName browseName() const;
+ void setBrowseName(const QOpcUa::QQualifiedName &browseName);
+
+ QOpcUa::NodeClass nodeClass() const;
+ void setNodeClass(const QOpcUa::NodeClass &nodeClass);
+
+ QOpcUaNodeCreationAttributes nodeAttributes() const;
+ QOpcUaNodeCreationAttributes &nodeAttributesRef();
+ void setNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes);
+
+ QOpcUa::QExpandedNodeId typeDefinition() const;
+ void setTypeDefinition(const QOpcUa::QExpandedNodeId &typeDefinition);
+
+private:
+ QSharedDataPointer<QOpcUaAddNodeItemData> data;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QOpcUaAddNodeItem)
+
+#endif // QOPCUADDNODEITEM_H
diff --git a/src/opcua/client/qopcuaaddreferenceitem.cpp b/src/opcua/client/qopcuaaddreferenceitem.cpp
new file mode 100644
index 0000000..305500e
--- /dev/null
+++ b/src/opcua/client/qopcuaaddreferenceitem.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopcuanodecreationattributes.h"
+#include "qopcuaaddreferenceitem.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpcUaAddReferenceItem
+ \inmodule QtOpcUa
+ \brief This class stores the necessary information to add a new reference on the server.
+
+ \sa QOpcUaClient::addReference()
+*/
+class QOpcUaAddReferenceItemData : public QSharedData
+{
+public:
+ QString sourceNodeId;
+ QString referenceTypeId;
+ bool isForward {true};
+ QOpcUa::QExpandedNodeId targetNodeId;
+ QOpcUa::NodeClass targetNodeClass {QOpcUa::NodeClass::Undefined};
+ QString targetServerUri;
+};
+
+QOpcUaAddReferenceItem::QOpcUaAddReferenceItem()
+ : data(new QOpcUaAddReferenceItemData)
+{
+}
+
+/*!
+ Constructs an add reference item from \a other.
+*/
+QOpcUaAddReferenceItem::QOpcUaAddReferenceItem(const QOpcUaAddReferenceItem &other)
+ : data(other.data)
+{
+
+}
+
+/*!
+ Sets the values from \a rhs in this add reference item.
+*/
+QOpcUaAddReferenceItem &QOpcUaAddReferenceItem::operator=(const QOpcUaAddReferenceItem &rhs)
+{
+ if (this != &rhs)
+ data.operator=(rhs.data);
+ return *this;
+}
+
+QOpcUaAddReferenceItem::~QOpcUaAddReferenceItem()
+{
+}
+
+/*!
+ Returns the target node class.
+*/
+QOpcUa::NodeClass QOpcUaAddReferenceItem::targetNodeClass() const
+{
+ return data->targetNodeClass;
+}
+
+/*!
+ Sets the node class of the target node to \a targetNodeClass.
+ The target node class shall be specified because the target node might be located on another server.
+*/
+void QOpcUaAddReferenceItem::setTargetNodeClass(QOpcUa::NodeClass targetNodeClass)
+{
+ data->targetNodeClass = targetNodeClass;
+}
+
+/*!
+ Returns the target server URI.
+*/
+QString QOpcUaAddReferenceItem::targetServerUri() const
+{
+ return data->targetServerUri;
+}
+
+/*!
+ Sets the URI of the target server to \a targetServerUri.
+ If this value is set, it will override the server URI from \l setTargetNodeId().
+*/
+void QOpcUaAddReferenceItem::setTargetServerUri(const QString &targetServerUri)
+{
+ data->targetServerUri = targetServerUri;
+}
+
+/*!
+ Returns the target node id.
+*/
+QOpcUa::QExpandedNodeId QOpcUaAddReferenceItem::targetNodeId() const
+{
+ return data->targetNodeId;
+}
+
+/*!
+ Sets the node id of the target node to \a targetNodeId.
+*/
+void QOpcUaAddReferenceItem::setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId)
+{
+ data->targetNodeId = targetNodeId;
+}
+
+/*!
+ Returns the isForward flag.
+*/
+bool QOpcUaAddReferenceItem::isForward() const
+{
+ return data->isForward;
+}
+
+/*!
+ Sets the isForward flag to \a isForward.
+ If the flag is set, a forward reference is created.
+ Otherwise, an inverse reference is created.
+*/
+void QOpcUaAddReferenceItem::setIsForward(bool isForward)
+{
+ data->isForward = isForward;
+}
+
+/*!
+ Returns the reference type id.
+*/
+QString QOpcUaAddReferenceItem::referenceTypeId() const
+{
+ return data->referenceTypeId;
+}
+
+/*!
+ Sets the reference type id to \a referenceTypeId.
+ A reference of this type will be created on the server.
+*/
+void QOpcUaAddReferenceItem::setReferenceTypeId(const QString &referenceTypeId)
+{
+ data->referenceTypeId = referenceTypeId;
+}
+
+/*!
+ Returns the source node id.
+*/
+QString QOpcUaAddReferenceItem::sourceNodeId() const
+{
+ return data->sourceNodeId;
+}
+
+/*!
+ Sets the node id of the source node to \a sourceNodeId.
+*/
+void QOpcUaAddReferenceItem::setSourceNodeId(const QString &sourceNodeId)
+{
+ data->sourceNodeId = sourceNodeId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opcua/client/qopcuaaddreferenceitem.h b/src/opcua/client/qopcuaaddreferenceitem.h
new file mode 100644
index 0000000..eb50bf4
--- /dev/null
+++ b/src/opcua/client/qopcuaaddreferenceitem.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPCUAADDREFERENCEITEM_H
+#define QOPCUAADDREFERENCEITEM_H
+
+#include <QtOpcUa/qopcuanodecreationattributes.h>
+#include <QtOpcUa/qopcuatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaAddReferenceItemData;
+class Q_OPCUA_EXPORT QOpcUaAddReferenceItem
+{
+public:
+ QOpcUaAddReferenceItem();
+ QOpcUaAddReferenceItem(const QOpcUaAddReferenceItem &other);
+ QOpcUaAddReferenceItem &operator=(const QOpcUaAddReferenceItem &rhs);
+ ~QOpcUaAddReferenceItem();
+
+ QString sourceNodeId() const;
+ void setSourceNodeId(const QString &sourceNodeId);
+
+ QString referenceTypeId() const;
+ void setReferenceTypeId(const QString &referenceTypeId);
+
+ bool isForward() const;
+ void setIsForward(bool isForward);
+
+ QOpcUa::QExpandedNodeId targetNodeId() const;
+ void setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId);
+
+ QOpcUa::NodeClass targetNodeClass() const;
+ void setTargetNodeClass(QOpcUa::NodeClass targetNodeClass);
+
+ QString targetServerUri() const;
+ void setTargetServerUri(const QString &targetServerUri);
+
+private:
+ QSharedDataPointer<QOpcUaAddReferenceItemData> data;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QOpcUaAddReferenceItem)
+
+#endif // QOPCUAADDREFERENCEITEM_H
diff --git a/src/opcua/client/qopcuabackend_p.h b/src/opcua/client/qopcuabackend_p.h
index 5ed80b7..628d2a5 100644
--- a/src/opcua/client/qopcuabackend_p.h
+++ b/src/opcua/client/qopcuabackend_p.h
@@ -97,6 +97,13 @@ Q_SIGNALS:
void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult);
void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult);
+ void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode);
+ void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode);
+ void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
+ void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
+
private:
Q_DISABLE_COPY(QOpcUaBackend)
};
diff --git a/src/opcua/client/qopcuaclient.cpp b/src/opcua/client/qopcuaclient.cpp
index de4e863..f484df7 100644
--- a/src/opcua/client/qopcuaclient.cpp
+++ b/src/opcua/client/qopcuaclient.cpp
@@ -214,6 +214,39 @@ Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA)
*/
/*!
+ \fn void QOpcUaClient::addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode)
+
+ This signal is emitted after an \l addNode() operation has finished.
+ \a requestedNodeId is the requested node id from the \l addNode() call, \a assignedNodeId is the node id the server has assigned to the new node.
+ \a statusCode contains the result of the operation. If the result is \l {QOpcUa::UaStatusCode} {Bad}, \a assignedNodeId is empty and no node
+ has been added to the server's address space.
+*/
+
+/*!
+ \fn void QOpcUaClient::deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode)
+
+ This signal is emitted after a \l deleteNode() operation has finished.
+ \a nodeId is the node id from the \l deleteNode() call.
+ \a statusCode contains the result of the operation.
+*/
+
+/*!
+ \fn void QOpcUaClient::addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode)
+
+ This signal is emitted after an \l addReference() operation has finished.
+ \a sourceNodeId, \a referenceTypeId, \a targetNodeId and \a isForward are the values from the \l addReference() call.
+ \a statusCode contains the result of the operation.
+*/
+
+/*!
+ \fn void QOpcUaClient::deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode)
+
+ This signal is emitted after a \l deleteReference() operation has finished.
+ \a sourceNodeId, \a referenceTypeId, \a targetNodeId and \a isForward are the values from the \l deleteReference() call.
+ \a statusCode contains the result of the operation.
+*/
+
+/*!
\internal QOpcUaClientImpl is an opaque type (as seen from the public API).
This prevents users of the public API to use this constructor (eventhough
it is public).
@@ -439,6 +472,135 @@ QOpcUa::QQualifiedName QOpcUaClient::qualifiedNameFromNamespaceUri(const QString
*ok = true;
return QOpcUa::QQualifiedName(index, name);
+};
+
+/*!
+ Adds the node described by \a nodeToAdd on the server.
+
+ Returns \c true if the asynchronous call has been successfully dispatched.
+
+ The success of the operation is returned in the \l addNodeFinished() signal.
+
+ The following example code adds new a Variable node on the server:
+
+ \code
+ QOpcUaNodeCreationAttributes attributes;
+ attributes.setDisplayName(QOpcUa::QLocalizedText("en", "My new Variable node"));
+ attributes.setDescription(QOpcUa::QLocalizedText("en", "A node which has been added at runtime"));
+ attributes.setValue(23.0, QOpcUa::Types::Double);
+ attributes.setDataTypeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::Double));
+ attributes.setValueRank(-2); // Scalar or array
+ attributes.setAccessLevel(QOpcUa::AccessLevelBit::CurrentRead);
+ attributes.setUserAccessLevel(QOpcUa::AccessLevelBit::CurrentRead);
+
+ QOpcUaAddNodeItem item;
+ item.setParentNodeId(QOpcUa::QExpandedNodeId("ns=3;s=TestFolder"));
+ item.setReferenceTypeId(QOpcUa::nodeIdFromReferenceType(QOpcUa::ReferenceTypeId::Organizes));
+ item.setRequestedNewNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode"));
+ item.setBrowseName(QOpcUa::QQualifiedName(3, "MyNewVariableNode"));
+ item.setNodeClass(QOpcUa::NodeClass::Variable);
+ item.setNodeAttributes(attributes);
+
+ m_client->addNode(item);
+ \endcode
+
+ \sa deleteNode() addNodeFinished() QOpcUaAddNodeItem
+*/
+bool QOpcUaClient::addNode(const QOpcUaAddNodeItem &nodeToAdd)
+{
+ if (state() != QOpcUaClient::Connected)
+ return false;
+
+ Q_D(QOpcUaClient);
+ return d->m_impl->addNode(nodeToAdd);
+}
+
+/*!
+ Deletes the node with node id \a nodeId from the server.
+ If \a deleteTargetReferences is \c false, only the references with source node \a nodeId are deleted.
+ If \a deleteTargetReferences is \c true, references with \a nodeId as target are deleted too.
+
+ Returns \c true if the asynchronous call has been successfully dispatched.
+
+ The success of the operation is returned in the \l deleteNodeFinished() signal.
+
+ The following example code deletes a node and all references to it from the server:
+
+ \code
+ m_client->deleteNode(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode"), true);
+ \endcode
+
+ \sa addNode() deleteNodeFinished()
+*/
+bool QOpcUaClient::deleteNode(const QString &nodeId, bool deleteTargetReferences)
+{
+ if (state() != QOpcUaClient::Connected)
+ return false;
+
+ Q_D(QOpcUaClient);
+ return d->m_impl->deleteNode(nodeId, deleteTargetReferences);
+}
+
+/*!
+ Adds the reference described by \a referenceToAdd to the server.
+
+ Returns \c true if the asynchronous call has been successfully dispatched.
+
+ The success of the operation is returned in the \l addReferenceFinished() signal.
+
+ The following example code adds a reference to a node to the "Objects" folder:
+
+ \code
+ QOpcUaAddReferenceItem item;
+ item.setSourceNodeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::ObjectsFolder));
+ item.setReferenceTypeId(QOpcUa::nodeIdFromInteger(0, static_cast<quint32>(QOpcUa::ReferenceTypeId::Organizes)));
+ item.setIsForward(true);
+ item.setTargetNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode"));
+ item.setTargetNodeClass(QOpcUa::NodeClass::Variable);
+
+ m_client->addReference(item);
+ \endcode
+
+ \sa deleteReference() addReferenceFinished() QOpcUaAddReferenceItem
+*/
+bool QOpcUaClient::addReference(const QOpcUaAddReferenceItem &referenceToAdd)
+{
+ if (state() != QOpcUaClient::Connected)
+ return false;
+
+ Q_D(QOpcUaClient);
+ return d->m_impl->addReference(referenceToAdd);
+}
+
+/*!
+ Deletes the reference described by \a referenceToDelete from the server.
+
+ Returns \c true if the asynchronous call has been successfully dispatched.
+
+ The success of the operation is returned in the \l deleteReferenceFinished() signal.
+
+ The following example code deletes a reference to a node from the "Objects" folder:
+
+ \code
+ QOpcUaDeleteReferenceItem item;
+ item.setSourceNodeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::ObjectsFolder));
+ item.setReferenceTypeId(QOpcUa::nodeIdFromInteger(0, static_cast<quint32>(QOpcUa::ReferenceTypeId::Organizes)));
+ item.setIsForward(true);
+ item.setTargetNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode"));
+ item.setDeleteBidirectional(true);
+
+ m_client->deleteReference(item);
+ \endcode
+
+ \sa addReference() deleteReferenceFinished() QOpcUaDeleteReferenceItem
+*/
+bool QOpcUaClient::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete)
+{
+ if (state() != QOpcUaClient::Connected)
+ return false;
+
+ Q_D(QOpcUaClient);
+ return d->m_impl->deleteReference(referenceToDelete);
}
/*!
diff --git a/src/opcua/client/qopcuaclient.h b/src/opcua/client/qopcuaclient.h
index 7aca93b..c764f7c 100644
--- a/src/opcua/client/qopcuaclient.h
+++ b/src/opcua/client/qopcuaclient.h
@@ -43,6 +43,9 @@
#include <QtOpcUa/qopcuareadresult.h>
#include <QtOpcUa/qopcuawriteitem.h>
#include <QtOpcUa/qopcuawriteresult.h>
+#include <QtOpcUa/qopcuaaddnodeitem.h>
+#include <QtOpcUa/qopcuaaddreferenceitem.h>
+#include <QtOpcUa/qopcuadeletereferenceitem.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
@@ -98,6 +101,12 @@ public:
bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead);
bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite);
+ bool addNode(const QOpcUaAddNodeItem &nodeToAdd);
+ bool deleteNode(const QString &nodeId, bool deleteTargetReferences = true);
+
+ bool addReference(const QOpcUaAddReferenceItem &referenceToAdd);
+ bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete);
+
QUrl url() const;
ClientState state() const;
@@ -121,6 +130,12 @@ Q_SIGNALS:
void findServersFinished(QVector<QOpcUa::QApplicationDescription> servers, QOpcUa::UaStatusCode statusCode);
void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult);
void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult);
+ void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode);
+ void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode);
+ void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
+ void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
private:
Q_DISABLE_COPY(QOpcUaClient)
diff --git a/src/opcua/client/qopcuaclientimpl.cpp b/src/opcua/client/qopcuaclientimpl.cpp
index df83d40..3480c61 100644
--- a/src/opcua/client/qopcuaclientimpl.cpp
+++ b/src/opcua/client/qopcuaclientimpl.cpp
@@ -85,6 +85,10 @@ void QOpcUaClientImpl::connectBackendWithClient(QOpcUaBackend *backend)
connect(backend, &QOpcUaBackend::findServersFinished, this, &QOpcUaClientImpl::findServersFinished);
connect(backend, &QOpcUaBackend::batchReadFinished, this, &QOpcUaClientImpl::batchReadFinished);
connect(backend, &QOpcUaBackend::batchWriteFinished, this, &QOpcUaClientImpl::batchWriteFinished);
+ connect(backend, &QOpcUaBackend::addNodeFinished, this, &QOpcUaClientImpl::addNodeFinished);
+ connect(backend, &QOpcUaBackend::deleteNodeFinished, this, &QOpcUaClientImpl::deleteNodeFinished);
+ connect(backend, &QOpcUaBackend::addReferenceFinished, this, &QOpcUaClientImpl::addReferenceFinished);
+ connect(backend, &QOpcUaBackend::deleteReferenceFinished, this, &QOpcUaClientImpl::deleteReferenceFinished);
}
void QOpcUaClientImpl::handleAttributesRead(quint64 handle, QVector<QOpcUaReadResult> attr, QOpcUa::UaStatusCode serviceResult)
diff --git a/src/opcua/client/qopcuaclientimpl_p.h b/src/opcua/client/qopcuaclientimpl_p.h
index 0b6b8da..76ab9eb 100644
--- a/src/opcua/client/qopcuaclientimpl_p.h
+++ b/src/opcua/client/qopcuaclientimpl_p.h
@@ -83,6 +83,12 @@ public:
bool registerNode(QPointer<QOpcUaNodeImpl> obj);
void unregisterNode(QPointer<QOpcUaNodeImpl> obj);
+ virtual bool addNode(const QOpcUaAddNodeItem &nodeToAdd) = 0;
+ virtual bool deleteNode(const QString &nodeId, bool deleteTargetReferences) = 0;
+
+ virtual bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) = 0;
+ virtual bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) = 0;
+
void connectBackendWithClient(QOpcUaBackend *backend);
QOpcUaClient *m_client;
@@ -111,6 +117,12 @@ signals:
void findServersFinished(QVector<QOpcUa::QApplicationDescription> servers, QOpcUa::UaStatusCode statusCode);
void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult);
void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult);
+ void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode);
+ void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode);
+ void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
+ void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward,
+ QOpcUa::UaStatusCode statusCode);
private:
Q_DISABLE_COPY(QOpcUaClientImpl)
diff --git a/src/opcua/client/qopcuaclientprivate.cpp b/src/opcua/client/qopcuaclientprivate.cpp
index a186bf8..33d5285 100644
--- a/src/opcua/client/qopcuaclientprivate.cpp
+++ b/src/opcua/client/qopcuaclientprivate.cpp
@@ -81,6 +81,28 @@ QOpcUaClientPrivate::QOpcUaClientPrivate(QOpcUaClientImpl *impl)
Q_Q(QOpcUaClient);
emit q->batchWriteFinished(results, serviceResult);
});
+
+ QObject::connect(m_impl.data(), &QOpcUaClientImpl::addNodeFinished, [this](const QOpcUa::QExpandedNodeId &requestedNodeId, const QString &assignedNodeId, QOpcUa::UaStatusCode statusCode) {
+ Q_Q(QOpcUaClient);
+ emit q->addNodeFinished(requestedNodeId, assignedNodeId, statusCode);
+ });
+
+ QObject::connect(m_impl.data(), &QOpcUaClientImpl::deleteNodeFinished, [this](const QString &nodeId, QOpcUa::UaStatusCode statusCode) {
+ Q_Q(QOpcUaClient);
+ emit q->deleteNodeFinished(nodeId, statusCode);
+ });
+
+ QObject::connect(m_impl.data(), &QOpcUaClientImpl::addReferenceFinished, [this](const QString &sourceNodeId, const QString &referenceTypeId,
+ const QOpcUa::QExpandedNodeId &targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) {
+ Q_Q(QOpcUaClient);
+ emit q->addReferenceFinished(sourceNodeId, referenceTypeId, targetNodeId, isForward, statusCode);
+ });
+
+ QObject::connect(m_impl.data(), &QOpcUaClientImpl::deleteReferenceFinished, [this](const QString &sourceNodeId, const QString &referenceTypeId,
+ const QOpcUa::QExpandedNodeId &targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) {
+ Q_Q(QOpcUaClient);
+ emit q->deleteReferenceFinished(sourceNodeId, referenceTypeId, targetNodeId, isForward, statusCode);
+ });
}
QOpcUaClientPrivate::~QOpcUaClientPrivate()
diff --git a/src/opcua/client/qopcuadeletereferenceitem.cpp b/src/opcua/client/qopcuadeletereferenceitem.cpp
new file mode 100644
index 0000000..abfcaa0
--- /dev/null
+++ b/src/opcua/client/qopcuadeletereferenceitem.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopcuanodecreationattributes.h"
+#include "qopcuadeletereferenceitem.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpcUaDeleteReferenceItem
+ \inmodule QtOpcUa
+ \brief This class stores the necessary information to delete a reference from the server.
+
+ \sa QOpcUaClient::deleteReference()
+*/
+
+class QOpcUaDeleteReferenceItemData : public QSharedData
+{
+public:
+ QString sourceNodeId;
+ QString referenceTypeId;
+ bool isForward {true};
+ QOpcUa::QExpandedNodeId targetNodeId;
+ bool deleteBidirectional {true};
+};
+
+QOpcUaDeleteReferenceItem::QOpcUaDeleteReferenceItem()
+ : data(new QOpcUaDeleteReferenceItemData)
+{
+}
+
+/*!
+ Constructs a delete reference item from \a other.
+*/
+QOpcUaDeleteReferenceItem::QOpcUaDeleteReferenceItem(const QOpcUaDeleteReferenceItem &other)
+ : data(other.data)
+{
+}
+
+/*!
+ Sets the values from \a rhs in this delete reference item.
+*/
+QOpcUaDeleteReferenceItem &QOpcUaDeleteReferenceItem::operator=(const QOpcUaDeleteReferenceItem &rhs)
+{
+ if (this != &rhs)
+ data.operator=(rhs.data);
+ return *this;
+}
+
+QOpcUaDeleteReferenceItem::~QOpcUaDeleteReferenceItem()
+{
+}
+
+/*!
+ Returns the deleteBidirectional Flag.
+*/
+bool QOpcUaDeleteReferenceItem::deleteBidirectional() const
+{
+ return data->deleteBidirectional;
+}
+
+/*!
+ Sets the deleteBidirectional flag to \a deleteBidirectional.
+ If this flag is false, only this reference will be deleted.
+ Else, the opposite reference from the target node is deleted too if accessible by the server.
+*/
+void QOpcUaDeleteReferenceItem::setDeleteBidirectional(bool deleteBidirectional)
+{
+ data->deleteBidirectional = deleteBidirectional;
+}
+
+/*!
+ Returns the target node id.
+*/
+QOpcUa::QExpandedNodeId QOpcUaDeleteReferenceItem::targetNodeId() const
+{
+ return data->targetNodeId;
+}
+
+/*!
+ Sets the node id of the target node to \a targetNodeId.
+*/
+void QOpcUaDeleteReferenceItem::setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId)
+{
+ data->targetNodeId = targetNodeId;
+}
+
+/*!
+ Returns the isForward flag.
+*/
+bool QOpcUaDeleteReferenceItem::isForward() const
+{
+ return data->isForward;
+}
+
+/*!
+ Sets the isForward flag to \a isForward.
+*/
+void QOpcUaDeleteReferenceItem::setIsForward(bool isForward)
+{
+ data->isForward = isForward;
+}
+
+/*!
+ Returns the reference type id.
+*/
+QString QOpcUaDeleteReferenceItem::referenceTypeId() const
+{
+ return data->referenceTypeId;
+}
+
+/*!
+ Sets the reference type id to \a referenceTypeId.
+*/
+void QOpcUaDeleteReferenceItem::setReferenceTypeId(const QString &referenceTypeId)
+{
+ data->referenceTypeId = referenceTypeId;
+}
+
+/*!
+ Returns the source node id.
+*/
+QString QOpcUaDeleteReferenceItem::sourceNodeId() const
+{
+ return data->sourceNodeId;
+}
+
+/*!
+ Sets the node id of the source node to \a sourceNodeId.
+*/
+void QOpcUaDeleteReferenceItem::setSourceNodeId(const QString &sourceNodeId)
+{
+ data->sourceNodeId = sourceNodeId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opcua/client/qopcuadeletereferenceitem.h b/src/opcua/client/qopcuadeletereferenceitem.h
new file mode 100644
index 0000000..7df305f
--- /dev/null
+++ b/src/opcua/client/qopcuadeletereferenceitem.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPCUADELETEREFERENCEITEM_H
+#define QOPCUADELETEREFERENCEITEM_H
+
+#include <QtOpcUa/qopcuanodecreationattributes.h>
+#include <QtOpcUa/qopcuatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaDeleteReferenceItemData;
+class Q_OPCUA_EXPORT QOpcUaDeleteReferenceItem
+{
+public:
+ QOpcUaDeleteReferenceItem();
+ QOpcUaDeleteReferenceItem(const QOpcUaDeleteReferenceItem &other);
+ QOpcUaDeleteReferenceItem &operator=(const QOpcUaDeleteReferenceItem &rhs);
+ ~QOpcUaDeleteReferenceItem();
+
+ QString sourceNodeId() const;
+ void setSourceNodeId(const QString &sourceNodeId);
+
+ QString referenceTypeId() const;
+ void setReferenceTypeId(const QString &referenceTypeId);
+
+ bool isForward() const;
+ void setIsForward(bool isForward);
+
+ QOpcUa::QExpandedNodeId targetNodeId() const;
+ void setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId);
+
+ bool deleteBidirectional() const;
+ void setDeleteBidirectional(bool deleteBidirectional);
+
+private:
+ QSharedDataPointer<QOpcUaDeleteReferenceItemData> data;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QOpcUaDeleteReferenceItem)
+
+#endif // QOPCUADELETEREFERENCEITEM_H
diff --git a/src/opcua/client/qopcuanodecreationattributes.cpp b/src/opcua/client/qopcuanodecreationattributes.cpp
new file mode 100644
index 0000000..b191611
--- /dev/null
+++ b/src/opcua/client/qopcuanodecreationattributes.cpp
@@ -0,0 +1,776 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopcuanodecreationattributes.h"
+
+#include "qopcuanodecreationattributes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpcUaNodeCreationAttributes
+ \inmodule QtOpcUa
+ \brief This class manages attribute values for node creation.
+
+ This class holds values for node attributes that are passed to the server
+ when creating a new node in the OPC UA address space.
+
+ The following node attributes are supported by the different node classes:
+
+ \table
+ \header
+ \li Attribute
+ \li Object
+ \li Variable
+ \li Method
+ \li ObjectType
+ \li VariableType
+ \li ReferenceType
+ \li DataType
+ \li View
+ \row
+ \li AccessLevel
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li ArrayDimensions
+ \li
+ \li X
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \row
+ \li ContainsNoLoops
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li X
+ \row
+ \li DataType
+ \li
+ \li X
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \row
+ \li Description
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \row
+ \li DisplayName
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \row
+ \li EventNotifier
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li Executable
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li Historizing
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li InverseName
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \row
+ \li IsAbstract
+ \li
+ \li
+ \li
+ \li X
+ \li X
+ \li X
+ \li X
+ \li
+ \row
+ \li MinimumSamplingInterval
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li Symmetric
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \row
+ \li UserAccessLevel
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li UserExecutable
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \li
+ \li
+ \row
+ \li UserWriteMask
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \row
+ \li Value
+ \li
+ \li X
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \row
+ \li ValueRank
+ \li
+ \li X
+ \li
+ \li
+ \li X
+ \li
+ \li
+ \li
+ \row
+ \li WriteMask
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \li X
+ \endtable
+
+ \sa QOpcUaClient::addNode()
+*/
+
+QOpcUaNodeCreationAttributes::QOpcUaNodeCreationAttributes()
+ : data(new QOpcUaNodeCreationAttributesPrivate())
+{}
+
+/*!
+ Constructs a node creation attributes object with the values of \a other.
+*/
+QOpcUaNodeCreationAttributes::QOpcUaNodeCreationAttributes(const QOpcUaNodeCreationAttributes &other)
+ : data(other.data)
+{}
+
+/*!
+ Assigns the value of \a rhs to this node creation attributes object.
+*/
+QOpcUaNodeCreationAttributes &QOpcUaNodeCreationAttributes::operator=(const QOpcUaNodeCreationAttributes &rhs)
+{
+ if (this != &rhs)
+ data = rhs.data;
+ return *this;
+}
+
+QOpcUaNodeCreationAttributes::~QOpcUaNodeCreationAttributes()
+{}
+
+/*!
+ Returns the bitmask containing information about set attributes.
+ For a mapping of bit positions to attributes, see OPC-UA part 4, table 145.
+*/
+quint32 QOpcUaNodeCreationAttributes::mask() const
+{
+ return data->mask;
+}
+
+/*!
+ Returns the value for the AccessLevel attribute.
+*/
+QOpcUa::AccessLevel QOpcUaNodeCreationAttributes::accessLevel() const
+{
+ return data->accessLevel;
+}
+
+/*!
+ Sets the value for the AccessLevel attribute to \a accessLevel.
+*/
+void QOpcUaNodeCreationAttributes::setAccessLevel(QOpcUa::AccessLevel accessLevel)
+{
+ data->accessLevel = accessLevel;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::AccessLevel);
+}
+
+/*!
+ Returns \c true if a value for the AccessLevel attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasAccessLevel() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::AccessLevel);
+}
+
+/*!
+ Returns the value for the ArrayDimensions attribute.
+*/
+QVector<quint32> QOpcUaNodeCreationAttributes::arrayDimensions() const
+{
+ return data->arrayDimensions;
+}
+
+/*!
+ Sets the value for the ArrayDimensions attribute to \a arrayDimensions.
+*/
+void QOpcUaNodeCreationAttributes::setArrayDimensions(const QVector<quint32> &arrayDimensions)
+{
+ data->arrayDimensions = arrayDimensions;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ArrayDimensions);
+}
+
+/*!
+ Returns \c true if a value for the ArrayDimensions attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasArrayDimensions() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ArrayDimensions);
+}
+
+/*!
+ Returns the value for the ContainsNoLoops attribute.
+*/
+bool QOpcUaNodeCreationAttributes::containsNoLoops() const
+{
+ return data->containsNoLoops;
+}
+
+/*!
+ Sets the value for the ContainsNoLoops attribute to \a containsNoLoops.
+*/
+void QOpcUaNodeCreationAttributes::setContainsNoLoops(bool containsNoLoops)
+{
+ data->containsNoLoops = containsNoLoops;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ContainsNoLoops);
+}
+
+/*!
+ Returns \c true if a value for the ContainsNoLoops attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasContainsNoLoops() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ContainsNoLoops);
+}
+
+/*!
+ Returns the value for the DataType attribute.
+*/
+QString QOpcUaNodeCreationAttributes::dataTypeId() const
+{
+ return data->dataTypeId;
+}
+
+/*!
+ Sets the value for the DataType attribute to \a dataTypeId.
+*/
+void QOpcUaNodeCreationAttributes::setDataTypeId(const QString &dataTypeId)
+{
+ data->dataTypeId = dataTypeId;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::DataType);
+}
+
+/*!
+ Returns \c true if a value for the DataType attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasDataTypeId() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::DataType);
+}
+
+/*!
+ Returns the value for the Description attribute.
+*/
+QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::description() const
+{
+ return data->description;
+}
+
+/*!
+ Sets the value for the Description attribute to \a description.
+*/
+void QOpcUaNodeCreationAttributes::setDescription(const QOpcUa::QLocalizedText &description)
+{
+ data->description = description;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Description);
+}
+
+/*!
+ Returns \c true if a value for the Description attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasDescription() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Description);
+}
+
+/*!
+ Returns the value for the DisplayName attribute.
+*/
+QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::displayName() const
+{
+ return data->displayName;
+}
+
+/*!
+ Sets the value for the DisplayName attribute to \a displayName.
+*/
+void QOpcUaNodeCreationAttributes::setDisplayName(const QOpcUa::QLocalizedText &displayName)
+{
+ data->displayName = displayName;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::DisplayName);
+}
+
+/*!
+ Returns \c true if a value for the DisplayName attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasDisplayName() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::DisplayName);
+}
+
+/*!
+ Returns the value for the EventNotifier attribute.
+*/
+QOpcUa::EventNotifier QOpcUaNodeCreationAttributes::eventNotifier() const
+{
+ return data->eventNotifier;
+}
+
+/*!
+ Sets the value for the EventNotifier attribute to \a eventNotifier.
+*/
+void QOpcUaNodeCreationAttributes::setEventNotifier(QOpcUa::EventNotifier eventNotifier)
+{
+ data->eventNotifier = eventNotifier;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::EventNotifier);
+}
+
+/*!
+ Returns \c true if a value for the EventNotifier attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasEventNotifier() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::EventNotifier);
+}
+
+/*!
+ Returns the value for the Executable attribute.
+*/
+bool QOpcUaNodeCreationAttributes::executable() const
+{
+ return data->executable;
+}
+
+/*!
+ Sets the value for the Executable attribute to \a executable.
+*/
+void QOpcUaNodeCreationAttributes::setExecutable(bool executable)
+{
+ data->executable = executable;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Executable);
+}
+
+/*!
+ Returns \c true if a value for the Executable attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasExecutable() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Executable);
+}
+
+/*!
+ Returns the value for the Historizing attribute.
+*/
+bool QOpcUaNodeCreationAttributes::historizing() const
+{
+ return data->historizing;
+}
+
+/*!
+ Sets the value for the Historizing attribute to \a historizing.
+*/
+void QOpcUaNodeCreationAttributes::setHistorizing(bool historizing)
+{
+ data->historizing = historizing;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Historizing);
+}
+
+/*!
+ Returns \c true if a value for the Historizing attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasHistorizing() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Historizing);
+}
+
+/*!
+ Returns the value for the InverseName attribute.
+*/
+QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::inverseName() const
+{
+ return data->inverseName;
+}
+
+/*!
+ Sets the value for the InverseName attribute to \a inverseName.
+*/
+void QOpcUaNodeCreationAttributes::setInverseName(const QOpcUa::QLocalizedText &inverseName)
+{
+ data->inverseName = inverseName;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::InverseName);
+}
+
+/*!
+ Returns \c true if a value for the InverseName attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasInverseName() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::InverseName);
+}
+
+/*!
+ Returns the value for the IsAbstract attribute.
+*/
+bool QOpcUaNodeCreationAttributes::isAbstract() const
+{
+ return data->isAbstract;
+}
+
+/*!
+ Sets the value for the IsAbstract attribute to \a isAbstract.
+*/
+void QOpcUaNodeCreationAttributes::setIsAbstract(bool isAbstract)
+{
+ data->isAbstract = isAbstract;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::IsAbstract);
+}
+
+/*!
+ Returns \c true if a value for the IsAbstract attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasIsAbstract() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::IsAbstract);
+}
+
+/*!
+ Returns the value for the MinimumSamplingInterval attribute.
+*/
+double QOpcUaNodeCreationAttributes::minimumSamplingInterval() const
+{
+ return data->minimumSamplingInterval;
+}
+
+/*!
+ Sets the value for the MinimumSamplingInterval attribute to \a minimumSamplingInterval.
+*/
+void QOpcUaNodeCreationAttributes::setMinimumSamplingInterval(double minimumSamplingInterval)
+{
+ data->minimumSamplingInterval = minimumSamplingInterval;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::MinimumSamplingInterval);
+}
+
+/*!
+ Returns \c true if a value for the MinimumSamplingInterval attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasMinimumSamplingInterval() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::MinimumSamplingInterval);
+}
+
+/*!
+ Returns the value for the Symmetric attribute.
+*/
+bool QOpcUaNodeCreationAttributes::symmetric() const
+{
+ return data->symmetric;
+}
+
+/*!
+ Sets the value for the Symmetric attribute to \a symmetric.
+*/
+void QOpcUaNodeCreationAttributes::setSymmetric(bool symmetric)
+{
+ data->symmetric = symmetric;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Symmetric);
+}
+
+/*!
+ Returns \c true if a value for the Symmetric attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasSymmetric() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Symmetric);
+}
+
+/*!
+ Returns the value for the UserAccessLevel attribute.
+*/
+QOpcUa::AccessLevel QOpcUaNodeCreationAttributes::userAccessLevel() const
+{
+ return data->userAccessLevel;
+}
+
+/*!
+ Sets the value for the UserAccessLevel attribute to \a userAccessLevel.
+*/
+void QOpcUaNodeCreationAttributes::setUserAccessLevel(QOpcUa::AccessLevel userAccessLevel)
+{
+ data->userAccessLevel = userAccessLevel;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserAccessLevel);
+}
+
+/*!
+ Returns \c true if a value for the UserAccessLevel attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasUserAccessLevel() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserAccessLevel);
+}
+
+/*!
+ Returns the value for the UserExecutable attribute.
+*/
+bool QOpcUaNodeCreationAttributes::userExecutable() const
+{
+ return data->userExecutable;
+}
+
+/*!
+ Sets the value for the UserExecutable attribute to \a userExecutable.
+*/
+void QOpcUaNodeCreationAttributes::setUserExecutable(bool userExecutable)
+{
+ data->userExecutable = userExecutable;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserExecutable);
+}
+
+/*!
+ Returns \c true if a value for the UserExecutable attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasUserExecutable() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserExecutable);
+}
+
+/*!
+ Returns the value for the UserWriteMask attribute.
+*/
+QOpcUa::WriteMask QOpcUaNodeCreationAttributes::userWriteMask() const
+{
+ return data->userWriteMask;
+}
+
+/*!
+ Sets the value for the UserWriteMask attribute to \a userWriteMask.
+*/
+void QOpcUaNodeCreationAttributes::setUserWriteMask(QOpcUa::WriteMask userWriteMask)
+{
+ data->userWriteMask = userWriteMask;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserWriteMask);
+}
+
+/*!
+ Returns \c true if a value for the UserWriteMask attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasUserWriteMask() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserWriteMask);
+}
+
+/*!
+ Returns the value for the ValueRank attribute.
+*/
+qint32 QOpcUaNodeCreationAttributes::valueRank() const
+{
+ return data->valueRank;
+}
+
+/*!
+ Sets the value for the ValueRank attribute to \a valueRank.
+*/
+void QOpcUaNodeCreationAttributes::setValueRank(qint32 valueRank)
+{
+ data->valueRank = valueRank;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ValueRank);
+}
+
+/*!
+ Returns \c true if a value for the ValueRank attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasValueRank() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ValueRank);
+}
+
+/*!
+ Returns the value for the WriteMask attribute.
+*/
+QOpcUa::WriteMask QOpcUaNodeCreationAttributes::writeMask() const
+{
+ return data->writeMask;
+}
+
+/*!
+ Sets the value for the WriteMask attribute to \a writeMask.
+*/
+void QOpcUaNodeCreationAttributes::setWriteMask(QOpcUa::WriteMask writeMask)
+{
+ data->writeMask = writeMask;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::WriteMask);
+}
+
+/*!
+ Returns \c true if a value for the WriteMask attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasWriteMask() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::WriteMask);
+}
+
+/*!
+ Returns the value for the Value attribute.
+*/
+QVariant QOpcUaNodeCreationAttributes::value() const
+{
+ return data->value;
+}
+
+/*!
+ Sets the value for the Value attribute to \a value of type \a type.
+*/
+void QOpcUaNodeCreationAttributes::setValue(const QVariant &value, QOpcUa::Types type)
+{
+ data->value = value;
+ data->valueType = type;
+ data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Value);
+}
+
+/*!
+ Returns \c true if a value for the Value attribute is set.
+*/
+bool QOpcUaNodeCreationAttributes::hasValue() const
+{
+ return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Value);
+}
+
+/*!
+ Returns the type of the value attribute.
+*/
+QOpcUa::Types QOpcUaNodeCreationAttributes::valueType() const
+{
+ return data->valueType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opcua/client/qopcuanodecreationattributes.h b/src/opcua/client/qopcuanodecreationattributes.h
new file mode 100644
index 0000000..ad775ce
--- /dev/null
+++ b/src/opcua/client/qopcuanodecreationattributes.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPCUANODECREATIONATTRIBUTES_H
+#define QOPCUANODECREATIONATTRIBUTES_H
+
+#include <QtOpcUa/qopcuatype.h>
+
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaNodeCreationAttributesPrivate;
+
+class Q_OPCUA_EXPORT QOpcUaNodeCreationAttributes
+{
+public:
+ QOpcUaNodeCreationAttributes();
+ QOpcUaNodeCreationAttributes(const QOpcUaNodeCreationAttributes &other);
+ QOpcUaNodeCreationAttributes &operator=(const QOpcUaNodeCreationAttributes &rhs);
+
+ ~QOpcUaNodeCreationAttributes();
+
+ // A bitmask containing all set values, see OPC-UA part 4, table 145
+ quint32 mask() const;
+
+ QOpcUa::AccessLevel accessLevel() const;
+ void setAccessLevel(QOpcUa::AccessLevel accessLevel);
+ bool hasAccessLevel() const;
+
+ QVector<quint32> arrayDimensions() const;
+ void setArrayDimensions(const QVector<quint32> &arrayDimensions);
+ bool hasArrayDimensions() const;
+
+ bool containsNoLoops() const;
+ void setContainsNoLoops(bool containsNoLoops);
+ bool hasContainsNoLoops() const;
+
+ QString dataTypeId() const;
+ void setDataTypeId(const QString &dataTypeId);
+ bool hasDataTypeId() const;
+
+ QOpcUa::QLocalizedText description() const;
+ void setDescription(const QOpcUa::QLocalizedText &description);
+ bool hasDescription() const;
+
+ QOpcUa::QLocalizedText displayName() const;
+ void setDisplayName(const QOpcUa::QLocalizedText &displayName);
+ bool hasDisplayName() const;
+
+ QOpcUa::EventNotifier eventNotifier() const;
+ void setEventNotifier(QOpcUa::EventNotifier eventNotifier);
+ bool hasEventNotifier() const;
+
+ bool executable() const;
+ void setExecutable(bool executable);
+ bool hasExecutable() const;
+
+ bool historizing() const;
+ void setHistorizing(bool historizing);
+ bool hasHistorizing() const;
+
+ QOpcUa::QLocalizedText inverseName() const;
+ void setInverseName(const QOpcUa::QLocalizedText &inverseName);
+ bool hasInverseName() const;
+
+ bool isAbstract() const;
+ void setIsAbstract(bool isAbstract);
+ bool hasIsAbstract() const;
+
+ double minimumSamplingInterval() const;
+ void setMinimumSamplingInterval(double minimumSamplingInterval);
+ bool hasMinimumSamplingInterval() const;
+
+ bool symmetric() const;
+ void setSymmetric(bool symmetric);
+ bool hasSymmetric() const;
+
+ QOpcUa::AccessLevel userAccessLevel() const;
+ void setUserAccessLevel(QOpcUa::AccessLevel userAccessLevel);
+ bool hasUserAccessLevel() const;
+
+ bool userExecutable() const;
+ void setUserExecutable(bool userExecutable);
+ bool hasUserExecutable() const;
+
+ QOpcUa::WriteMask userWriteMask() const;
+ void setUserWriteMask(QOpcUa::WriteMask userWriteMask);
+ bool hasUserWriteMask() const;
+
+ qint32 valueRank() const;
+ void setValueRank(qint32 valueRank);
+ bool hasValueRank() const;
+
+ QOpcUa::WriteMask writeMask() const;
+ void setWriteMask(QOpcUa::WriteMask writeMask);
+ bool hasWriteMask() const;
+
+ QVariant value() const;
+ void setValue(const QVariant &value, QOpcUa::Types type = QOpcUa::Types::Undefined);
+ bool hasValue() const;
+
+ QOpcUa::Types valueType() const;
+
+private:
+ QSharedDataPointer<QOpcUaNodeCreationAttributesPrivate> data;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QOpcUaNodeCreationAttributes)
+
+#endif // QOPCUANODECREATIONATTRIBUTES_H
diff --git a/src/opcua/client/qopcuanodecreationattributes_p.h b/src/opcua/client/qopcuanodecreationattributes_p.h
new file mode 100644
index 0000000..c33d3cf
--- /dev/null
+++ b/src/opcua/client/qopcuanodecreationattributes_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPCUANODECREATIONATTRIBUTES_P_H
+#define QOPCUANODECREATIONATTRIBUTES_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qopcuatype.h"
+
+#include <QSharedData>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaNodeCreationAttributesPrivate : public QSharedData
+{
+public:
+ QOpcUaNodeCreationAttributesPrivate()
+ : mask(0)
+ {}
+
+ // Bit positions from OPC-UA part 4, table 145
+ enum class BitMask : quint32 {
+ AccessLevel = 0,
+ ArrayDimensions = 1,
+ ContainsNoLoops = 3,
+ DataType = 4,
+ Description = 5,
+ DisplayName = 6,
+ EventNotifier = 7,
+ Executable = 8,
+ Historizing = 9,
+ InverseName = 10,
+ IsAbstract = 11,
+ MinimumSamplingInterval = 12,
+ Symmetric = 15,
+ UserAccessLevel = 16,
+ UserExecutable = 17,
+ UserWriteMask = 18,
+ ValueRank = 19,
+ WriteMask = 20,
+ Value = 21
+ };
+
+ void setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask attribute)
+ {
+ const quint32 position = static_cast<quint32>(attribute);
+ mask |= (1 << position);
+ }
+
+ bool attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask attribute) const
+ {
+ const quint32 position = static_cast<quint32>(attribute);
+ return mask & (1 << position);
+ }
+
+ quint32 mask {0};
+ QOpcUa::AccessLevel accessLevel {QOpcUa::AccessLevelBit::None};
+ QVector<quint32> arrayDimensions;
+ bool containsNoLoops {false};
+ QString dataTypeId;
+ QOpcUa::QLocalizedText description;
+ QOpcUa::QLocalizedText displayName;
+ QOpcUa::EventNotifier eventNotifier {QOpcUa::EventNotifierBit::None};
+ bool executable {false};
+ bool historizing {false};
+ QOpcUa::QLocalizedText inverseName;
+ bool isAbstract {false};
+ double minimumSamplingInterval {0};
+ bool symmetric {false};
+ QOpcUa::AccessLevel userAccessLevel {QOpcUa::AccessLevelBit::None};
+ bool userExecutable {false};
+ QOpcUa::WriteMask userWriteMask {QOpcUa::WriteMaskBit::None};
+ qint32 valueRank {0};
+ QOpcUa::WriteMask writeMask {QOpcUa::WriteMaskBit::None};
+ QVariant value;
+ QOpcUa::Types valueType {QOpcUa::Types::Undefined};
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPCUANODECREATIONATTRIBUTES_P_H
diff --git a/src/opcua/client/qopcuatype.cpp b/src/opcua/client/qopcuatype.cpp
index 96bd943..6e462df 100644
--- a/src/opcua/client/qopcuatype.cpp
+++ b/src/opcua/client/qopcuatype.cpp
@@ -137,6 +137,65 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QOpcUa::WriteMaskBit
+
+ This enum contains all possible bits for the WriteMask and UserWriteMask node attributes
+ defined in OPC-UA part 3, Tabe 3.
+
+ \value None No attribute is writable.
+ \value AccessLevel The AccessLevel attribute is writable.
+ \value ArrayDimensions The ArrayDimensions attribute is writable.
+ \value BrowseName The BrowseName attribute is writable.
+ \value ContainsNoLoops The ContainsNoLoops attribute is writable.
+ \value DataType The DataType attribute is writable.
+ \value Description The Description attribute is writable.
+ \value DisplayName The DisplayName attribute is writable.
+ \value EventNotifier The EventNotifier attribute is writable.
+ \value Executable The Executable attribute is writable.
+ \value Historizing The Historizing attribute is writable.
+ \value InverseName The InverseName attribute is writable.
+ \value IsAbstract The IsAbstract attribute is writable.
+ \value MinimumSamplingInterval The MinimumSamplingInterval attribute is writable.
+ \value NodeClass The NodeClass attribute is writable.
+ \value NodeId The NodeId attribute is writable.
+ \value Symmetric The Symmetric attribute is writable.
+ \value UserAccessLevel The UserAccessLevel attribute is writable.
+ \value UserExecutable The UserExecutable attribute is writable.
+ \value UserWriteMask The UserWriteMask attribute is writable.
+ \value ValueRank The ValueRank attribute is writable.
+ \value WriteMask The WriteMask attribute is writable.
+ \value ValueForVariableType The Value attribute of a variable type is writable.
+*/
+
+/*!
+ \enum QOpcUa::AccessLevelBit
+
+ This enum contains all possible bits for the AccessLevel and UserAccessLevel node attributes
+ defined in OPC-UA part 3, Table 8.
+
+ \value None No read access to the Value attribute is permitted.
+ \value CurrentRead The current value can be read.
+ \value CurrentWrite The current value can be written.
+ \value HistoryRead The history of the value is readable.
+ \value HistoryWrite The history of the value is writable.
+ \value SemanticChange The property variable generates SemanticChangeEvents.
+ \value StatusWrite The status code of the value is writable.
+ \value TimestampWrite The SourceTimestamp is writable.
+*/
+
+/*!
+ \enum QOpcUa::EventNotifierBit
+
+ This enum contains all possible bits for the EventNotifier node attribute
+ defined in OPC-UA part 3, Table 6.
+
+ \value None The node can't be used to interact with events.
+ \value SubscribeToEvents A client can subscribe to events.
+ \value HistoryRead A client can read the event history.
+ \value HistoryWrite A client can write the event history.
+*/
+
+/*!
\fn inline uint QOpcUa::qHash(const QOpcUa::NodeAttribute& attr)
Returns a \l QHash key for \a attr.
diff --git a/src/opcua/client/qopcuatype.h b/src/opcua/client/qopcuatype.h
index bee0954..5390af5 100644
--- a/src/opcua/client/qopcuatype.h
+++ b/src/opcua/client/qopcuatype.h
@@ -98,6 +98,59 @@ enum class NodeAttribute {
Q_ENUM_NS(NodeAttribute)
Q_DECLARE_FLAGS(NodeAttributes, NodeAttribute)
+// Defined in OPC-UA part 3, Table 8.
+enum class WriteMaskBit : quint32 {
+ None = 0,
+ AccessLevel = (1 << 0),
+ ArrayDimensions = (1 << 1),
+ BrowseName = (1 << 2),
+ ContainsNoLoops = (1 << 3),
+ DataType = (1 << 4),
+ Description = (1 << 5),
+ DisplayName = (1 << 6),
+ EventNotifier = (1 << 7),
+ Executable = (1 << 8),
+ Historizing = (1 << 9),
+ InverseName = (1 << 10),
+ IsAbstract = (1 << 11),
+ MinimumSamplingInterval = (1 << 12),
+ NodeClass = (1 << 13),
+ NodeId = (1 << 14),
+ Symmetric = (1 << 15),
+ UserAccessLevel = (1 << 16),
+ UserExecutable = (1 << 17),
+ UserWriteMask = (1 << 18),
+ ValueRank = (1 << 19),
+ WriteMask = (1 << 20),
+ ValueForVariableType = (1 << 21),
+};
+Q_ENUM_NS(WriteMaskBit)
+Q_DECLARE_FLAGS(WriteMask, WriteMaskBit)
+
+// Defined in OPC-UA part 3, Table 8.
+enum class AccessLevelBit : quint8 {
+ None = 0,
+ CurrentRead = (1 << 0),
+ CurrentWrite = (1 << 1),
+ HistoryRead = (1 << 2),
+ HistoryWrite = (1 << 3),
+ SemanticChange = (1 << 4),
+ StatusWrite = (1 << 5),
+ TimestampWrite = (1 << 6),
+};
+Q_ENUM_NS(AccessLevelBit)
+Q_DECLARE_FLAGS(AccessLevel, AccessLevelBit)
+
+// Defined in OPC-UA part 3, Table 6.
+enum class EventNotifierBit : quint8 {
+ None = 0,
+ SubscribeToEvents = (1 << 0),
+ HistoryRead = (1 << 2),
+ HistoryWrite = (1 << 3)
+};
+Q_ENUM_NS(EventNotifierBit)
+Q_DECLARE_FLAGS(EventNotifier, EventNotifierBit)
+
inline uint qHash(const QOpcUa::NodeAttribute& attr)
{
return ::qHash(static_cast<uint>(attr));
@@ -1139,6 +1192,9 @@ Q_DECLARE_TYPEINFO(QOpcUa::ErrorCategory, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QOpcUa::NodeClass, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QOpcUa::NodeAttribute, Q_PRIMITIVE_TYPE);
Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::NodeAttributes)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::WriteMask)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::AccessLevel)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::EventNotifier)
Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::NodeClasses)
Q_DECLARE_TYPEINFO(QOpcUa::ReferenceTypeId, Q_PRIMITIVE_TYPE);
@@ -1153,6 +1209,12 @@ Q_DECLARE_METATYPE(QOpcUa::ErrorCategory)
Q_DECLARE_METATYPE(QOpcUa::NodeClass)
Q_DECLARE_METATYPE(QOpcUa::NodeAttribute)
Q_DECLARE_METATYPE(QOpcUa::NodeAttributes)
+Q_DECLARE_METATYPE(QOpcUa::WriteMaskBit)
+Q_DECLARE_METATYPE(QOpcUa::WriteMask)
+Q_DECLARE_METATYPE(QOpcUa::AccessLevelBit)
+Q_DECLARE_METATYPE(QOpcUa::AccessLevel)
+Q_DECLARE_METATYPE(QOpcUa::EventNotifierBit)
+Q_DECLARE_METATYPE(QOpcUa::EventNotifier)
Q_DECLARE_METATYPE(QOpcUa::ReferenceTypeId)
Q_DECLARE_METATYPE(QOpcUa::NodeClasses)
Q_DECLARE_METATYPE(QOpcUa::QRange)
diff --git a/src/opcua/core/qopcuaprovider.cpp b/src/opcua/core/qopcuaprovider.cpp
index 9f3c795..6e4df1a 100644
--- a/src/opcua/core/qopcuaprovider.cpp
+++ b/src/opcua/core/qopcuaprovider.cpp
@@ -165,6 +165,10 @@ QOpcUaProvider::QOpcUaProvider(QObject *parent)
qRegisterMetaType<QOpcUaWriteResult>();
qRegisterMetaType<QVector<QOpcUaWriteItem>>();
qRegisterMetaType<QVector<QOpcUaWriteResult>>();
+ qRegisterMetaType<QOpcUaNodeCreationAttributes>();
+ qRegisterMetaType<QOpcUaAddNodeItem>();
+ qRegisterMetaType<QOpcUaAddReferenceItem>();
+ qRegisterMetaType<QOpcUaDeleteReferenceItem>();
}
QOpcUaProvider::~QOpcUaProvider()
diff --git a/src/opcua/doc/src/qtopcua.qdoc b/src/opcua/doc/src/qtopcua.qdoc
index d0263fc..2801420 100644
--- a/src/opcua/doc/src/qtopcua.qdoc
+++ b/src/opcua/doc/src/qtopcua.qdoc
@@ -174,6 +174,9 @@
\li FindServers
\li X
\li
+ \li NodeManagement
+ \li X
+ \li
\endtable
\section1 Data types
diff --git a/src/plugins/opcua/open62541/qopen62541backend.cpp b/src/plugins/opcua/open62541/qopen62541backend.cpp
index 5e6a1ef..44a675e 100644
--- a/src/plugins/opcua/open62541/qopen62541backend.cpp
+++ b/src/plugins/opcua/open62541/qopen62541backend.cpp
@@ -558,6 +558,126 @@ void Open62541AsyncBackend::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWr
}
}
+void Open62541AsyncBackend::addNode(const QOpcUaAddNodeItem &nodeToAdd)
+{
+ UA_AddNodesRequest req;
+ UA_AddNodesRequest_init(&req);
+ UaDeleter<UA_AddNodesRequest> requestDeleter(&req, UA_AddNodesRequest_deleteMembers);
+ req.nodesToAddSize = 1;
+ req.nodesToAdd = UA_AddNodesItem_new();
+ UA_AddNodesItem_init(req.nodesToAdd);
+
+ QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>(
+ nodeToAdd.parentNodeId(), &req.nodesToAdd->parentNodeId);
+
+ req.nodesToAdd->referenceTypeId = Open62541Utils::nodeIdFromQString(nodeToAdd.referenceTypeId());
+
+ QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>(
+ nodeToAdd.requestedNewNodeId(), &req.nodesToAdd->requestedNewNodeId);
+
+ QOpen62541ValueConverter::scalarFromQt<UA_QualifiedName, QOpcUa::QQualifiedName>(
+ nodeToAdd.browseName(), &req.nodesToAdd->browseName);
+
+ req.nodesToAdd->nodeClass = static_cast<UA_NodeClass>(nodeToAdd.nodeClass());
+
+ req.nodesToAdd->nodeAttributes = assembleNodeAttributes(nodeToAdd.nodeAttributes(),
+ nodeToAdd.nodeClass());
+
+ if (!nodeToAdd.typeDefinition().nodeId().isEmpty())
+ QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>(
+ nodeToAdd.typeDefinition(), &req.nodesToAdd->typeDefinition);
+
+ UA_AddNodesResponse res = UA_Client_Service_addNodes(m_uaclient, req);
+ UaDeleter<UA_AddNodesResponse> responseDeleter(&res, UA_AddNodesResponse_deleteMembers);
+
+ QOpcUa::UaStatusCode status = QOpcUa::UaStatusCode::Good;
+ QString resultId;
+ if (res.responseHeader.serviceResult == UA_STATUSCODE_GOOD) {
+ if (res.results[0].statusCode == UA_STATUSCODE_GOOD)
+ resultId = Open62541Utils::nodeIdToQString(res.results[0].addedNodeId);
+ else {
+ status = static_cast<QOpcUa::UaStatusCode>(res.results[0].statusCode);
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add node:" << status;
+ }
+ } else {
+ status = static_cast<QOpcUa::UaStatusCode>(res.responseHeader.serviceResult);
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add node:" << status;
+ }
+
+ emit addNodeFinished(nodeToAdd.requestedNewNodeId(), resultId, status);
+}
+
+void Open62541AsyncBackend::deleteNode(const QString &nodeId, bool deleteTargetReferences)
+{
+ UA_NodeId id = Open62541Utils::nodeIdFromQString(nodeId);
+ UaDeleter<UA_NodeId> nodeIdDeleter(&id, UA_NodeId_deleteMembers);
+
+ UA_StatusCode res = UA_Client_deleteNode(m_uaclient, id, deleteTargetReferences);
+
+ QOpcUa::UaStatusCode resultStatus = static_cast<QOpcUa::UaStatusCode>(res);
+
+ if (resultStatus != QOpcUa::UaStatusCode::Good) {
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to delete node" << nodeId << "with status code" << resultStatus;
+ }
+
+ emit deleteNodeFinished(nodeId, resultStatus);
+}
+
+void Open62541AsyncBackend::addReference(const QOpcUaAddReferenceItem &referenceToAdd)
+{
+ UA_ExpandedNodeId target;
+ UA_ExpandedNodeId_init(&target);
+ UaDeleter<UA_ExpandedNodeId> nodeIdDeleter(&target, UA_ExpandedNodeId_deleteMembers);
+
+ QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>(
+ referenceToAdd.targetNodeId(), &target);
+
+ UA_String serverUri;
+ UaDeleter<UA_String> serverUriDeleter(&serverUri, UA_String_deleteMembers);
+ QOpen62541ValueConverter::scalarFromQt<UA_String, QString>(
+ referenceToAdd.targetServerUri(), &serverUri);
+
+ UA_NodeClass nodeClass = static_cast<UA_NodeClass>(referenceToAdd.targetNodeClass());
+
+ UA_StatusCode res = UA_Client_addReference(m_uaclient,
+ Open62541Utils::nodeIdFromQString(referenceToAdd.sourceNodeId()),
+ Open62541Utils::nodeIdFromQString(referenceToAdd.referenceTypeId()),
+ referenceToAdd.isForward(), serverUri, target, nodeClass);
+
+ QOpcUa::UaStatusCode statusCode = static_cast<QOpcUa::UaStatusCode>(res);
+ if (res != UA_STATUSCODE_GOOD)
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add reference from" << referenceToAdd.sourceNodeId() << "to"
+ << referenceToAdd.targetNodeId().nodeId() << ":" << statusCode;
+
+ emit addReferenceFinished(referenceToAdd.sourceNodeId(), referenceToAdd.referenceTypeId(),
+ referenceToAdd.targetNodeId(),
+ referenceToAdd.isForward(), statusCode);
+}
+
+void Open62541AsyncBackend::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete)
+{
+ UA_ExpandedNodeId target;
+ UA_ExpandedNodeId_init(&target);
+ UaDeleter<UA_ExpandedNodeId> targetDeleter(&target, UA_ExpandedNodeId_deleteMembers);
+ QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>(
+ referenceToDelete.targetNodeId(), &target);
+
+ UA_StatusCode res = UA_Client_deleteReference(m_uaclient,
+ Open62541Utils::nodeIdFromQString(referenceToDelete.sourceNodeId()),
+ Open62541Utils::nodeIdFromQString(referenceToDelete.referenceTypeId()),
+ referenceToDelete.isForward(),
+ target, referenceToDelete.deleteBidirectional());
+
+ QOpcUa::UaStatusCode statusCode = static_cast<QOpcUa::UaStatusCode>(res);
+ if (res != UA_STATUSCODE_GOOD)
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to delete reference from" << referenceToDelete.sourceNodeId() << "to"
+ << referenceToDelete.targetNodeId().nodeId() << ":" << statusCode;
+
+ emit deleteReferenceFinished(referenceToDelete.sourceNodeId(), referenceToDelete.referenceTypeId(),
+ referenceToDelete.targetNodeId(),
+ referenceToDelete.isForward(), statusCode);
+}
+
static void convertBrowseResult(UA_BrowseResult *src, quint32 referencesSize, QVector<QOpcUaReferenceDescription> &dst)
{
if (!src)
@@ -834,4 +954,161 @@ void Open62541AsyncBackend::cleanupSubscriptions()
m_minPublishingInterval = 0;
}
+UA_ExtensionObject Open62541AsyncBackend::assembleNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes,
+ QOpcUa::NodeClass nodeClass)
+{
+ UA_ExtensionObject obj;
+ UA_ExtensionObject_init(&obj);
+ obj.encoding = UA_EXTENSIONOBJECT_DECODED;
+
+ switch (nodeClass) {
+ case QOpcUa::NodeClass::Object: {
+ UA_ObjectAttributes *attr = UA_ObjectAttributes_new();
+ *attr = UA_ObjectAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES];
+
+ if (nodeAttributes.hasEventNotifier())
+ attr->eventNotifier = nodeAttributes.eventNotifier();
+ break;
+ }
+ case QOpcUa::NodeClass::Variable: {
+ UA_VariableAttributes *attr = UA_VariableAttributes_new();
+ *attr = UA_VariableAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES];
+
+ if (nodeAttributes.hasValue())
+ attr->value = QOpen62541ValueConverter::toOpen62541Variant(nodeAttributes.value(),
+ nodeAttributes.valueType());
+ if (nodeAttributes.hasDataTypeId())
+ attr->dataType = Open62541Utils::nodeIdFromQString(nodeAttributes.dataTypeId());
+ if (nodeAttributes.hasValueRank())
+ attr->valueRank = nodeAttributes.valueRank();
+ if (nodeAttributes.hasArrayDimensions())
+ attr->arrayDimensions = copyArrayDimensions(nodeAttributes.arrayDimensions(), &attr->arrayDimensionsSize);
+ if (nodeAttributes.hasAccessLevel())
+ attr->accessLevel = nodeAttributes.accessLevel();
+ if (nodeAttributes.hasUserAccessLevel())
+ attr->userAccessLevel = nodeAttributes.userAccessLevel();
+ if (nodeAttributes.hasMinimumSamplingInterval())
+ attr->minimumSamplingInterval = nodeAttributes.minimumSamplingInterval();
+ if (nodeAttributes.hasHistorizing())
+ attr->historizing = nodeAttributes.historizing();
+ break;
+ }
+ case QOpcUa::NodeClass::Method: {
+ UA_MethodAttributes *attr = UA_MethodAttributes_new();
+ *attr = UA_MethodAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_METHODATTRIBUTES];
+
+ if (nodeAttributes.hasExecutable())
+ attr->executable = nodeAttributes.executable();
+ if (nodeAttributes.hasUserExecutable())
+ attr->userExecutable = nodeAttributes.userExecutable();
+ break;
+ }
+ case QOpcUa::NodeClass::ObjectType: {
+ UA_ObjectTypeAttributes *attr = UA_ObjectTypeAttributes_new();
+ *attr = UA_ObjectTypeAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES];
+
+ if (nodeAttributes.hasIsAbstract())
+ attr->isAbstract = nodeAttributes.isAbstract();
+ break;
+ }
+ case QOpcUa::NodeClass::VariableType: {
+ UA_VariableTypeAttributes *attr = UA_VariableTypeAttributes_new();
+ *attr = UA_VariableTypeAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES];
+
+ if (nodeAttributes.hasValue())
+ attr->value = QOpen62541ValueConverter::toOpen62541Variant(nodeAttributes.value(),
+ nodeAttributes.valueType());
+ if (nodeAttributes.hasDataTypeId())
+ attr->dataType = Open62541Utils::nodeIdFromQString(nodeAttributes.dataTypeId());
+ if (nodeAttributes.hasValueRank())
+ attr->valueRank = nodeAttributes.valueRank();
+ if (nodeAttributes.hasArrayDimensions())
+ attr->arrayDimensions = copyArrayDimensions(nodeAttributes.arrayDimensions(), &attr->arrayDimensionsSize);
+ if (nodeAttributes.hasIsAbstract())
+ attr->isAbstract = nodeAttributes.isAbstract();
+ break;
+ }
+ case QOpcUa::NodeClass::ReferenceType: {
+ UA_ReferenceTypeAttributes *attr = UA_ReferenceTypeAttributes_new();
+ *attr = UA_ReferenceTypeAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES];
+
+ if (nodeAttributes.hasIsAbstract())
+ attr->isAbstract = nodeAttributes.isAbstract();
+ if (nodeAttributes.hasSymmetric())
+ attr->symmetric = nodeAttributes.symmetric();
+ if (nodeAttributes.hasInverseName())
+ QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>(
+ nodeAttributes.inverseName(), &attr->inverseName);
+ break;
+ }
+ case QOpcUa::NodeClass::DataType: {
+ UA_DataTypeAttributes *attr = UA_DataTypeAttributes_new();
+ *attr = UA_DataTypeAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES];
+
+ if (nodeAttributes.hasIsAbstract())
+ attr->isAbstract = nodeAttributes.isAbstract();
+ break;
+ }
+ case QOpcUa::NodeClass::View: {
+ UA_ViewAttributes *attr = UA_ViewAttributes_new();
+ *attr = UA_ViewAttributes_default;
+ obj.content.decoded.data = attr;
+ obj.content.decoded.type = &UA_TYPES[UA_TYPES_VIEWATTRIBUTES];
+
+ if (nodeAttributes.hasContainsNoLoops())
+ attr->containsNoLoops = nodeAttributes.containsNoLoops();
+ if (nodeAttributes.hasEventNotifier())
+ attr->eventNotifier = nodeAttributes.eventNotifier();
+ break;
+ }
+ default:
+ qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Could not convert node attributes, unknown node class";
+ UA_ExtensionObject_init(&obj);
+ return obj;
+ }
+
+ UA_ObjectAttributes *attr = reinterpret_cast<UA_ObjectAttributes *>(obj.content.decoded.data);
+ attr->specifiedAttributes = nodeAttributes.mask();
+ if (nodeAttributes.hasDisplayName())
+ QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>(
+ nodeAttributes.displayName(), &attr->displayName);
+ if (nodeAttributes.hasDescription())
+ QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>(
+ nodeAttributes.description(), &attr->description);
+ if (nodeAttributes.hasWriteMask())
+ attr->writeMask = nodeAttributes.writeMask();
+ if (nodeAttributes.hasUserWriteMask())
+ attr->userWriteMask = nodeAttributes.userWriteMask();
+
+ return obj;
+}
+
+UA_UInt32 *Open62541AsyncBackend::copyArrayDimensions(const QVector<quint32> &arrayDimensions, size_t *outputSize)
+{
+ if (outputSize)
+ *outputSize = arrayDimensions.size();
+
+ if (!outputSize)
+ return nullptr;
+
+ UA_UInt32 *data = nullptr;
+ UA_StatusCode res = UA_Array_copy(arrayDimensions.constData(), arrayDimensions.size(),
+ reinterpret_cast<void **>(&data), &UA_TYPES[UA_TYPES_UINT32]);
+ return res == UA_STATUSCODE_GOOD ? data : nullptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/opcua/open62541/qopen62541backend.h b/src/plugins/opcua/open62541/qopen62541backend.h
index 44b549f..622f91d 100644
--- a/src/plugins/opcua/open62541/qopen62541backend.h
+++ b/src/plugins/opcua/open62541/qopen62541backend.h
@@ -72,6 +72,12 @@ public Q_SLOTS:
void batchRead(const QVector<QOpcUaReadItem> &nodesToRead);
void batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite);
+ // Node management
+ void addNode(const QOpcUaAddNodeItem &nodeToAdd);
+ void deleteNode(const QString &nodeId, bool deleteTargetReferences);
+ void addReference(const QOpcUaAddReferenceItem &referenceToAdd);
+ void deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete);
+
// Subscription
QOpen62541Subscription *getSubscription(const QOpcUaMonitoringParameters &settings);
bool removeSubscription(UA_UInt32 subscriptionId);
@@ -89,6 +95,9 @@ private:
QOpen62541Subscription *getSubscriptionForItem(quint64 handle, QOpcUa::NodeAttribute attr);
QOpcUa::QApplicationDescription convertApplicationDescription(UA_ApplicationDescription &desc);
+ UA_ExtensionObject assembleNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes, QOpcUa::NodeClass nodeClass);
+ UA_UInt32 *copyArrayDimensions(const QVector<quint32> &arrayDimensions, size_t *outputSize);
+
QTimer m_subscriptionTimer;
QHash<quint32, QOpen62541Subscription *> m_subscriptions;
diff --git a/src/plugins/opcua/open62541/qopen62541client.cpp b/src/plugins/opcua/open62541/qopen62541client.cpp
index 841c841..370bcee 100644
--- a/src/plugins/opcua/open62541/qopen62541client.cpp
+++ b/src/plugins/opcua/open62541/qopen62541client.cpp
@@ -124,4 +124,29 @@ bool QOpen62541Client::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite)
Q_ARG(QVector<QOpcUaWriteItem>, nodesToWrite));
}
+bool QOpen62541Client::addNode(const QOpcUaAddNodeItem &nodeToAdd)
+{
+ return QMetaObject::invokeMethod(m_backend, "addNode", Qt::QueuedConnection,
+ Q_ARG(QOpcUaAddNodeItem, nodeToAdd));
+}
+
+bool QOpen62541Client::deleteNode(const QString &nodeId, bool deleteTargetReferences)
+{
+ return QMetaObject::invokeMethod(m_backend, "deleteNode", Qt::QueuedConnection,
+ Q_ARG(QString, nodeId),
+ Q_ARG(bool, deleteTargetReferences));
+}
+
+bool QOpen62541Client::addReference(const QOpcUaAddReferenceItem &referenceToAdd)
+{
+ return QMetaObject::invokeMethod(m_backend, "addReference", Qt::QueuedConnection,
+ Q_ARG(QOpcUaAddReferenceItem, referenceToAdd));
+}
+
+bool QOpen62541Client::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete)
+{
+ return QMetaObject::invokeMethod(m_backend, "deleteReference", Qt::QueuedConnection,
+ Q_ARG(QOpcUaDeleteReferenceItem, referenceToDelete));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/opcua/open62541/qopen62541client.h b/src/plugins/opcua/open62541/qopen62541client.h
index 84e8e1a..466b60a 100644
--- a/src/plugins/opcua/open62541/qopen62541client.h
+++ b/src/plugins/opcua/open62541/qopen62541client.h
@@ -68,6 +68,12 @@ public:
bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead) override;
bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) override;
+ bool addNode(const QOpcUaAddNodeItem &nodeToAdd) override;
+ bool deleteNode(const QString &nodeId, bool deleteTargetReferences) override;
+
+ bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) override;
+ bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) override;
+
private slots:
private:
diff --git a/src/plugins/opcua/uacpp/quacppclient.cpp b/src/plugins/opcua/uacpp/quacppclient.cpp
index 28c52c3..815f741 100644
--- a/src/plugins/opcua/uacpp/quacppclient.cpp
+++ b/src/plugins/opcua/uacpp/quacppclient.cpp
@@ -115,4 +115,37 @@ bool QUACppClient::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite)
return false;
}
+bool QUACppClient::addNode(const QOpcUaAddNodeItem &nodeToAdd)
+{
+ Q_UNUSED(nodeToAdd);
+
+ qCInfo(QT_OPCUA_PLUGINS_UACPP) << "AddNode is not yet supported by the uacpp backend";
+ return false;
+}
+
+bool QUACppClient::deleteNode(const QString &nodeId, bool deleteTargetReferences)
+{
+ Q_UNUSED(nodeId);
+ Q_UNUSED(deleteTargetReferences);
+
+ qCInfo(QT_OPCUA_PLUGINS_UACPP) << "DeleteNode is not yet supported by the uacpp backend";
+ return false;
+}
+
+bool QUACppClient::addReference(const QOpcUaAddReferenceItem &referenceToAdd)
+{
+ Q_UNUSED(referenceToAdd);
+
+ qCInfo(QT_OPCUA_PLUGINS_UACPP) << "AddReference is not yet supported by the uacpp backend";
+ return false;
+}
+
+bool QUACppClient::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete)
+{
+ Q_UNUSED(referenceToDelete);
+
+ qCDebug(QT_OPCUA_PLUGINS_UACPP) << "deleteReference is not yet supported by the uacpp backend";
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/opcua/uacpp/quacppclient.h b/src/plugins/opcua/uacpp/quacppclient.h
index 4efbadb..af16cd2 100644
--- a/src/plugins/opcua/uacpp/quacppclient.h
+++ b/src/plugins/opcua/uacpp/quacppclient.h
@@ -52,6 +52,12 @@ public:
bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead) override;
bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) override;
+ bool addNode(const QOpcUaAddNodeItem &nodeToAdd) override;
+ bool deleteNode(const QString &nodeId, bool deleteTargetReferences) override;
+
+ bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) override;
+ bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) override;
+
private:
friend class QUACppNode;
QThread *m_thread;