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
10QT_BEGIN_NAMESPACE
11
12QOpcUaClientImpl::QOpcUaClientImpl(QObject *parent)
13 : QObject(parent)
14 , m_client(nullptr)
15 , m_handleCounter(0)
16{}
17
18QOpcUaClientImpl::~QOpcUaClientImpl()
19{}
20
21bool 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
37void QOpcUaClientImpl::unregisterNode(QPointer<QOpcUaNodeImpl> obj)
38{
39 m_handles.remove(key: obj->handle());
40}
41
42void 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
67void 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
74void 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
81void 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
88void 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
95void 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
102void 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
109void 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
116void 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
124void 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
131QT_END_NAMESPACE
132

source code of qtopcua/src/opcua/client/qopcuaclientimpl.cpp