open62541pp 0.17.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
request_handling.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm> // transform
4#include <type_traits> // remove_const_t
5#include <vector>
6
7#include "open62541pp/common.hpp" // AttributeId
9#include "open62541pp/detail/string_utils.hpp" // toNativeString
10#include "open62541pp/span.hpp"
11#include "open62541pp/types.hpp"
13#include "open62541pp/wrapper.hpp" // asNative
14
15namespace opcua::services::detail {
16
17template <typename T>
18auto* getPointer(T& value) noexcept {
19 // NOLINTNEXTLINE(*-const-cast), request object won't be modified
20 return const_cast<std::remove_const_t<T>*>(&value);
21}
22
23template <typename T>
24auto* getPointer(Span<T> array) noexcept {
25 // NOLINTNEXTLINE(*-const-cast), request object won't be modified
26 return const_cast<std::remove_const_t<T>*>(array.data());
27}
28
29template <typename T>
30auto* getNativePointer(T& wrapper) noexcept {
31 return asNative(getPointer(wrapper));
32}
33
34template <typename T>
35auto* getNativePointer(Span<T> array) noexcept {
36 return asNative(getPointer(array));
37}
38
39template <typename T>
40ExtensionObject wrapNodeAttributes(const T& attributes) noexcept {
41 // NOLINTNEXTLINE(*-const-cast), won't be modified
42 return ExtensionObject(const_cast<T*>(&attributes));
43}
44
45inline UA_AddNodesItem createAddNodesItem(
46 const NodeId& parentId,
47 const NodeId& referenceType,
48 const NodeId& id,
49 std::string_view browseName,
50 NodeClass nodeClass,
51 const ExtensionObject& nodeAttributes,
52 const NodeId& typeDefinition
53) noexcept {
54 UA_AddNodesItem item{};
55 item.parentNodeId.nodeId = parentId;
56 item.referenceTypeId = referenceType;
57 item.requestedNewNodeId.nodeId = id;
58 item.browseName.namespaceIndex = id.namespaceIndex();
59 item.browseName.name = opcua::detail::toNativeString(browseName);
60 item.nodeClass = static_cast<UA_NodeClass>(nodeClass);
61 item.nodeAttributes = nodeAttributes;
62 item.typeDefinition.nodeId = typeDefinition;
63 return item;
64}
65
66inline UA_AddNodesRequest createAddNodesRequest(UA_AddNodesItem& item) noexcept {
67 UA_AddNodesRequest request{};
68 request.nodesToAddSize = 1;
69 request.nodesToAdd = &item;
70 return request;
71}
72
73inline UA_AddReferencesItem createAddReferencesItem(
74 const NodeId& sourceId, const NodeId& referenceType, bool forward, const NodeId& targetId
75) noexcept {
77 item.sourceNodeId = sourceId;
78 item.referenceTypeId = referenceType;
79 item.isForward = forward;
80 item.targetNodeId.nodeId = targetId;
81 return item;
82}
83
84inline UA_AddReferencesRequest createAddReferencesRequest(UA_AddReferencesItem& item) noexcept {
86 request.referencesToAddSize = 1;
87 request.referencesToAdd = &item;
88 return request;
89}
90
91inline UA_DeleteNodesItem createDeleteNodesItem(const NodeId& id, bool deleteReferences) noexcept {
92 UA_DeleteNodesItem item{};
93 item.nodeId = id;
94 item.deleteTargetReferences = deleteReferences;
95 return item;
96}
97
98inline UA_DeleteNodesRequest createDeleteNodesRequest(UA_DeleteNodesItem& item) noexcept {
99 UA_DeleteNodesRequest request{};
100 request.nodesToDeleteSize = 1;
101 request.nodesToDelete = &item;
102 return request;
103}
104
105inline UA_DeleteReferencesItem createDeleteReferencesItem(
106 const NodeId& sourceId,
107 const NodeId& referenceType,
108 bool isForward,
109 const NodeId& targetId,
110 bool deleteBidirectional
111) noexcept {
113 item.sourceNodeId = sourceId;
114 item.referenceTypeId = referenceType;
115 item.isForward = isForward;
116 item.targetNodeId.nodeId = targetId;
117 item.deleteBidirectional = deleteBidirectional;
118 return item;
119}
120
121inline UA_DeleteReferencesRequest createDeleteReferencesRequest(UA_DeleteReferencesItem& item
122) noexcept {
124 request.referencesToDeleteSize = 1;
125 request.referencesToDelete = &item;
126 return request;
127}
128
129inline UA_ReadValueId createReadValueId(const NodeId& id, AttributeId attributeId) noexcept {
130 UA_ReadValueId item{};
131 item.nodeId = *id.handle();
132 item.attributeId = static_cast<uint32_t>(attributeId);
133 return item;
134}
135
136inline UA_ReadRequest createReadRequest(
137 TimestampsToReturn timestamps, UA_ReadValueId& item
138) noexcept {
139 UA_ReadRequest request{};
140 request.timestampsToReturn = static_cast<UA_TimestampsToReturn>(timestamps);
141 request.nodesToReadSize = 1;
142 request.nodesToRead = &item;
143 return request;
144}
145
146inline UA_ReadRequest createReadRequest(
147 TimestampsToReturn timestamps, Span<const ReadValueId> nodesToRead
148) noexcept {
149 UA_ReadRequest request{};
150 request.timestampsToReturn = static_cast<UA_TimestampsToReturn>(timestamps);
151 request.nodesToReadSize = nodesToRead.size();
152 request.nodesToRead = getNativePointer(nodesToRead);
153 return request;
154}
155
156inline UA_WriteValue createWriteValue(
157 const NodeId& id, AttributeId attributeId, const DataValue& value
158) noexcept {
159 UA_WriteValue item{};
160 item.nodeId = *id.handle();
161 item.attributeId = static_cast<uint32_t>(attributeId);
162 item.value = *value.handle(); // shallow copy, avoid copy of value
163 item.value.hasValue = true;
164 return item;
165}
166
167inline UA_WriteRequest createWriteRequest(UA_WriteValue& item) noexcept {
168 UA_WriteRequest request{};
169 request.nodesToWriteSize = 1;
170 request.nodesToWrite = &item;
171 return request;
172}
173
174inline UA_WriteRequest createWriteRequest(Span<const WriteValue> nodesToWrite) noexcept {
175 UA_WriteRequest request{};
176 request.nodesToWriteSize = nodesToWrite.size();
177 request.nodesToWrite = getNativePointer(nodesToWrite);
178 return request;
179}
180
181#ifdef UA_ENABLE_METHODCALLS
182
183inline UA_CallMethodRequest createCallMethodRequest(
184 const NodeId& objectId, const NodeId& methodId, Span<const Variant> inputArguments
185) noexcept {
186 UA_CallMethodRequest request{};
187 request.objectId = objectId;
188 request.methodId = methodId;
189 request.inputArgumentsSize = inputArguments.size();
190 request.inputArguments = getNativePointer(inputArguments);
191 return request;
192}
193
194inline UA_CallRequest createCallRequest(UA_CallMethodRequest& item) noexcept {
195 UA_CallRequest request{};
196 request.methodsToCall = &item;
197 request.methodsToCallSize = 1;
198 return request;
199}
200
201#endif // UA_ENABLE_METHODCALLS
202
203inline UA_BrowseRequest createBrowseRequest(
204 const BrowseDescription& bd, uint32_t maxReferences
205) noexcept {
206 UA_BrowseRequest request{};
207 request.requestedMaxReferencesPerNode = maxReferences;
208 request.nodesToBrowseSize = 1;
209 request.nodesToBrowse = getNativePointer(bd);
210 return request;
211}
212
213inline UA_BrowseNextRequest createBrowseNextRequest(
214 bool releaseContinuationPoint, const ByteString& continuationPoint
215) noexcept {
216 UA_BrowseNextRequest request{};
217 request.releaseContinuationPoints = releaseContinuationPoint;
218 request.continuationPointsSize = 1;
219 request.continuationPoints = getNativePointer(continuationPoint);
220 return request;
221}
222
223inline UA_TranslateBrowsePathsToNodeIdsRequest createTranslateBrowsePathsToNodeIdsRequest(
224 const BrowsePath& browsePath
225) noexcept {
227 request.browsePathsSize = 1;
228 request.browsePaths = getNativePointer(browsePath);
229 return request;
230}
231
232inline BrowsePath createBrowsePath(const NodeId& origin, Span<const QualifiedName> browsePath) {
233 std::vector<RelativePathElement> relativePathElements(browsePath.size());
234 std::transform(
235 browsePath.begin(),
236 browsePath.end(),
237 relativePathElements.begin(),
238 [](const auto& qn) {
239 return RelativePathElement(ReferenceTypeId::HierarchicalReferences, false, true, qn);
240 }
241 );
242 return {origin, RelativePath(relativePathElements)};
243}
244
245#ifdef UA_ENABLE_SUBSCRIPTIONS
246
247template <typename SubscriptionParameters>
248UA_CreateSubscriptionRequest createCreateSubscriptionRequest(
249 const SubscriptionParameters& parameters, bool publishingEnabled
250) noexcept {
252 request.requestedPublishingInterval = parameters.publishingInterval;
253 request.requestedLifetimeCount = parameters.lifetimeCount;
254 request.requestedMaxKeepAliveCount = parameters.maxKeepAliveCount;
255 request.maxNotificationsPerPublish = parameters.maxNotificationsPerPublish;
256 request.publishingEnabled = publishingEnabled;
257 request.priority = parameters.priority;
258 return request;
259}
260
261template <typename SubscriptionParameters>
262UA_ModifySubscriptionRequest createModifySubscriptionRequest(
263 IntegerId subscriptionId, const SubscriptionParameters& parameters
264) noexcept {
266 request.subscriptionId = subscriptionId;
267 request.requestedPublishingInterval = parameters.publishingInterval;
268 request.requestedLifetimeCount = parameters.lifetimeCount;
269 request.requestedMaxKeepAliveCount = parameters.maxKeepAliveCount;
270 request.maxNotificationsPerPublish = parameters.maxNotificationsPerPublish;
271 request.priority = parameters.priority;
272 return request;
273}
274
275inline UA_SetPublishingModeRequest createSetPublishingModeRequest(
276 bool publishing, Span<const IntegerId> subscriptionIds
277) noexcept {
279 request.publishingEnabled = publishing;
280 request.subscriptionIdsSize = subscriptionIds.size();
281 request.subscriptionIds = getPointer(subscriptionIds);
282 return request;
283}
284
285inline UA_DeleteSubscriptionsRequest createDeleteSubscriptionsRequest(IntegerId& subscriptionId
286) noexcept {
288 request.subscriptionIdsSize = 1;
289 request.subscriptionIds = &subscriptionId;
290 return request;
291}
292
293template <typename MonitoringParameters>
294inline void copyMonitoringParametersToNative(
295 const MonitoringParameters& parameters, UA_MonitoringParameters& native
296) noexcept {
297 native.samplingInterval = parameters.samplingInterval;
298 native.filter = parameters.filter;
299 native.queueSize = parameters.queueSize;
300 native.discardOldest = parameters.discardOldest;
301}
302
303template <typename MonitoringParameters>
304UA_MonitoredItemCreateRequest createMonitoredItemCreateRequest(
305 const ReadValueId& itemToMonitor,
306 MonitoringMode monitoringMode,
307 MonitoringParameters& parameters
308) noexcept {
310 request.itemToMonitor = itemToMonitor;
311 request.monitoringMode = static_cast<UA_MonitoringMode>(monitoringMode);
312 copyMonitoringParametersToNative(parameters, request.requestedParameters);
313 return request;
314}
315
316inline UA_CreateMonitoredItemsRequest createCreateMonitoredItemsRequest(
317 IntegerId subscriptionId,
318 TimestampsToReturn timestampsToReturn,
320) noexcept {
322 request.subscriptionId = subscriptionId;
323 request.timestampsToReturn = static_cast<UA_TimestampsToReturn>(timestampsToReturn);
324 request.itemsToCreateSize = itemsToCreate.size();
325 request.itemsToCreate = getPointer(itemsToCreate);
326 return request;
327}
328
329template <typename MonitoringParameters>
330UA_MonitoredItemModifyRequest createMonitoredItemModifyRequest(
331 IntegerId monitoredItemId, MonitoringParameters& parameters
332) noexcept {
334 item.monitoredItemId = monitoredItemId;
335 copyMonitoringParametersToNative(parameters, item.requestedParameters);
336 return item;
337}
338
339template <typename MonitoringParameters>
340UA_ModifyMonitoredItemsRequest createModifyMonitoredItemsRequest(
341 IntegerId subscriptionId, MonitoringParameters& parameters, UA_MonitoredItemModifyRequest& item
342) noexcept {
344 request.subscriptionId = subscriptionId;
345 request.timestampsToReturn = static_cast<UA_TimestampsToReturn>(parameters.timestamps);
346 request.itemsToModifySize = 1;
347 request.itemsToModify = &item;
348 return request;
349}
350
351inline UA_SetMonitoringModeRequest createSetMonitoringModeRequest(
352 IntegerId subscriptionId, Span<const IntegerId> monitoredItemIds, MonitoringMode monitoringMode
353) noexcept {
355 request.subscriptionId = subscriptionId;
356 request.monitoringMode = static_cast<UA_MonitoringMode>(monitoringMode);
357 request.monitoredItemIdsSize = monitoredItemIds.size();
358 request.monitoredItemIds = getPointer(monitoredItemIds);
359 return request;
360}
361
362inline UA_SetTriggeringRequest createSetTriggeringRequest(
363 IntegerId subscriptionId,
364 IntegerId triggeringItemId,
365 Span<const IntegerId> linksToAdd,
366 Span<const IntegerId> linksToRemove
367) noexcept {
368 UA_SetTriggeringRequest request{};
369 request.subscriptionId = subscriptionId;
370 request.triggeringItemId = triggeringItemId;
371 request.linksToAddSize = linksToAdd.size();
372 request.linksToAdd = getPointer(linksToAdd);
373 request.linksToRemoveSize = linksToRemove.size();
374 request.linksToRemove = getPointer(linksToRemove);
375 return request;
376}
377
378inline UA_DeleteMonitoredItemsRequest createDeleteMonitoredItemsRequest(
379 IntegerId subscriptionId, Span<const IntegerId> monitoredItemIds
380) noexcept {
382 request.subscriptionId = subscriptionId;
383 request.monitoredItemIdsSize = monitoredItemIds.size();
384 request.monitoredItemIds = getPointer(monitoredItemIds);
385 return request;
386}
387
388#endif // UA_ENABLE_SUBSCRIPTIONS
389
390} // namespace opcua::services::detail
Span(Container &) -> Span< typename Container::value_type >
DeleteReferencesResponse deleteReferences(Client &connection, const DeleteReferencesRequest &request) noexcept
Delete one or more references (client only).
constexpr NativeType * asNative(WrapperType *wrapper) noexcept
Cast Wrapper object pointers to native object pointers.
Definition wrapper.hpp:223
MonitoringMode
Monitoring mode.
Definition types.hpp:1664
TimestampsToReturn
Timestamps to return.
Definition types.hpp:1379
uint32_t IntegerId
IntegerId.
Definition types.hpp:123
NodeClass
Node class.
Definition common.hpp:111
services::SubscriptionParameters SubscriptionParameters
AttributeId
Attribute identifiers.
Definition common.hpp:28
@ NodeId
Unambiguous identifier of a node.
UA_ExpandedNodeId parentNodeId
UA_Boolean releaseContinuationPoints
UA_UInt32 requestedMaxReferencesPerNode
UA_CallMethodRequest * methodsToCall
UA_UInt16 namespaceIndex
UA_TimestampsToReturn timestampsToReturn
UA_NodeId nodeId
size_t nodesToWriteSize
UA_NodeId nodeId
UA_TimestampsToReturn
UA_MonitoringMode
UA_NodeClass