opcua/client/session/services.rs
1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5use std::{convert::TryFrom, sync::mpsc::SyncSender};
6
7use crate::{
8 client::callbacks::OnSubscriptionNotification,
9 core::supported_message::SupportedMessage,
10 types::{
11 node_ids::{MethodId, ObjectId},
12 status_code::StatusCode,
13 *,
14 },
15};
16
17/// Enumeration used with Session::history_read()
18pub enum HistoryReadAction {
19 ReadEventDetails(ReadEventDetails),
20 ReadRawModifiedDetails(ReadRawModifiedDetails),
21 ReadProcessedDetails(ReadProcessedDetails),
22 ReadAtTimeDetails(ReadAtTimeDetails),
23}
24
25impl From<HistoryReadAction> for ExtensionObject {
26 fn from(action: HistoryReadAction) -> Self {
27 match action {
28 HistoryReadAction::ReadEventDetails(v) => {
29 Self::from_encodable(ObjectId::ReadEventDetails_Encoding_DefaultBinary, &v)
30 }
31 HistoryReadAction::ReadRawModifiedDetails(v) => {
32 Self::from_encodable(ObjectId::ReadRawModifiedDetails_Encoding_DefaultBinary, &v)
33 }
34 HistoryReadAction::ReadProcessedDetails(v) => {
35 Self::from_encodable(ObjectId::ReadProcessedDetails_Encoding_DefaultBinary, &v)
36 }
37 HistoryReadAction::ReadAtTimeDetails(v) => {
38 Self::from_encodable(ObjectId::ReadAtTimeDetails_Encoding_DefaultBinary, &v)
39 }
40 }
41 }
42}
43
44/// Enumeration used with Session::history_update()
45pub enum HistoryUpdateAction {
46 UpdateDataDetails(UpdateDataDetails),
47 UpdateStructureDataDetails(UpdateStructureDataDetails),
48 UpdateEventDetails(UpdateEventDetails),
49 DeleteRawModifiedDetails(DeleteRawModifiedDetails),
50 DeleteAtTimeDetails(DeleteAtTimeDetails),
51 DeleteEventDetails(DeleteEventDetails),
52}
53
54impl From<&HistoryUpdateAction> for ExtensionObject {
55 fn from(action: &HistoryUpdateAction) -> Self {
56 match action {
57 HistoryUpdateAction::UpdateDataDetails(v) => {
58 Self::from_encodable(ObjectId::UpdateDataDetails_Encoding_DefaultBinary, v)
59 }
60 HistoryUpdateAction::UpdateStructureDataDetails(v) => Self::from_encodable(
61 ObjectId::UpdateStructureDataDetails_Encoding_DefaultBinary,
62 v,
63 ),
64 HistoryUpdateAction::UpdateEventDetails(v) => {
65 Self::from_encodable(ObjectId::UpdateEventDetails_Encoding_DefaultBinary, v)
66 }
67 HistoryUpdateAction::DeleteRawModifiedDetails(v) => {
68 Self::from_encodable(ObjectId::DeleteRawModifiedDetails_Encoding_DefaultBinary, v)
69 }
70 HistoryUpdateAction::DeleteAtTimeDetails(v) => {
71 Self::from_encodable(ObjectId::DeleteAtTimeDetails_Encoding_DefaultBinary, v)
72 }
73 HistoryUpdateAction::DeleteEventDetails(v) => {
74 Self::from_encodable(ObjectId::DeleteEventDetails_Encoding_DefaultBinary, v)
75 }
76 }
77 }
78}
79
80pub trait Service {
81 fn make_request_header(&self) -> RequestHeader;
82
83 /// Synchronously sends a request. The return value is the response to the request
84 fn send_request<T>(&self, request: T) -> Result<SupportedMessage, StatusCode>
85 where
86 T: Into<SupportedMessage>;
87
88 /// Asynchronously sends a request. The return value is the request handle of the request
89 fn async_send_request<T>(
90 &self,
91 request: T,
92 sender: Option<SyncSender<SupportedMessage>>,
93 ) -> Result<u32, StatusCode>
94 where
95 T: Into<SupportedMessage>;
96}
97
98/// Discovery Service set
99pub trait DiscoveryService: Service {
100 /// Sends a [`FindServersRequest`] to the server denoted by the discovery url.
101 ///
102 /// See OPC UA Part 4 - Services 5.4.2 for complete description of the service and error responses.
103 ///
104 /// # Arguments
105 ///
106 /// * `endpoint_url` - The network address that the Client used to access the Discovery Endpoint.
107 ///
108 /// # Returns
109 ///
110 /// * `Ok(Vec<ApplicationDescription>)` - A list of [`ApplicationDescription`] that meet criteria specified in the request.
111 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
112 ///
113 /// [`FindServersRequest`]: ./struct.FindServersRequest.html
114 /// [`ApplicationDescription`]: ./struct.ApplicationDescription.html
115 ///
116 fn find_servers<T>(&self, endpoint_url: T) -> Result<Vec<ApplicationDescription>, StatusCode>
117 where
118 T: Into<UAString>;
119
120 /// Obtain the list of endpoints supported by the server by sending it a [`GetEndpointsRequest`].
121 ///
122 /// See OPC UA Part 4 - Services 5.4.4 for complete description of the service and error responses.
123 ///
124 /// # Returns
125 ///
126 /// * `Ok(Vec<EndpointDescription>)` - A list of endpoints supported by the server
127 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
128 ///
129 /// [`GetEndpointsRequest`]: ./struct.GetEndpointsRequest.html
130 ///
131 fn get_endpoints(&self) -> Result<Vec<EndpointDescription>, StatusCode>;
132
133 /// This function is used by servers that wish to register themselves with a discovery server.
134 /// i.e. one server is the client to another server. The server sends a [`RegisterServerRequest`]
135 /// to the discovery server to register itself. Servers are expected to re-register themselves periodically
136 /// with the discovery server, with a maximum of 10 minute intervals.
137 ///
138 /// See OPC UA Part 4 - Services 5.4.5 for complete description of the service and error responses.
139 ///
140 /// # Arguments
141 ///
142 /// * `server` - The server to register
143 ///
144 /// # Returns
145 ///
146 /// * `Ok(())` - Success
147 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
148 ///
149 /// [`RegisterServerRequest`]: ./struct.RegisterServerRequest.html
150 ///
151 fn register_server(&self, server: RegisteredServer) -> Result<(), StatusCode>;
152}
153
154/// SecureChannel Service set
155pub trait SecureChannelService: Service {
156 /// Sends an [`OpenSecureChannelRequest`] to the server
157 ///
158 ///
159 /// See OPC UA Part 4 - Services 5.5.2 for complete description of the service and error responses.
160 /// # Returns
161 ///
162 /// * `Ok(())` - Success
163 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
164 ///
165 /// [`OpenSecureChannelRequest`]: ./struct.OpenSecureChannelRequest.html
166 ///
167 fn open_secure_channel(&self) -> Result<(), StatusCode>;
168
169 /// Sends a [`CloseSecureChannelRequest`] to the server which will cause the server to drop
170 /// the connection.
171 ///
172 /// See OPC UA Part 4 - Services 5.5.3 for complete description of the service and error responses.
173 ///
174 /// # Returns
175 ///
176 /// * `Ok(())` - Success
177 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
178 ///
179 /// [`CloseSecureChannelRequest`]: ./struct.CloseSecureChannelRequest.html
180 ///
181 fn close_secure_channel(&self) -> Result<(), StatusCode>;
182}
183
184/// Session Service set
185pub trait SessionService: Service {
186 /// Sends a [`CreateSessionRequest`] to the server, returning the session id of the created
187 /// session. Internally, the session will store the authentication token which is used for requests
188 /// subsequent to this call.
189 ///
190 /// See OPC UA Part 4 - Services 5.6.2 for complete description of the service and error responses.
191 ///
192 /// # Returns
193 ///
194 /// * `Ok(NodeId)` - Success, session id
195 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
196 ///
197 /// [`CreateSessionRequest`]: ./struct.CreateSessionRequest.html
198 ///
199 fn create_session(&self) -> Result<NodeId, StatusCode>;
200
201 /// Sends an [`ActivateSessionRequest`] to the server to activate this session
202 ///
203 /// See OPC UA Part 4 - Services 5.6.3 for complete description of the service and error responses.
204 ///
205 /// # Returns
206 ///
207 /// * `Ok(())` - Success
208 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
209 ///
210 /// [`ActivateSessionRequest`]: ./struct.ActivateSessionRequest.html
211 ///
212 fn activate_session(&self) -> Result<(), StatusCode>;
213
214 /// Cancels an outstanding service request by sending a [`CancelRequest`] to the server.
215 ///
216 /// See OPC UA Part 4 - Services 5.6.5 for complete description of the service and error responses.
217 ///
218 /// # Arguments
219 ///
220 /// * `request_handle` - Handle to the outstanding request to be cancelled.
221 ///
222 /// # Returns
223 ///
224 /// * `Ok(u32)` - Success, number of cancelled requests
225 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
226 ///
227 /// [`CancelRequest`]: ./struct.CancelRequest.html
228 ///
229 fn cancel(&self, request_handle: IntegerId) -> Result<u32, StatusCode>;
230}
231
232/// NodeManagement Service set
233
234pub trait NodeManagementService: Service {
235 /// Add nodes by sending a [`AddNodesRequest`] to the server.
236 ///
237 /// See OPC UA Part 4 - Services 5.7.2 for complete description of the service and error responses.
238 ///
239 /// # Arguments
240 ///
241 /// * `nodes_to_add` - A list of [`AddNodesItem`] to be added to the server.
242 ///
243 /// # Returns
244 ///
245 /// * `Ok(Vec<AddNodesResult>)` - A list of [`AddNodesResult`] corresponding to each add node operation.
246 /// * `Err(StatusCode)` - Status code reason for failure.
247 ///
248 /// [`AddNodesRequest`]: ./struct.AddNodesRequest.html
249 /// [`AddNodesItem`]: ./struct.AddNodesItem.html
250 /// [`AddNodesResult`]: ./struct.AddNodesResult.html
251 ///
252 fn add_nodes(&self, nodes_to_add: &[AddNodesItem]) -> Result<Vec<AddNodesResult>, StatusCode>;
253
254 /// Add references by sending a [`AddReferencesRequest`] to the server.
255 ///
256 /// See OPC UA Part 4 - Services 5.7.3 for complete description of the service and error responses.
257 ///
258 /// # Arguments
259 ///
260 /// * `references_to_add` - A list of [`AddReferencesItem`] to be sent to the server.
261 ///
262 /// # Returns
263 ///
264 /// * `Ok(Vec<StatusCode>)` - A list of `StatusCode` corresponding to each add reference operation.
265 /// * `Err(StatusCode)` - Status code reason for failure.
266 ///
267 /// [`AddReferencesRequest`]: ./struct.AddReferencesRequest.html
268 /// [`AddReferencesItem`]: ./struct.AddReferencesItem.html
269 ///
270 fn add_references(
271 &self,
272 references_to_add: &[AddReferencesItem],
273 ) -> Result<Vec<StatusCode>, StatusCode>;
274
275 /// Delete nodes by sending a [`DeleteNodesRequest`] to the server.
276 ///
277 /// See OPC UA Part 4 - Services 5.7.4 for complete description of the service and error responses.
278 ///
279 /// # Arguments
280 ///
281 /// * `nodes_to_delete` - A list of [`DeleteNodesItem`] to be sent to the server.
282 ///
283 /// # Returns
284 ///
285 /// * `Ok(Vec<StatusCode>)` - A list of `StatusCode` corresponding to each delete node operation.
286 /// * `Err(StatusCode)` - Status code reason for failure.
287 ///
288 /// [`DeleteNodesRequest`]: ./struct.DeleteNodesRequest.html
289 /// [`DeleteNodesItem`]: ./struct.DeleteNodesItem.html
290 ///
291 fn delete_nodes(
292 &self,
293 nodes_to_delete: &[DeleteNodesItem],
294 ) -> Result<Vec<StatusCode>, StatusCode>;
295
296 /// Delete references by sending a [`DeleteReferencesRequest`] to the server.
297 ///
298 /// See OPC UA Part 4 - Services 5.7.5 for complete description of the service and error responses.
299 ///
300 /// # Arguments
301 ///
302 /// * `nodes_to_delete` - A list of [`DeleteReferencesItem`] to be sent to the server.
303 ///
304 /// # Returns
305 ///
306 /// * `Ok(Vec<StatusCode>)` - A list of `StatusCode` corresponding to each delete node operation.
307 /// * `Err(StatusCode)` - Status code reason for failure.
308 ///
309 /// [`DeleteReferencesRequest`]: ./struct.DeleteReferencesRequest.html
310 /// [`DeleteReferencesItem`]: ./struct.DeleteReferencesItem.html
311 ///
312 fn delete_references(
313 &self,
314 references_to_delete: &[DeleteReferencesItem],
315 ) -> Result<Vec<StatusCode>, StatusCode>;
316}
317
318/// View Service set
319pub trait ViewService: Service {
320 /// Discover the references to the specified nodes by sending a [`BrowseRequest`] to the server.
321 ///
322 /// See OPC UA Part 4 - Services 5.8.2 for complete description of the service and error responses.
323 ///
324 /// # Arguments
325 ///
326 /// * `nodes_to_browse` - A list of [`BrowseDescription`] describing nodes to browse.
327 ///
328 /// # Returns
329 ///
330 /// * `Ok(Option<Vec<BrowseResult>)` - A list [`BrowseResult`] corresponding to each node to browse. A browse result
331 /// may contain a continuation point, for use with `browse_next()`.
332 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
333 ///
334 /// [`BrowseRequest`]: ./struct.BrowseRequest.html
335 /// [`BrowseDescription`]: ./struct.BrowseDescription.html
336 /// [`BrowseResult`]: ./struct.BrowseResult.html
337 ///
338 fn browse(
339 &self,
340 nodes_to_browse: &[BrowseDescription],
341 ) -> Result<Option<Vec<BrowseResult>>, StatusCode>;
342
343 /// Continue to discover references to nodes by sending continuation points in a [`BrowseNextRequest`]
344 /// to the server. This function may have to be called repeatedly to process the initial query.
345 ///
346 /// See OPC UA Part 4 - Services 5.8.3 for complete description of the service and error responses.
347 ///
348 /// # Arguments
349 ///
350 /// * `release_continuation_points` - Flag indicating if the continuation points should be released by the server
351 /// * `continuation_points` - A list of [`BrowseDescription`] continuation points
352 ///
353 /// # Returns
354 ///
355 /// * `Ok(Option<Vec<BrowseResult>)` - A list [`BrowseResult`] corresponding to each node to browse. A browse result
356 /// may contain a continuation point, for use with `browse_next()`.
357 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
358 ///
359 /// [`BrowseRequest`]: ./struct.BrowseRequest.html
360 /// [`BrowseNextRequest`]: ./struct.BrowseNextRequest.html
361 /// [`BrowseResult`]: ./struct.BrowseResult.html
362 ///
363 fn browse_next(
364 &self,
365 release_continuation_points: bool,
366 continuation_points: &[ByteString],
367 ) -> Result<Option<Vec<BrowseResult>>, StatusCode>;
368
369 /// Translate browse paths to NodeIds by sending a [`TranslateBrowsePathsToNodeIdsRequest`] request to the Server
370 /// Each [`BrowsePath`] is constructed of a starting node and a `RelativePath`. The specified starting node
371 /// identifies the node from which the RelativePath is based. The RelativePath contains a sequence of
372 /// ReferenceTypes and BrowseNames.
373 ///
374 /// See OPC UA Part 4 - Services 5.8.4 for complete description of the service and error responses.
375 ///
376 /// # Arguments
377 ///
378 /// * `browse_paths` - A list of [`BrowsePath`] node + relative path for the server to look up
379 ///
380 /// # Returns
381 ///
382 /// * `Ok(Vec<BrowsePathResult>>)` - List of [`BrowsePathResult`] for the list of browse
383 /// paths. The size and order of the list matches the size and order of the `browse_paths`
384 /// parameter.
385 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
386 ///
387 /// [`TranslateBrowsePathsToNodeIdsRequest`]: ./struct.TranslateBrowsePathsToNodeIdsRequest.html
388 /// [`BrowsePath`]: ./struct.BrowsePath.html
389 /// [`BrowsePathResult`]: ./struct.BrowsePathResult.html
390 fn translate_browse_paths_to_node_ids(
391 &self,
392 browse_paths: &[BrowsePath],
393 ) -> Result<Vec<BrowsePathResult>, StatusCode>;
394
395 /// Register nodes on the server by sending a [`RegisterNodesRequest`]. The purpose of this
396 /// call is server-dependent but allows a client to ask a server to create nodes which are
397 /// otherwise expensive to set up or maintain, e.g. nodes attached to hardware.
398 ///
399 /// See OPC UA Part 4 - Services 5.8.5 for complete description of the service and error responses.
400 ///
401 /// # Arguments
402 ///
403 /// * `nodes_to_register` - A list of [`NodeId`] nodes for the server to register
404 ///
405 /// # Returns
406 ///
407 /// * `Ok(Vec<NodeId>)` - A list of [`NodeId`] corresponding to size and order of the input. The
408 /// server may return an alias for the input `NodeId`
409 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
410 ///
411 /// [`RegisterNodesRequest`]: ./struct.RegisterNodesRequest.html
412 /// [`NodeId`]: ./struct.NodeId.html
413 fn register_nodes(&self, nodes_to_register: &[NodeId]) -> Result<Vec<NodeId>, StatusCode>;
414
415 /// Unregister nodes on the server by sending a [`UnregisterNodesRequest`]. This indicates to
416 /// the server that the client relinquishes any need for these nodes. The server will ignore
417 /// unregistered nodes.
418 ///
419 /// See OPC UA Part 4 - Services 5.8.5 for complete description of the service and error responses.
420 ///
421 /// # Arguments
422 ///
423 /// * `nodes_to_unregister` - A list of [`NodeId`] nodes for the server to unregister
424 ///
425 /// # Returns
426 ///
427 /// * `Ok(())` - Request succeeded, server ignores invalid nodes
428 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
429 ///
430 /// [`UnregisterNodesRequest`]: ./struct.UnregisterNodesRequest.html
431 /// [`NodeId`]: ./struct.NodeId.html
432 ///
433 fn unregister_nodes(&self, nodes_to_unregister: &[NodeId]) -> Result<(), StatusCode>;
434}
435
436/// Attribute Service set
437pub trait AttributeService: Service {
438 /// Reads the value of nodes by sending a [`ReadRequest`] to the server.
439 ///
440 /// See OPC UA Part 4 - Services 5.10.2 for complete description of the service and error responses.
441 ///
442 /// # Arguments
443 ///
444 /// * `nodes_to_read` - A list of [`ReadValueId`] to be read by the server.
445 /// * `timestamps_to_return` - The [`TimestampsToReturn`] for each node, Both, Server, Source or None
446 /// * `max_age` - The maximum age of value to read in milliseconds. Read the service description
447 /// for details. Basically it will attempt to read a value within the age range or
448 /// attempt to read a new value. If 0 the server will attempt to read a new value from the datasource.
449 /// If set to `i32::MAX` or greater, the server shall attempt to get a cached value.
450 ///
451 /// # Returns
452 ///
453 /// * `Ok(Vec<DataValue>)` - A list of [`DataValue`] corresponding to each read operation.
454 /// * `Err(StatusCode)` - Status code reason for failure.
455 ///
456 /// [`ReadRequest`]: ./struct.ReadRequest.html
457 /// [`ReadValueId`]: ./struct.ReadValueId.html
458 /// [`DataValue`]: ./struct.DataValue.html
459 ///
460 fn read(
461 &self,
462 nodes_to_read: &[ReadValueId],
463 timestamps_to_return: TimestampsToReturn,
464 max_age: f64,
465 ) -> Result<Vec<DataValue>, StatusCode>;
466
467 /// Reads historical values or events of one or more nodes. The caller is expected to provide
468 /// a HistoryReadAction enum which must be one of the following:
469 ///
470 /// * HistoryReadAction::ReadEventDetails
471 /// * HistoryReadAction::ReadRawModifiedDetails
472 /// * HistoryReadAction::ReadProcessedDetails
473 /// * HistoryReadAction::ReadAtTimeDetails
474 ///
475 /// See OPC UA Part 4 - Services 5.10.3 for complete description of the service and error responses.
476 ///
477 /// # Arguments
478 ///
479 /// * `history_read_details` - A history read operation encoded in an `ExtensionObject`.
480 /// * `timestamps_to_return` - Enumeration of which timestamps to return.
481 /// * `release_continuation_points` - Flag indicating whether to release the continuation point for the operation.
482 /// * `nodes_to_read` - The list of `HistoryReadValueId` of the nodes to apply the history read operation to.
483 ///
484 /// # Returns
485 ///
486 /// * `Ok(Vec<HistoryReadResult>)` - A list of `HistoryReadResult` results corresponding to history read operation.
487 /// * `Err(StatusCode)` - Status code reason for failure.
488 ///
489 fn history_read(
490 &self,
491 history_read_details: HistoryReadAction,
492 timestamps_to_return: TimestampsToReturn,
493 release_continuation_points: bool,
494 nodes_to_read: &[HistoryReadValueId],
495 ) -> Result<Vec<HistoryReadResult>, StatusCode>;
496
497 /// Writes values to nodes by sending a [`WriteRequest`] to the server. Note that some servers may reject DataValues
498 /// containing source or server timestamps.
499 ///
500 /// See OPC UA Part 4 - Services 5.10.4 for complete description of the service and error responses.
501 ///
502 /// # Arguments
503 ///
504 /// * `nodes_to_write` - A list of [`WriteValue`] to be sent to the server.
505 ///
506 /// # Returns
507 ///
508 /// * `Ok(Vec<StatusCode>)` - A list of `StatusCode` results corresponding to each write operation.
509 /// * `Err(StatusCode)` - Status code reason for failure.
510 ///
511 /// [`WriteRequest`]: ./struct.WriteRequest.html
512 /// [`WriteValue`]: ./struct.WriteValue.html
513 ///
514 fn write(&self, nodes_to_write: &[WriteValue]) -> Result<Vec<StatusCode>, StatusCode>;
515
516 /// Updates historical values. The caller is expected to provide one or more history update operations
517 /// in a slice of HistoryUpdateAction enums which are one of the following:
518 ///
519 /// * UpdateDataDetails
520 /// * UpdateStructureDataDetails
521 /// * UpdateEventDetails
522 /// * DeleteRawModifiedDetails
523 /// * DeleteAtTimeDetails
524 /// * DeleteEventDetails
525 ///
526 /// See OPC UA Part 4 - Services 5.10.5 for complete description of the service and error responses.
527 ///
528 /// # Arguments
529 ///
530 /// * `history_update_details` - A list of history update operations each encoded as an `ExtensionObject`.
531 ///
532 /// # Returns
533 ///
534 /// * `Ok(Vec<ClientHistoryUpdateResult>)` - A list of `ClientHistoryUpdateResult` results corresponding to history update operation.
535 /// * `Err(StatusCode)` - Status code reason for failure.
536 ///
537 fn history_update(
538 &self,
539 history_update_details: &[HistoryUpdateAction],
540 ) -> Result<Vec<HistoryUpdateResult>, StatusCode>;
541}
542
543/// Method Service set
544pub trait MethodService: Service {
545 /// Calls a single method on an object on the server by sending a [`CallRequest`] to the server.
546 ///
547 /// See OPC UA Part 4 - Services 5.11.2 for complete description of the service and error responses.
548 ///
549 /// # Arguments
550 ///
551 /// * `method` - The method to call. Note this function takes anything that can be turned into
552 /// a [`CallMethodRequest`] which includes a (`NodeId`, `NodeId`, `Option<Vec<Variant>>`)
553 /// which refers to the object id, method id, and input arguments respectively.
554 ///
555 /// # Returns
556 ///
557 /// * `Ok(CallMethodResult)` - A `[CallMethodResult]` for the Method call.
558 /// * `Err(StatusCode)` - Status code reason for failure.
559 ///
560 /// [`CallRequest`]: ./struct.CallRequest.html
561 /// [`CallMethodRequest`]: ./struct.CallMethodRequest.html
562 /// [`CallMethodResult`]: ./struct.CallMethodResult.html
563 ///
564 fn call<T>(&self, method: T) -> Result<CallMethodResult, StatusCode>
565 where
566 T: Into<CallMethodRequest>;
567
568 /// Calls GetMonitoredItems via call_method(), putting a sane interface on the input / output.
569 ///
570 /// # Arguments
571 ///
572 /// * `subscription_id` - Server allocated identifier for the subscription to return monitored items for.
573 ///
574 /// # Returns
575 ///
576 /// * `Ok((Vec<u32>, Vec<u32>))` - Result for call, consisting a list of (monitored_item_id, client_handle)
577 /// * `Err(StatusCode)` - Status code reason for failure.
578 ///
579 fn call_get_monitored_items(
580 &self,
581 subscription_id: u32,
582 ) -> Result<(Vec<u32>, Vec<u32>), StatusCode> {
583 let args = Some(vec![Variant::from(subscription_id)]);
584 let object_id: NodeId = ObjectId::Server.into();
585 let method_id: NodeId = MethodId::Server_GetMonitoredItems.into();
586 let request: CallMethodRequest = (object_id, method_id, args).into();
587 let response = self.call(request)?;
588 if let Some(mut result) = response.output_arguments {
589 if result.len() == 2 {
590 let server_handles = <Vec<u32>>::try_from(&result.remove(0))
591 .map_err(|_| StatusCode::BadUnexpectedError)?;
592 let client_handles = <Vec<u32>>::try_from(&result.remove(0))
593 .map_err(|_| StatusCode::BadUnexpectedError)?;
594 Ok((server_handles, client_handles))
595 } else {
596 error!("Expected a result with 2 args and didn't get it.");
597 Err(StatusCode::BadUnexpectedError)
598 }
599 } else {
600 error!("Expected a result and didn't get it.");
601 Err(StatusCode::BadUnexpectedError)
602 }
603 }
604}
605
606////////////////////////////////////////////////////////////////////////////////////////////////
607// MonitoredItem Service set
608////////////////////////////////////////////////////////////////////////////////////////////////
609pub trait MonitoredItemService: Service {
610 /// Creates monitored items on a subscription by sending a [`CreateMonitoredItemsRequest`] to the server.
611 ///
612 /// See OPC UA Part 4 - Services 5.12.2 for complete description of the service and error responses.
613 ///
614 /// # Arguments
615 ///
616 /// * `subscription_id` - The Server-assigned identifier for the Subscription that will report Notifications for this MonitoredItem
617 /// * `timestamps_to_return` - An enumeration that specifies the timestamp Attributes to be transmitted for each MonitoredItem.
618 /// * `items_to_create` - A list of [`MonitoredItemCreateRequest`] to be created and assigned to the specified Subscription.
619 ///
620 /// # Returns
621 ///
622 /// * `Ok(Vec<MonitoredItemCreateResult>)` - A list of [`MonitoredItemCreateResult`] corresponding to the items to create.
623 /// The size and order of the list matches the size and order of the `items_to_create` request parameter.
624 /// * `Err(StatusCode)` - Status code reason for failure
625 ///
626 /// [`CreateMonitoredItemsRequest`]: ./struct.CreateMonitoredItemsRequest.html
627 /// [`MonitoredItemCreateRequest`]: ./struct.MonitoredItemCreateRequest.html
628 /// [`MonitoredItemCreateResult`]: ./struct.MonitoredItemCreateResult.html
629 ///
630 fn create_monitored_items(
631 &self,
632 subscription_id: u32,
633 timestamps_to_return: TimestampsToReturn,
634 items_to_create: &[MonitoredItemCreateRequest],
635 ) -> Result<Vec<MonitoredItemCreateResult>, StatusCode>;
636
637 /// Modifies monitored items on a subscription by sending a [`ModifyMonitoredItemsRequest`] to the server.
638 ///
639 /// See OPC UA Part 4 - Services 5.12.3 for complete description of the service and error responses.
640 ///
641 /// # Arguments
642 ///
643 /// * `subscription_id` - The Server-assigned identifier for the Subscription that will report Notifications for this MonitoredItem.
644 /// * `timestamps_to_return` - An enumeration that specifies the timestamp Attributes to be transmitted for each MonitoredItem.
645 /// * `items_to_modify` - The list of [`MonitoredItemModifyRequest`] to modify.
646 ///
647 /// # Returns
648 ///
649 /// * `Ok(Vec<MonitoredItemModifyResult>)` - A list of [`MonitoredItemModifyResult`] corresponding to the MonitoredItems to modify.
650 /// The size and order of the list matches the size and order of the `items_to_modify` request parameter.
651 /// * `Err(StatusCode)` - Status code reason for failure.
652 ///
653 /// [`ModifyMonitoredItemsRequest`]: ./struct.ModifyMonitoredItemsRequest.html
654 /// [`MonitoredItemModifyRequest`]: ./struct.MonitoredItemModifyRequest.html
655 /// [`MonitoredItemModifyResult`]: ./struct.MonitoredItemModifyResult.html
656 ///
657 fn modify_monitored_items(
658 &self,
659 subscription_id: u32,
660 timestamps_to_return: TimestampsToReturn,
661 items_to_modify: &[MonitoredItemModifyRequest],
662 ) -> Result<Vec<MonitoredItemModifyResult>, StatusCode>;
663
664 /// Sets the monitoring mode on one or more monitored items by sending a [`SetMonitoringModeRequest`]
665 /// to the server.
666 ///
667 /// See OPC UA Part 4 - Services 5.12.4 for complete description of the service and error responses.
668 ///
669 /// # Arguments
670 ///
671 /// * `subscription_id` - the subscription identifier containing the monitored items to be modified.
672 /// * `monitoring_mode` - the monitored mode to apply to the monitored items
673 /// * `monitored_item_ids` - the monitored items to be modified
674 ///
675 /// # Returns
676 ///
677 /// * `Ok(Vec<StatusCode>)` - Individual result for each monitored item.
678 /// * `Err(StatusCode)` - Status code reason for failure.
679 ///
680 /// [`SetMonitoringModeRequest`]: ./struct.SetMonitoringModeRequest.html
681 ///
682 fn set_monitoring_mode(
683 &self,
684 subscription_id: u32,
685 monitoring_mode: MonitoringMode,
686 monitored_item_ids: &[u32],
687 ) -> Result<Vec<StatusCode>, StatusCode>;
688
689 /// Sets a monitored item so it becomes the trigger that causes other monitored items to send
690 /// change events in the same update. Sends a [`SetTriggeringRequest`] to the server.
691 /// Note that `items_to_remove` is applied before `items_to_add`.
692 ///
693 /// See OPC UA Part 4 - Services 5.12.5 for complete description of the service and error responses.
694 ///
695 /// # Arguments
696 ///
697 /// * `subscription_id` - the subscription identifier containing the monitored item to be used as the trigger.
698 /// * `monitored_item_id` - the monitored item that is the trigger.
699 /// * `links_to_add` - zero or more items to be added to the monitored item's triggering list.
700 /// * `items_to_remove` - zero or more items to be removed from the monitored item's triggering list.
701 ///
702 /// # Returns
703 ///
704 /// * `Ok((Option<Vec<StatusCode>>, Option<Vec<StatusCode>>))` - Individual result for each item added / removed for the SetTriggering call.
705 /// * `Err(StatusCode)` - Status code reason for failure.
706 ///
707 /// [`SetTriggeringRequest`]: ./struct.SetTriggeringRequest.html
708 ///
709 fn set_triggering(
710 &self,
711 subscription_id: u32,
712 triggering_item_id: u32,
713 links_to_add: &[u32],
714 links_to_remove: &[u32],
715 ) -> Result<(Option<Vec<StatusCode>>, Option<Vec<StatusCode>>), StatusCode>;
716
717 /// Deletes monitored items from a subscription by sending a [`DeleteMonitoredItemsRequest`] to the server.
718 ///
719 /// See OPC UA Part 4 - Services 5.12.6 for complete description of the service and error responses.
720 ///
721 /// # Arguments
722 ///
723 /// * `subscription_id` - The Server-assigned identifier for the Subscription that will report Notifications for this MonitoredItem.
724 /// * `items_to_delete` - List of Server-assigned ids for the MonitoredItems to be deleted.
725 ///
726 /// # Returns
727 ///
728 /// * `Ok(Vec<StatusCode>)` - List of StatusCodes for the MonitoredItems to delete. The size and
729 /// order of the list matches the size and order of the `items_to_delete` request parameter.
730 /// * `Err(StatusCode)` - Status code reason for failure.
731 ///
732 /// [`DeleteMonitoredItemsRequest`]: ./struct.DeleteMonitoredItemsRequest.html
733 ///
734 fn delete_monitored_items(
735 &self,
736 subscription_id: u32,
737 items_to_delete: &[u32],
738 ) -> Result<Vec<StatusCode>, StatusCode>;
739}
740
741////////////////////////////////////////////////////////////////////////////////////////////////
742// Subscription Service set
743////////////////////////////////////////////////////////////////////////////////////////////////
744pub trait SubscriptionService: Service {
745 /// Create a subscription by sending a [`CreateSubscriptionRequest`] to the server.
746 ///
747 /// See OPC UA Part 4 - Services 5.13.2 for complete description of the service and error responses.
748 ///
749 /// # Arguments
750 ///
751 /// * `publishing_interval` - The requested publishing interval defines the cyclic rate that
752 /// the Subscription is being requested to return Notifications to the Client. This interval
753 /// is expressed in milliseconds. This interval is represented by the publishing timer in the
754 /// Subscription state table. The negotiated value for this parameter returned in the
755 /// response is used as the default sampling interval for MonitoredItems assigned to this
756 /// Subscription. If the requested value is 0 or negative, the server shall revise with the
757 /// fastest supported publishing interval in milliseconds.
758 /// * `lifetime_count` - Requested lifetime count. The lifetime count shall be a minimum of
759 /// three times the keep keep-alive count. When the publishing timer has expired this
760 /// number of times without a Publish request being available to send a NotificationMessage,
761 /// then the Subscription shall be deleted by the Server.
762 /// * `max_keep_alive_count` - Requested maximum keep-alive count. When the publishing timer has
763 /// expired this number of times without requiring any NotificationMessage to be sent, the
764 /// Subscription sends a keep-alive Message to the Client. The negotiated value for this
765 /// parameter is returned in the response. If the requested value is 0, the server shall
766 /// revise with the smallest supported keep-alive count.
767 /// * `max_notifications_per_publish` - The maximum number of notifications that the Client
768 /// wishes to receive in a single Publish response. A value of zero indicates that there is
769 /// no limit. The number of notifications per Publish is the sum of monitoredItems in
770 /// the DataChangeNotification and events in the EventNotificationList.
771 /// * `priority` - Indicates the relative priority of the Subscription. When more than one
772 /// Subscription needs to send Notifications, the Server should de-queue a Publish request
773 /// to the Subscription with the highest priority number. For Subscriptions with equal
774 /// priority the Server should de-queue Publish requests in a round-robin fashion.
775 /// A Client that does not require special priority settings should set this value to zero.
776 /// * `publishing_enabled` - A boolean parameter with the following values - `true` publishing
777 /// is enabled for the Subscription, `false`, publishing is disabled for the Subscription.
778 /// The value of this parameter does not affect the value of the monitoring mode Attribute of
779 /// MonitoredItems.
780 ///
781 /// # Returns
782 ///
783 /// * `Ok(u32)` - identifier for new subscription
784 /// * `Err(StatusCode)` - Status code reason for failure
785 ///
786 /// [`CreateSubscriptionRequest`]: ./struct.CreateSubscriptionRequest.html
787 ///
788 fn create_subscription<CB>(
789 &self,
790 publishing_interval: f64,
791 lifetime_count: u32,
792 max_keep_alive_count: u32,
793 max_notifications_per_publish: u32,
794 priority: u8,
795 publishing_enabled: bool,
796 callback: CB,
797 ) -> Result<u32, StatusCode>
798 where
799 CB: OnSubscriptionNotification + Send + Sync + 'static;
800
801 /// Modifies a subscription by sending a [`ModifySubscriptionRequest`] to the server.
802 ///
803 /// See OPC UA Part 4 - Services 5.13.3 for complete description of the service and error responses.
804 ///
805 /// # Arguments
806 ///
807 /// * `subscription_id` - subscription identifier returned from `create_subscription`.
808 ///
809 /// See `create_subscription` for description of other parameters
810 ///
811 /// # Returns
812 ///
813 /// * `Ok(())` - Success
814 /// * `Err(StatusCode)` - Request failed, status code is the reason for failure
815 ///
816 /// [`ModifySubscriptionRequest`]: ./struct.ModifySubscriptionRequest.html
817 ///
818 fn modify_subscription(
819 &self,
820 subscription_id: u32,
821 publishing_interval: f64,
822 lifetime_count: u32,
823 max_keep_alive_count: u32,
824 max_notifications_per_publish: u32,
825 priority: u8,
826 ) -> Result<(), StatusCode>;
827
828 /// Changes the publishing mode of subscriptions by sending a [`SetPublishingModeRequest`] to the server.
829 ///
830 /// See OPC UA Part 4 - Services 5.13.4 for complete description of the service and error responses.
831 ///
832 /// # Arguments
833 ///
834 /// * `subscription_ids` - one or more subscription identifiers.
835 /// * `publishing_enabled` - A boolean parameter with the following values - `true` publishing
836 /// is enabled for the Subscriptions, `false`, publishing is disabled for the Subscriptions.
837 ///
838 /// # Returns
839 ///
840 /// * `Ok(Vec<StatusCode>)` - Service return code for the action for each id, `Good` or `BadSubscriptionIdInvalid`
841 /// * `Err(StatusCode)` - Status code reason for failure
842 ///
843 /// [`SetPublishingModeRequest`]: ./struct.SetPublishingModeRequest.html
844 ///
845 fn set_publishing_mode(
846 &self,
847 subscription_ids: &[u32],
848 publishing_enabled: bool,
849 ) -> Result<Vec<StatusCode>, StatusCode>;
850
851 /// Transfers Subscriptions and their MonitoredItems from one Session to another. For example,
852 /// a Client may need to reopen a Session and then transfer its Subscriptions to that Session.
853 /// It may also be used by one Client to take over a Subscription from another Client by
854 /// transferring the Subscription to its Session.
855 ///
856 /// See OPC UA Part 4 - Services 5.13.7 for complete description of the service and error responses.
857 ///
858 /// * `subscription_ids` - one or more subscription identifiers.
859 /// * `send_initial_values` - A boolean parameter with the following values - `true` the first
860 /// publish response shall contain the current values of all monitored items in the subscription,
861 /// `false`, the first publish response shall contain only the value changes since the last
862 /// publish response was sent.
863 ///
864 /// # Returns
865 ///
866 /// * `Ok(Vec<TransferResult>)` - The [`TransferResult`] for each transfer subscription.
867 /// * `Err(StatusCode)` - Status code reason for failure
868 ///
869 /// [`TransferSubscriptionsRequest`]: ./struct.TransferSubscriptionsRequest.html
870 /// [`TransferResult`]: ./struct.TransferResult.html
871 ///
872 fn transfer_subscriptions(
873 &self,
874 subscription_ids: &[u32],
875 send_initial_values: bool,
876 ) -> Result<Vec<TransferResult>, StatusCode>;
877
878 /// Deletes a subscription by sending a [`DeleteSubscriptionsRequest`] to the server.
879 ///
880 /// See OPC UA Part 4 - Services 5.13.8 for complete description of the service and error responses.
881 ///
882 /// # Arguments
883 ///
884 /// * `subscription_id` - subscription identifier returned from `create_subscription`.
885 ///
886 /// # Returns
887 ///
888 /// * `Ok(StatusCode)` - Service return code for the delete action, `Good` or `BadSubscriptionIdInvalid`
889 /// * `Err(StatusCode)` - Status code reason for failure
890 ///
891 /// [`DeleteSubscriptionsRequest`]: ./struct.DeleteSubscriptionsRequest.html
892 ///
893 fn delete_subscription(&self, subscription_id: u32) -> Result<StatusCode, StatusCode>;
894
895 /// Deletes subscriptions by sending a [`DeleteSubscriptionsRequest`] to the server with the list
896 /// of subscriptions to delete.
897 ///
898 /// See OPC UA Part 4 - Services 5.13.8 for complete description of the service and error responses.
899 ///
900 /// # Arguments
901 ///
902 /// * `subscription_ids` - List of subscription identifiers to delete.
903 ///
904 /// # Returns
905 ///
906 /// * `Ok(Vec<StatusCode>)` - List of result for delete action on each id, `Good` or `BadSubscriptionIdInvalid`
907 /// The size and order of the list matches the size and order of the input.
908 /// * `Err(StatusCode)` - Status code reason for failure
909 ///
910 /// [`DeleteSubscriptionsRequest`]: ./struct.DeleteSubscriptionsRequest.html
911 ///
912 fn delete_subscriptions(&self, subscription_ids: &[u32])
913 -> Result<Vec<StatusCode>, StatusCode>;
914}