1 | // Copyright (C) 2016 basysKom GmbH, opensource@basyskom.com |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include <private/qopcuabackend_p.h> |
5 | #include <private/qopcuaclientimpl_p.h> |
6 | #include <QtOpcUa/qopcuamonitoringparameters.h> |
7 | #include "qopcuaclient_p.h" |
8 | #include "qopcuaerrorstate.h" |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | QOpcUaClientImpl::QOpcUaClientImpl(QObject *parent) |
13 | : QObject(parent) |
14 | , m_client(nullptr) |
15 | , m_handleCounter(0) |
16 | {} |
17 | |
18 | QOpcUaClientImpl::~QOpcUaClientImpl() |
19 | {} |
20 | |
21 | bool QOpcUaClientImpl::registerNode(QPointer<QOpcUaNodeImpl> obj) |
22 | { |
23 | if (m_handles.size() == (std::numeric_limits<int>::max)()) |
24 | return false; |
25 | |
26 | while (true) { |
27 | ++m_handleCounter; |
28 | |
29 | if (!m_handles.contains(key: m_handleCounter)) { |
30 | obj->setHandle(m_handleCounter); |
31 | m_handles[m_handleCounter] = obj; |
32 | return true; |
33 | } |
34 | } |
35 | } |
36 | |
37 | void QOpcUaClientImpl::unregisterNode(QPointer<QOpcUaNodeImpl> obj) |
38 | { |
39 | m_handles.remove(key: obj->handle()); |
40 | } |
41 | |
42 | void QOpcUaClientImpl::connectBackendWithClient(QOpcUaBackend *backend) |
43 | { |
44 | connect(sender: backend, signal: &QOpcUaBackend::attributesRead, context: this, slot: &QOpcUaClientImpl::handleAttributesRead); |
45 | connect(sender: backend, signal: &QOpcUaBackend::stateAndOrErrorChanged, context: this, slot: &QOpcUaClientImpl::stateAndOrErrorChanged); |
46 | connect(sender: backend, signal: &QOpcUaBackend::attributeWritten, context: this, slot: &QOpcUaClientImpl::handleAttributeWritten); |
47 | connect(sender: backend, signal: &QOpcUaBackend::dataChangeOccurred, context: this, slot: &QOpcUaClientImpl::handleDataChangeOccurred); |
48 | connect(sender: backend, signal: &QOpcUaBackend::monitoringEnableDisable, context: this, slot: &QOpcUaClientImpl::handleMonitoringEnableDisable); |
49 | connect(sender: backend, signal: &QOpcUaBackend::monitoringStatusChanged, context: this, slot: &QOpcUaClientImpl::handleMonitoringStatusChanged); |
50 | connect(sender: backend, signal: &QOpcUaBackend::methodCallFinished, context: this, slot: &QOpcUaClientImpl::handleMethodCallFinished); |
51 | connect(sender: backend, signal: &QOpcUaBackend::browseFinished, context: this, slot: &QOpcUaClientImpl::handleBrowseFinished); |
52 | connect(sender: backend, signal: &QOpcUaBackend::resolveBrowsePathFinished, context: this, slot: &QOpcUaClientImpl::handleResolveBrowsePathFinished); |
53 | connect(sender: backend, signal: &QOpcUaBackend::eventOccurred, context: this, slot: &QOpcUaClientImpl::handleNewEvent); |
54 | connect(sender: backend, signal: &QOpcUaBackend::endpointsRequestFinished, context: this, slot: &QOpcUaClientImpl::endpointsRequestFinished); |
55 | connect(sender: backend, signal: &QOpcUaBackend::findServersFinished, context: this, slot: &QOpcUaClientImpl::findServersFinished); |
56 | connect(sender: backend, signal: &QOpcUaBackend::readNodeAttributesFinished, context: this, slot: &QOpcUaClientImpl::readNodeAttributesFinished); |
57 | connect(sender: backend, signal: &QOpcUaBackend::writeNodeAttributesFinished, context: this, slot: &QOpcUaClientImpl::writeNodeAttributesFinished); |
58 | connect(sender: backend, signal: &QOpcUaBackend::addNodeFinished, context: this, slot: &QOpcUaClientImpl::addNodeFinished); |
59 | connect(sender: backend, signal: &QOpcUaBackend::deleteNodeFinished, context: this, slot: &QOpcUaClientImpl::deleteNodeFinished); |
60 | connect(sender: backend, signal: &QOpcUaBackend::addReferenceFinished, context: this, slot: &QOpcUaClientImpl::addReferenceFinished); |
61 | connect(sender: backend, signal: &QOpcUaBackend::deleteReferenceFinished, context: this, slot: &QOpcUaClientImpl::deleteReferenceFinished); |
62 | // This needs to be blocking queued because it is called from another thread, which needs to wait for a result. |
63 | connect(sender: backend, signal: &QOpcUaBackend::connectError, context: this, slot: &QOpcUaClientImpl::connectError, type: Qt::BlockingQueuedConnection); |
64 | connect(sender: backend, signal: &QOpcUaBackend::passwordForPrivateKeyRequired, context: this, slot: &QOpcUaClientImpl::passwordForPrivateKeyRequired, type: Qt::BlockingQueuedConnection); |
65 | } |
66 | |
67 | void QOpcUaClientImpl::handleAttributesRead(quint64 handle, QList<QOpcUaReadResult> attr, QOpcUa::UaStatusCode serviceResult) |
68 | { |
69 | auto it = m_handles.constFind(key: handle); |
70 | if (it != m_handles.constEnd() && !it->isNull()) |
71 | emit (*it)->attributesRead(attr, serviceResult); |
72 | } |
73 | |
74 | void QOpcUaClientImpl::handleAttributeWritten(quint64 handle, QOpcUa::NodeAttribute attr, const QVariant &value, QOpcUa::UaStatusCode statusCode) |
75 | { |
76 | auto it = m_handles.constFind(key: handle); |
77 | if (it != m_handles.constEnd() && !it->isNull()) |
78 | emit (*it)->attributeWritten(attr, value, statusCode); |
79 | } |
80 | |
81 | void QOpcUaClientImpl::handleDataChangeOccurred(quint64 handle, const QOpcUaReadResult &value) |
82 | { |
83 | auto it = m_handles.constFind(key: handle); |
84 | if (it != m_handles.constEnd() && !it->isNull()) |
85 | emit (*it)->dataChangeOccurred(attr: value.attribute(), value); |
86 | } |
87 | |
88 | void QOpcUaClientImpl::handleMonitoringEnableDisable(quint64 handle, QOpcUa::NodeAttribute attr, bool subscribe, QOpcUaMonitoringParameters status) |
89 | { |
90 | auto it = m_handles.constFind(key: handle); |
91 | if (it != m_handles.constEnd() && !it->isNull()) |
92 | emit (*it)->monitoringEnableDisable(attr, subscribe, status); |
93 | } |
94 | |
95 | void QOpcUaClientImpl::handleMonitoringStatusChanged(quint64 handle, QOpcUa::NodeAttribute attr, QOpcUaMonitoringParameters::Parameters items, QOpcUaMonitoringParameters param) |
96 | { |
97 | auto it = m_handles.constFind(key: handle); |
98 | if (it != m_handles.constEnd() && !it->isNull()) |
99 | emit (*it)->monitoringStatusChanged(attr, items, param); |
100 | } |
101 | |
102 | void QOpcUaClientImpl::handleMethodCallFinished(quint64 handle, QString methodNodeId, QVariant result, QOpcUa::UaStatusCode statusCode) |
103 | { |
104 | auto it = m_handles.constFind(key: handle); |
105 | if (it != m_handles.constEnd() && !it->isNull()) |
106 | emit (*it)->methodCallFinished(methodNodeId, result, statusCode); |
107 | } |
108 | |
109 | void QOpcUaClientImpl::handleBrowseFinished(quint64 handle, const QList<QOpcUaReferenceDescription> &children, QOpcUa::UaStatusCode statusCode) |
110 | { |
111 | auto it = m_handles.constFind(key: handle); |
112 | if (it != m_handles.constEnd() && !it->isNull()) |
113 | emit (*it)->browseFinished(children, statusCode); |
114 | } |
115 | |
116 | void QOpcUaClientImpl::handleResolveBrowsePathFinished(quint64 handle, QList<QOpcUaBrowsePathTarget> targets, |
117 | QList<QOpcUaRelativePathElement> path, QOpcUa::UaStatusCode status) |
118 | { |
119 | auto it = m_handles.constFind(key: handle); |
120 | if (it != m_handles.constEnd() && !it->isNull()) |
121 | emit (*it)->resolveBrowsePathFinished(targets, path, status); |
122 | } |
123 | |
124 | void QOpcUaClientImpl::handleNewEvent(quint64 handle, QVariantList eventFields) |
125 | { |
126 | auto it = m_handles.constFind(key: handle); |
127 | if (it != m_handles.constEnd() && !it->isNull()) |
128 | emit (*it)->eventOccurred(eventFields); |
129 | } |
130 | |
131 | QT_END_NAMESPACE |
132 | |