1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QOPEN62541BACKEND_H
5#define QOPEN62541BACKEND_H
6
7#include "qopen62541client.h"
8#include "qopen62541subscription.h"
9#include <private/qopcuabackend_p.h>
10
11#include <QtCore/qset.h>
12#include <QtCore/qstring.h>
13#include <QtCore/qtimer.h>
14
15QT_BEGIN_NAMESPACE
16
17class Open62541AsyncBackend : public QOpcUaBackend
18{
19 Q_OBJECT
20public:
21 Open62541AsyncBackend(QOpen62541Client *parent);
22 ~Open62541AsyncBackend();
23
24public Q_SLOTS:
25 void connectToEndpoint(const QOpcUaEndpointDescription &endpoint);
26 void disconnectFromEndpoint();
27 void requestEndpoints(const QUrl &url);
28
29 // Node functions
30 void browse(quint64 handle, UA_NodeId id, const QOpcUaBrowseRequest &request);
31 void readAttributes(quint64 handle, UA_NodeId id, QOpcUa::NodeAttributes attr, QString indexRange);
32
33 void writeAttribute(quint64 handle, UA_NodeId id, QOpcUa::NodeAttribute attrId, QVariant value, QOpcUa::Types type, QString indexRange);
34 void writeAttributes(quint64 handle, UA_NodeId id, QOpcUaNode::AttributeMap toWrite, QOpcUa::Types valueAttributeType);
35 void enableMonitoring(quint64 handle, UA_NodeId id, QOpcUa::NodeAttributes attr, const QOpcUaMonitoringParameters &settings);
36 void disableMonitoring(quint64 handle, QOpcUa::NodeAttributes attr);
37 void modifyMonitoring(quint64 handle, QOpcUa::NodeAttribute attr, QOpcUaMonitoringParameters::Parameter item, QVariant value);
38 void callMethod(quint64 handle, UA_NodeId objectId, UA_NodeId methodId, QList<QOpcUa::TypedVariant> args);
39 void resolveBrowsePath(quint64 handle, UA_NodeId startNode, const QList<QOpcUaRelativePathElement> &path);
40 void findServers(const QUrl &url, const QStringList &localeIds, const QStringList &serverUris);
41
42 void readNodeAttributes(const QList<QOpcUaReadItem> &nodesToRead);
43 void writeNodeAttributes(const QList<QOpcUaWriteItem> &nodesToWrite);
44
45 void readHistoryRaw(QOpcUaHistoryReadRawRequest request, QList<QByteArray> continuationPoints, bool releaseContinuationPoints, quint64 handle);
46
47 // Node management
48 void addNode(const QOpcUaAddNodeItem &nodeToAdd);
49 void deleteNode(const QString &nodeId, bool deleteTargetReferences);
50 void addReference(const QOpcUaAddReferenceItem &referenceToAdd);
51 void deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete);
52
53 // Subscription
54 QOpen62541Subscription *getSubscription(const QOpcUaMonitoringParameters &settings);
55 bool removeSubscription(UA_UInt32 subscriptionId);
56 void iterateClient();
57 void handleSubscriptionTimeout(QOpen62541Subscription *sub, QList<QPair<quint64, QOpcUa::NodeAttribute>> items);
58 void cleanupSubscriptions();
59
60 // Callbacks
61 static void asyncMethodCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
62 static void asyncTranslateBrowsePathCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
63 static void asyncAddNodeCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
64 static void asyncDeleteNodeCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
65 static void asyncAddReferenceCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
66 static void asyncDeleteReferenceCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
67 static void asyncReadCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
68 static void asyncWriteAttributesCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
69 static void asyncBrowseCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
70 static void asyncBatchReadCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
71 static void asyncBatchWriteCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
72 static void asyncReadHistoryDataCallBack(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response);
73
74public:
75 UA_Client *m_uaclient;
76 QOpen62541Client *m_clientImpl;
77 bool m_useStateCallback;
78 quint32 m_clientIterateInterval;
79 quint32 m_asyncRequestTimeout;
80
81private:
82 static void clientStateCallback(UA_Client *client,
83 UA_SecureChannelState channelState,
84 UA_SessionState sessionState,
85 UA_StatusCode connectStatus);
86
87 static void inactivityCallback(UA_Client *client);
88
89 static void open62541LogHandler(void *logContext, UA_LogLevel level, UA_LogCategory category,
90 const char *msg, va_list args);
91
92 QOpen62541Subscription *getSubscriptionForItem(quint64 handle, QOpcUa::NodeAttribute attr);
93 QOpcUaApplicationDescription convertApplicationDescription(UA_ApplicationDescription &desc);
94
95 UA_ExtensionObject assembleNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes, QOpcUa::NodeClass nodeClass);
96 UA_UInt32 *copyArrayDimensions(const QList<quint32> &arrayDimensions, size_t *outputSize);
97
98 // Helper
99 bool loadFileToByteString(const QString &location, UA_ByteString *target) const;
100 bool loadAllFilesInDirectory(const QString &location, UA_ByteString **target, qsizetype *size) const;
101
102 void disconnectInternal(QOpcUaClient::ClientError error = QOpcUaClient::ClientError::NoError);
103
104 QTimer m_clientIterateTimer;
105 QTimer m_disconnectAfterStateChangeTimer;
106
107 QHash<quint32, QOpen62541Subscription *> m_subscriptions;
108
109 QHash<quint64, QHash<QOpcUa::NodeAttribute, QOpen62541Subscription *>> m_attributeMapping; // Handle -> Attribute -> Subscription
110
111 double m_minPublishingInterval;
112
113 const UA_Logger m_open62541Logger {.log: open62541LogHandler, .context: nullptr, .clear: nullptr};
114
115 // Async contexts
116
117 struct AsyncCallContext {
118 quint64 handle;
119 QString methodNodeId;
120 };
121 QMap<quint32, AsyncCallContext> m_asyncCallContext;
122
123 struct AsyncTranslateContext {
124 quint64 handle;
125 QList<QOpcUaRelativePathElement> path;
126 };
127 QMap<quint32, AsyncTranslateContext> m_asyncTranslateContext;
128
129 struct AsyncAddNodeContext {
130 QOpcUaExpandedNodeId requestedNodeId;
131 };
132 QMap<quint32, AsyncAddNodeContext> m_asyncAddNodeContext;
133
134 struct AsyncDeleteNodeContext {
135 QString nodeId;
136 };
137 QMap<quint32, AsyncDeleteNodeContext> m_asyncDeleteNodeContext;
138
139 struct AsyncAddReferenceContext {
140 QString sourceNodeId;
141 QString referenceTypeId;
142 QOpcUaExpandedNodeId targetNodeId;
143 bool isForwardReference;
144 };
145 QMap<quint32, AsyncAddReferenceContext> m_asyncAddReferenceContext;
146
147 struct AsyncDeleteReferenceContext {
148 QString sourceNodeId;
149 QString referenceTypeId;
150 QOpcUaExpandedNodeId targetNodeId;
151 bool isForwardReference;
152 };
153 QMap<quint32, AsyncDeleteReferenceContext> m_asyncDeleteReferenceContext;
154
155 struct AsyncReadContext {
156 quint64 handle;
157 QList<QOpcUaReadResult> results;
158 };
159 QMap<quint32, AsyncReadContext> m_asyncReadContext;
160
161 struct AsyncWriteAttributesContext {
162 quint64 handle;
163 QOpcUaNode::AttributeMap toWrite;
164 };
165 QMap<quint32, AsyncWriteAttributesContext> m_asyncWriteAttributesContext;
166
167 struct AsyncBrowseContext {
168 quint64 handle;
169 bool isBrowseNext;
170 QList<QOpcUaReferenceDescription> results;
171 };
172 QMap<quint32, AsyncBrowseContext> m_asyncBrowseContext;
173
174 struct AsyncBatchReadContext {
175 QList<QOpcUaReadItem> nodesToRead;
176 };
177 QMap<quint32, AsyncBatchReadContext> m_asyncBatchReadContext;
178
179 struct AsyncBatchWriteContext {
180 QList<QOpcUaWriteItem> nodesToWrite;
181 };
182 QMap<quint32, AsyncBatchWriteContext> m_asyncBatchWriteContext;
183
184 struct AsyncReadHistoryDataContext {
185 quint64 handle;
186 QOpcUaHistoryReadRawRequest historyReadRawRequest;
187 };
188 QMap<quint32, AsyncReadHistoryDataContext> m_asyncReadHistoryDataContext;
189};
190
191QT_END_NAMESPACE
192
193#endif // QOPEN62541BACKEND_H
194

source code of qtopcua/src/plugins/opcua/open62541/qopen62541backend.h