opcua_server/callbacks.rs
1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5//! Callbacks that a server implementation may register with the library
6
7use std::sync::{Arc, RwLock};
8
9use opcua_types::{
10 service_types::{CallMethodRequest, CallMethodResult, TimestampsToReturn},
11 status_code::StatusCode,
12 AttributeId, DataValue, NodeId, NumericRange, QualifiedName,
13};
14
15use crate::session::{Session, SessionManager};
16
17/// An attribute getter trait is used to obtain the data value associated with the particular attribute id
18/// This allows server implementations to supply a value on demand, usually in response to a polling action
19/// such as a monitored item in a subscription.
20///
21/// `node_id` is the node to which the node belongs
22/// `attribute_id` is the attribute of the node to fetch a value for
23///
24/// Use `max_age` according to the OPC UA Part 4, Table 52 specification to determine how to return
25/// a value:
26///
27/// * 0 = a new value
28/// * time in ms for a value less than the specified age
29/// * i32::max() or higher to fetch a cached value.
30///
31pub trait AttributeGetter {
32 /// Returns a data value of the specified attribute or none.
33 fn get(
34 &mut self,
35 node_id: &NodeId,
36 timestamps_to_return: TimestampsToReturn,
37 attribute_id: AttributeId,
38 index_range: NumericRange,
39 data_encoding: &QualifiedName,
40 max_age: f64,
41 ) -> Result<Option<DataValue>, StatusCode>;
42}
43
44// An attribute setter. Sets the value on the specified attribute
45pub trait AttributeSetter {
46 /// Sets the attribute on the specified node
47 fn set(
48 &mut self,
49 node_id: &NodeId,
50 attribute_id: AttributeId,
51 index_range: NumericRange,
52 data_value: DataValue,
53 ) -> Result<(), StatusCode>;
54}
55
56/// Called by RegisterNodes service
57pub trait RegisterNodes {
58 /// Called when a client calls the RegisterNodes service. This implementation should return a list
59 /// of the same size and order containing node ids corresponding to the input, or aliases. The implementation
60 /// should return `BadNodeIdInvalid` if any of the node ids in the input are invalid.
61 ///
62 /// The call is also given the session that the request was made on. The implementation should
63 /// NOT hold a strong reference to this session, but it can make a weak reference if it desires.
64 ///
65 /// There is no guarantee that the corresponding `OnUnregisterNodes` will be called by the client,
66 /// therefore use the weak session references and a periodic check to perform any housekeeping.
67 fn register_nodes(
68 &mut self,
69 session: Arc<RwLock<Session>>,
70 nodes_to_register: &[NodeId],
71 ) -> Result<Vec<NodeId>, StatusCode>;
72}
73
74/// Called by UnregisterNodes service
75pub trait UnregisterNodes {
76 /// Called when a client calls the UnregisterNodes service. See `OnRegisterNodes` trait for more
77 /// information. A client may not call this function, e.g. if connection breaks so do not
78 /// count on receiving this to perform any housekeeping.
79 ///
80 /// The function should not validate the nodes in the request and should just ignore any
81 /// unregistered nodes.
82 fn unregister_nodes(
83 &mut self,
84 session: Arc<RwLock<Session>>,
85 nodes_to_unregister: &[NodeId],
86 ) -> Result<(), StatusCode>;
87}
88
89/// Called by the Method service when it invokes a method
90pub trait Method {
91 /// A method is registered via the address space to a method id and optionally an object id.
92 /// When a client sends a CallRequest / CallMethod request, the registered object will
93 /// be invoked to handle the call.
94 fn call(
95 &mut self,
96 session_id: &NodeId,
97 session_manager: Arc<RwLock<SessionManager>>,
98 request: &CallMethodRequest,
99 ) -> Result<CallMethodResult, StatusCode>;
100}