Skip to main content

opcua/core/
mod.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5//! The OPC UA Core module holds functionality that is common to server and clients that make use of OPC UA.
6//! It contains message chunking, cryptography / pki, communications and standard handshake messages.
7
8#[macro_export]
9macro_rules! supported_message_as {
10    ($v: expr, $i: ident) => {
11        if let SupportedMessage::$i(value) = $v {
12            *value
13        } else {
14            panic!("Cannot convert to {:?}", stringify!($i));
15        }
16    };
17}
18
19lazy_static! {
20    pub static ref RUNTIME: crate::core::runtime::Runtime =
21        crate::core::runtime::Runtime::default();
22}
23
24/// Returns a vector of all currently existing runtime components as a vector of strings.
25#[macro_export]
26macro_rules! runtime_components {
27    () => {{
28        use $crate::core::RUNTIME;
29        RUNTIME.components()
30    }};
31}
32
33/// This macro is for debugging purposes - code register a running component (e.g. tokio task) when it starts
34/// and calls the corresponding deregister macro when it finishes. This enables the code to print
35/// out a list of components in existence at any time to ensure they were properly cleaned up.
36#[macro_export]
37macro_rules! register_runtime_component {
38    ( $component_name:expr ) => {
39        RUNTIME.register_component($component_name);
40    };
41}
42
43/// See `register_runtime_component`
44#[macro_export]
45macro_rules! deregister_runtime_component {
46    ( $component_name:expr ) => {
47        RUNTIME.deregister_component($component_name);
48    };
49}
50
51/// Contains debugging utility helper functions
52pub mod debug {
53    /// Prints out the content of a slice in hex and visible char format to aid debugging. Format
54    /// is similar to corresponding functionality in node-opcua
55    pub fn log_buffer(message: &str, buf: &[u8]) {
56        // No point doing anything unless debug level is on
57        if !log_enabled!(target: "hex", log::Level::Trace) {
58            return;
59        }
60
61        let line_len = 32;
62        let len = buf.len();
63        let last_line_padding = ((len / line_len) + 1) * line_len - len;
64
65        trace!(target: "hex", "{}", message);
66
67        let mut char_line = String::new();
68        let mut hex_line = format!("{:08x}: ", 0);
69
70        for (i, b) in buf.iter().enumerate() {
71            let value = *b as u8;
72            if i > 0 && i % line_len == 0 {
73                trace!(target: "hex", "{} {}", hex_line, char_line);
74                hex_line = format!("{:08}: ", i);
75                char_line.clear();
76            }
77            hex_line = format!("{} {:02x}", hex_line, value);
78            char_line.push(if value >= 32 && value <= 126 {
79                value as char
80            } else {
81                '.'
82            });
83        }
84        if last_line_padding > 0 {
85            for _ in 0..last_line_padding {
86                hex_line.push_str("   ");
87            }
88            trace!(target: "hex", "{} {}", hex_line, char_line);
89        }
90    }
91}
92
93#[cfg(test)]
94pub mod tests;
95
96pub mod constants {
97    /// Default OPC UA port number. Used by a discovery server. Other servers would normally run
98    /// on a different port. So OPC UA for Rust does not use this nr by default but it is used
99    /// implicitly in opc.tcp:// urls and elsewhere.
100    pub const DEFAULT_OPC_UA_SERVER_PORT: u16 = 4840;
101}
102
103pub mod comms;
104pub mod config;
105pub mod handle;
106pub mod runtime;
107#[rustfmt::skip]
108pub mod supported_message;
109
110/// Contains most of the things that are typically required from a client / server.
111pub mod prelude {
112    pub use super::{comms::prelude::*, config::Config, supported_message::*};
113    pub use crate::types::{status_code::StatusCode, *};
114}