Skip to main content

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