open62541pp 0.21.2
C++ wrapper of open62541
Loading...
Searching...
No Matches
subscription.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <functional>
5#include <memory>
6#include <utility> // forward
7
9#include "open62541pp/config.hpp"
10#include "open62541pp/detail/client_utils.hpp" // getHandle
19#include "open62541pp/ua/types.hpp" // IntegerId, StatusChangeNotification
20
21#ifdef UA_ENABLE_SUBSCRIPTIONS
22
23namespace opcua {
24class Client;
25} // namespace opcua
26
27namespace opcua::services {
28
29/**
30 * @defgroup Subscription Subscription service set
31 * Report notifications to the client.
32 *
33 * Note the difference between Subscriptions and MonitoredItems. Subscriptions are used to report
34 * back notifications. MonitoredItems are used to generate notifications. Every MonitoredItem is
35 * attached to exactly one Subscription. And a Subscription can contain many MonitoredItems.
36 *
37 * @see MonitoredItem
38 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.14
39 * @ingroup Services
40 * @{
41 */
42
43/**
44 * Subscription parameters with default values from open62541.
45 */
47 /// Cyclic interval in milliseconds that the subscription is requested to return notifications.
48 double publishingInterval = 500.0;
49 /// Delete the subscription after defined publishing cycles without sending any notifications.
50 uint32_t lifetimeCount = 10000;
51 /// Send keep-alive message after defined publishing cycles without notifications.
52 uint32_t maxKeepAliveCount = 10;
53 /// The maximum number of notifications per publish (0 if unlimited).
55 /// Relative priority of the subscription. Notifications with higher priority are sent first.
56 uint8_t priority = 0;
57};
58
59/**
60 * @defgroup CreateSubscription CreateSubscription service
61 * Create subscriptions. Subscriptions monitor a set of monitored items for notifications and return
62 * them to the client.
63 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.14.2
64 * @{
65 */
66
67/**
68 * Subscription deletion callback.
69 * @param subId Subscription identifier
70 */
71using DeleteSubscriptionCallback = std::function<void(IntegerId subId)>;
72
73/**
74 * Subscription status change notification callback.
75 * @param subId Subscription identifier
76 * @param notification Status change notification
77 */
79 std::function<void(IntegerId subId, StatusChangeNotification& notification)>;
80
81namespace detail {
82std::unique_ptr<SubscriptionContext> createSubscriptionContext(
83 Client& connection,
84 StatusChangeNotificationCallback&& statusChangeCallback,
85 DeleteSubscriptionCallback&& deleteCallback
86);
87
88void storeSubscriptionContext(
89 Client& connection, IntegerId subscriptionId, std::unique_ptr<SubscriptionContext>&& context
90);
91} // namespace detail
92
93/**
94 * Create a subscription.
95 * @param connection Instance of type Client
96 * @param request Create subscription request
97 * @param statusChangeCallback Invoked when the status of a subscription is changed
98 * @param deleteCallback Invoked when the subscription is deleted
99 */
101 Client& connection,
102 const CreateSubscriptionRequest& request,
103 StatusChangeNotificationCallback statusChangeCallback,
104 DeleteSubscriptionCallback deleteCallback
105);
106
107/// @overload
109 Client& connection,
110 const SubscriptionParameters& parameters,
111 bool publishingEnabled,
112 StatusChangeNotificationCallback statusChangeCallback,
113 DeleteSubscriptionCallback deleteCallback
114) noexcept;
115
116#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
117/**
118 * @copydoc createSubscription(Client&, const CreateSubscriptionRequest&,
119 * StatusChangeNotificationCallback, DeleteSubscriptionCallback)
120 * @param token @completiontoken{void(CreateSubscriptionResponse&)}
121 * @return @asyncresult{CreateSubscriptionResponse}
122 */
123template <typename CompletionToken>
125 Client& connection,
126 const CreateSubscriptionRequest& request,
127 StatusChangeNotificationCallback statusChangeCallback,
128 DeleteSubscriptionCallback deleteCallback,
129 CompletionToken&& token
130) {
131 auto context = detail::createSubscriptionContext(
132 connection, std::move(statusChangeCallback), std::move(deleteCallback)
133 );
134 auto* contextPtr = context.get();
135 return detail::AsyncServiceAdapter<CreateSubscriptionResponse>::initiate(
136 connection,
137 [&connection](
139 void* userdata,
140 const CreateSubscriptionRequest& innerRequest,
141 detail::SubscriptionContext* innerContextPtr
142 ) {
144 opcua::detail::getHandle(connection),
145 asNative(innerRequest),
146 innerContextPtr,
147 detail::SubscriptionContext::statusChangeCallbackNative,
148 detail::SubscriptionContext::deleteCallbackNative,
149 callback,
150 userdata,
151 nullptr
152 ));
153 },
154 detail::HookToken(
155 [&, context = std::move(context)](const CreateSubscriptionResponse& response) mutable {
156 if (detail::getServiceResult(response).isGood()) {
157 detail::storeSubscriptionContext(
158 connection, response.subscriptionId(), std::move(context)
159 );
160 }
161 },
162 std::forward<CompletionToken>(token)
163 ),
164 request,
165 contextPtr
166 );
167}
168
169/// @overload
170template <typename CompletionToken>
172 Client& connection,
173 const SubscriptionParameters& parameters,
174 bool publishingEnabled,
175 StatusChangeNotificationCallback statusChangeCallback,
176 DeleteSubscriptionCallback deleteCallback,
177 CompletionToken&& token
178) {
179 const auto request = detail::makeCreateSubscriptionRequest(parameters, publishingEnabled);
181 connection,
182 asWrapper<CreateSubscriptionRequest>(request),
183 std::move(statusChangeCallback),
184 std::move(deleteCallback),
185 std::forward<CompletionToken>(token)
186 );
187}
188#endif
189
190/**
191 * @}
192 * @defgroup ModifySubscription ModifySubscription service
193 * Modify subscriptions.
194 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.14.3
195 * @{
196 */
197
198/**
199 * Modify a subscription.
200 * @param connection Instance of type Client
201 * @param request Modify subscription request
202 */
204 Client& connection, const ModifySubscriptionRequest& request
205) noexcept;
206
207/// @overload
209 Client& connection, IntegerId subscriptionId, const SubscriptionParameters& parameters
210) noexcept {
211 const auto request = detail::makeModifySubscriptionRequest(subscriptionId, parameters);
212 return modifySubscription(connection, asWrapper<ModifySubscriptionRequest>(request));
213}
214
215#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
216/**
217 * @copydoc modifySubscription(Client&, const ModifySubscriptionRequest&)
218 * @param token @completiontoken{void(ModifySubscriptionResponse&)}
219 * @return @asyncresult{ModifySubscriptionResponse}
220 */
221template <typename CompletionToken>
223 Client& connection, const ModifySubscriptionRequest& request, CompletionToken&& token
224) {
225 return detail::AsyncServiceAdapter<ModifySubscriptionResponse>::initiate(
226 connection,
227 [&connection](
229 void* userdata,
230 const ModifySubscriptionRequest& innerRequest
231 ) {
233 opcua::detail::getHandle(connection),
234 asNative(innerRequest),
235 callback,
236 userdata,
237 nullptr
238 ));
239 },
240 std::forward<CompletionToken>(token),
241 request
242 );
243}
244
245/// @overload
246template <typename CompletionToken>
248 Client& connection,
249 IntegerId subscriptionId,
250 const SubscriptionParameters& parameters,
251 CompletionToken&& token
252) {
253 const auto request = detail::makeModifySubscriptionRequest(subscriptionId, parameters);
255 connection,
256 asWrapper<ModifySubscriptionRequest>(request),
257 std::forward<CompletionToken>(token)
258 );
259}
260#endif
261
262/**
263 * @}
264 * @defgroup SetPublishingMode SetPublishingMode service
265 * Enable/disable sending of notifications on subscriptions.
266 * Disable publishing of NotificationMessages of the subscription doesn't discontinue the sending
267 * of keep-alive messages, nor change the monitoring mode.
268 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.14.4
269 * @{
270 */
271
272/**
273 * Enable/disable publishing of notification messages of subscriptions.
274 * @param connection Instance of type Client
275 * @param request Set publishing mode request
276 */
278 Client& connection, const SetPublishingModeRequest& request
279) noexcept;
280
281/**
282 * @copydoc setPublishingMode(Client&, const SetPublishingModeRequest&)
283 * @param token @completiontoken{void(SetPublishingModeResponse&)}
284 * @return @asyncresult{SetPublishingModeResponse}
285 */
286template <typename CompletionToken>
288 Client& connection, const SetPublishingModeRequest& request, CompletionToken&& token
289) {
290 return detail::sendRequestAsync<SetPublishingModeRequest, SetPublishingModeResponse>(
291 connection, request, std::forward<CompletionToken>(token)
292 );
293}
294
295/**
296 * Enable/disable publishing of notification messages of a single subscription.
297 * @param connection Instance of type Client
298 * @param subscriptionId Identifier of the subscription returned by @ref createSubscription
299 * @param publishing Enable/disable publishing
300 */
302 Client& connection, IntegerId subscriptionId, bool publishing
303) noexcept {
304 const auto request = detail::makeSetPublishingModeRequest(publishing, {&subscriptionId, 1});
305 return detail::getSingleStatus(
306 setPublishingMode(connection, asWrapper<SetPublishingModeRequest>(request))
307 );
308}
309
310/**
311 * @copydoc setPublishingMode(Client&, IntegerId, bool)
312 * @param token @completiontoken{void(StatusCode)}
313 * @return @asyncresult{StatusCode}
314 */
315template <typename CompletionToken>
317 Client& connection, IntegerId subscriptionId, bool publishing, CompletionToken&& token
318) {
319 const auto request = detail::makeSetPublishingModeRequest(publishing, {&subscriptionId, 1});
321 connection,
322 asWrapper<SetPublishingModeRequest>(request),
323 detail::TransformToken(
324 detail::getSingleStatus<UA_SetPublishingModeResponse>,
325 std::forward<CompletionToken>(token)
326 )
327 );
328}
329
330/**
331 * @}
332 * @defgroup DeleteSubscriptions DeleteSubscriptions service
333 * Delete subscriptions.
334 * @see https://reference.opcfoundation.org/Core/Part4/v105/docs/5.14.8
335 * @{
336 */
337
338/**
339 * Delete subscriptions.
340 * @param connection Instance of type Client
341 * @param request Delete subscriptions request
342 */
344 Client& connection, const DeleteSubscriptionsRequest& request
345) noexcept;
346
347#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
348/**
349 * @copydoc deleteSubscriptions
350 * @param token @completiontoken{void(DeleteSubscriptionsResponse&)}
351 * @return @asyncresult{DeleteSubscriptionsResponse}
352 */
353template <typename CompletionToken>
355 Client& connection, const DeleteSubscriptionsRequest& request, CompletionToken&& token
356) {
357 return detail::AsyncServiceAdapter<DeleteSubscriptionsResponse>::initiate(
358 connection,
359 [&connection](
361 void* userdata,
362 const DeleteSubscriptionsRequest& innerRequest
363 ) {
365 opcua::detail::getHandle(connection),
366 asNative(innerRequest),
367 callback,
368 userdata,
369 nullptr
370 ));
371 },
372 std::forward<CompletionToken>(token),
373 request
374 );
375}
376#endif
377
378/**
379 * Delete a single subscription.
380 * @param connection Instance of type Client
381 * @param subscriptionId Identifier of the subscription returned by @ref createSubscription
382 */
383inline StatusCode deleteSubscription(Client& connection, IntegerId subscriptionId) noexcept {
384 const auto request = detail::makeDeleteSubscriptionsRequest(subscriptionId);
385 return detail::getSingleStatus(
386 deleteSubscriptions(connection, asWrapper<DeleteSubscriptionsRequest>(request))
387 );
388}
389
390#if UAPP_HAS_ASYNC_SUBSCRIPTIONS
391/**
392 * @copydoc deleteSubscription
393 * @param token @completiontoken{void(StatusCode)}
394 * @return @asyncresult{StatusCode}
395 */
396template <typename CompletionToken>
398 Client& connection, IntegerId subscriptionId, CompletionToken&& token
399) {
400 const auto request = detail::makeDeleteSubscriptionsRequest(subscriptionId);
402 connection,
403 asWrapper<DeleteSubscriptionsRequest>(request),
404 detail::TransformToken{
405 detail::getSingleStatus<UA_DeleteSubscriptionsResponse>,
406 std::forward<CompletionToken>(token)
407 }
408 );
409}
410#endif
411
412/**
413 * @}
414 * @}
415 */
416
417} // namespace opcua::services
418
419#endif
High-level client class.
Definition client.hpp:130
UA_StatusCode wrapper class.
Definition types.hpp:41
UA_CreateSubscriptionRequest wrapper class.
Definition types.hpp:2257
UA_CreateSubscriptionResponse wrapper class.
Definition types.hpp:2293
IntegerId subscriptionId() const noexcept
Definition types.hpp:2298
UA_DeleteSubscriptionsRequest wrapper class.
Definition types.hpp:2410
UA_DeleteSubscriptionsResponse wrapper class.
Definition types.hpp:2429
UA_ModifySubscriptionRequest wrapper class.
Definition types.hpp:2309
UA_ModifySubscriptionResponse wrapper class.
Definition types.hpp:2345
UA_SetPublishingModeRequest wrapper class.
Definition types.hpp:2360
UA_SetPublishingModeResponse wrapper class.
Definition types.hpp:2383
UA_StatusChangeNotification wrapper class.
Definition types.hpp:2397
void(* UA_ClientAsyncServiceCallback)(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response)
UA_StatusCode UA_Client_Subscriptions_create_async(UA_Client *client, const UA_CreateSubscriptionRequest request, void *subscriptionContext, UA_Client_StatusChangeNotificationCallback statusChangeCallback, UA_Client_DeleteSubscriptionCallback deleteCallback, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *requestId)
UA_StatusCode UA_Client_Subscriptions_delete_async(UA_Client *client, const UA_DeleteSubscriptionsRequest request, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *requestId)
UA_StatusCode UA_Client_Subscriptions_modify_async(UA_Client *client, const UA_ModifySubscriptionRequest request, UA_ClientAsyncServiceCallback callback, void *userdata, UA_UInt32 *requestId)
auto createSubscriptionAsync(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback, CompletionToken &&token)
Create a subscription.
std::function< void(IntegerId subId, StatusChangeNotification &notification)> StatusChangeNotificationCallback
Subscription status change notification callback.
std::function< void(IntegerId subId)> DeleteSubscriptionCallback
Subscription deletion callback.
CreateSubscriptionResponse createSubscription(Client &connection, const CreateSubscriptionRequest &request, StatusChangeNotificationCallback statusChangeCallback, DeleteSubscriptionCallback deleteCallback)
Create a subscription.
DeleteSubscriptionsResponse deleteSubscriptions(Client &connection, const DeleteSubscriptionsRequest &request) noexcept
Delete subscriptions.
StatusCode deleteSubscription(Client &connection, IntegerId subscriptionId) noexcept
Delete a single subscription.
auto deleteSubscriptionsAsync(Client &connection, const DeleteSubscriptionsRequest &request, CompletionToken &&token)
Delete subscriptions.
auto deleteSubscriptionAsync(Client &connection, IntegerId subscriptionId, CompletionToken &&token)
Delete a single subscription.
ModifySubscriptionResponse modifySubscription(Client &connection, const ModifySubscriptionRequest &request) noexcept
Modify a subscription.
auto modifySubscriptionAsync(Client &connection, const ModifySubscriptionRequest &request, CompletionToken &&token)
Modify a subscription.
SetPublishingModeResponse setPublishingMode(Client &connection, const SetPublishingModeRequest &request) noexcept
Enable/disable publishing of notification messages of subscriptions.
auto setPublishingModeAsync(Client &connection, const SetPublishingModeRequest &request, CompletionToken &&token)
Enable/disable publishing of notification messages of subscriptions.
constexpr T::NativeType * asNative(T *wrapper) noexcept
Cast Wrapper object pointers to native object pointers.
Definition wrapper.hpp:342
OPC UA services as free functions.
Definition attribute.hpp:21
uint32_t IntegerId
IntegerId.
Definition types.hpp:84
constexpr void throwIfBad(UA_StatusCode code)
Check the status code and throw a BadStatus exception if the status code is bad.
Definition exception.hpp:85
Subscription parameters with default values from open62541.
uint8_t priority
Relative priority of the subscription. Notifications with higher priority are sent first.
uint32_t maxKeepAliveCount
Send keep-alive message after defined publishing cycles without notifications.
uint32_t maxNotificationsPerPublish
The maximum number of notifications per publish (0 if unlimited).
uint32_t lifetimeCount
Delete the subscription after defined publishing cycles without sending any notifications.
double publishingInterval
Cyclic interval in milliseconds that the subscription is requested to return notifications.