openthread/ot/
border_agent.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::prelude_internal::*;
6use num::FromPrimitive;
7
8/// Represents the thread joiner state.
9///
10/// Functional equivalent of [`otsys::otJoinerState`](crate::otsys::otJoinerState).
11#[derive(
12    Debug,
13    Copy,
14    Clone,
15    Eq,
16    Ord,
17    PartialOrd,
18    PartialEq,
19    num_derive::FromPrimitive,
20    num_derive::ToPrimitive,
21)]
22pub enum BorderAgentEphemeralKeyState {
23    /// Functional equivalent of [`otsys::OT_BORDER_AGENT_STATE_DISABLED`](crate::otsys::OT_BORDER_AGENT_STATE_DISABLED).
24    Disabled = OT_BORDER_AGENT_STATE_DISABLED as isize,
25
26    /// Functional equivalent of [`otsys::OT_BORDER_AGENT_STATE_STOPPED`](crate::otsys::OT_BORDER_AGENT_STATE_STOPPED).
27    Stopped = OT_BORDER_AGENT_STATE_STOPPED as isize,
28
29    /// Functional equivalent of [`otsys::OT_BORDER_AGENT_STATE_STARTED`](crate::otsys::OT_BORDER_AGENT_STATE_STARTED).
30    Started = OT_BORDER_AGENT_STATE_STARTED as isize,
31
32    /// Functional equivalent of [`otsys::OT_BORDER_AGENT_STATE_CONNECTED`](crate::otsys::OT_BORDER_AGENT_STATE_CONNECTED).
33    Connected = OT_BORDER_AGENT_STATE_CONNECTED as isize,
34
35    /// Functional equivalent of [`otsys::OT_BORDER_AGENT_STATE_ACCEPTED`](crate::otsys::OT_BORDER_AGENT_STATE_ACCEPTED).
36    Accepted = OT_BORDER_AGENT_STATE_ACCEPTED as isize,
37}
38
39impl From<otBorderAgentEphemeralKeyState> for BorderAgentEphemeralKeyState {
40    fn from(x: otBorderAgentEphemeralKeyState) -> Self {
41        Self::from_u32(x)
42            .unwrap_or_else(|| panic!("Unknown otBorderAgentEphemeralKeyState value: {x}"))
43    }
44}
45
46impl From<BorderAgentEphemeralKeyState> for otBorderAgentEphemeralKeyState {
47    fn from(x: BorderAgentEphemeralKeyState) -> Self {
48        x as otBorderAgentEphemeralKeyState
49    }
50}
51
52/// Methods from the [OpenThread "Border Agent" Module][1].
53///
54/// [1]: https://openthread.io/reference/group/api-border-agent
55pub trait BorderAgent {
56    /// Functional equivalent of
57    /// [`otsys::otBorderAgentIsActive`](crate::otsys::otBorderAgentIsActive).
58    fn border_agent_is_active(&self) -> bool;
59
60    /// Functional equivalent of
61    /// [`otsys::otBorderAgentUdpPort`](crate::otsys::otBorderAgentGetUdpPort).
62    fn border_agent_get_udp_port(&self) -> u16;
63
64    /// Functional equivalent of
65    /// [`otsys::otBorderAgentEphemeralKeyGetState`](crate::otsys::otBorderAgentEphemeralKeyGetState).
66    fn border_agent_ephemeral_key_get_state(&self) -> BorderAgentEphemeralKeyState;
67
68    /// Functional equivalent of
69    /// [`otsys::otBorderAgentEphemeralKeySetEnabled`](crate::otsys::otBorderAgentEphemeralKeySetEnabled).
70    fn border_agent_ephemeral_key_set_enabled(&self, enabled: bool);
71
72    /// Functional equivalent of
73    /// [`otsys::otBorderAgentEphemeralKeyStart`](crate::otsys::otBorderAgentEphemeralKeyStart).
74    fn border_agent_ephemeral_key_start(
75        &self,
76        key_string: &CStr,
77        timeout: u32,
78        port: u16,
79    ) -> Result;
80
81    /// Functional equivalent of
82    /// [`otsys::otBorderAgentEphemeralKeyStop`](crate::otsys::otBorderAgentEphemeralKeyStop).
83    fn border_agent_ephemeral_key_stop(&self);
84
85    /// Functional equivalent of
86    /// [`otsys::otBorderAgentEphemeralKeyGetUdpPort`](crate::otsys::otBorderAgentEphemeralKeyGetUdpPort).
87    fn border_agent_ephemeral_key_get_udp_port(&self) -> u16;
88
89    /// Functional equivalent of
90    /// [`otsys::otBorderAgentEphemeralKeySetCallback`](crate::otsys::otBorderAgentEphemeralKeySetCallback).
91    fn border_agent_set_ephemeral_key_callback<'a, F>(&'a self, f: Option<F>)
92    where
93        F: FnMut() + 'a;
94}
95
96impl<T: BorderAgent + Boxable> BorderAgent for ot::Box<T> {
97    fn border_agent_is_active(&self) -> bool {
98        self.as_ref().border_agent_is_active()
99    }
100
101    fn border_agent_get_udp_port(&self) -> u16 {
102        self.as_ref().border_agent_get_udp_port()
103    }
104
105    fn border_agent_ephemeral_key_get_state(&self) -> BorderAgentEphemeralKeyState {
106        self.as_ref().border_agent_ephemeral_key_get_state()
107    }
108
109    fn border_agent_ephemeral_key_set_enabled(&self, enabled: bool) {
110        self.as_ref().border_agent_ephemeral_key_set_enabled(enabled)
111    }
112
113    fn border_agent_ephemeral_key_start(&self, key: &CStr, timeout: u32, port: u16) -> Result {
114        self.as_ref().border_agent_ephemeral_key_start(key, timeout, port)
115    }
116
117    fn border_agent_ephemeral_key_stop(&self) {
118        self.as_ref().border_agent_ephemeral_key_stop()
119    }
120
121    fn border_agent_ephemeral_key_get_udp_port(&self) -> u16 {
122        self.as_ref().border_agent_ephemeral_key_get_udp_port()
123    }
124
125    fn border_agent_set_ephemeral_key_callback<'a, F>(&'a self, f: Option<F>)
126    where
127        F: FnMut() + 'a,
128    {
129        self.as_ref().border_agent_set_ephemeral_key_callback(f)
130    }
131}
132
133impl BorderAgent for Instance {
134    fn border_agent_is_active(&self) -> bool {
135        unsafe { otBorderAgentIsActive(self.as_ot_ptr()) }
136    }
137
138    fn border_agent_get_udp_port(&self) -> u16 {
139        unsafe { otBorderAgentGetUdpPort(self.as_ot_ptr()) }
140    }
141
142    fn border_agent_ephemeral_key_get_state(&self) -> BorderAgentEphemeralKeyState {
143        unsafe { otBorderAgentEphemeralKeyGetState(self.as_ot_ptr()).into() }
144    }
145
146    fn border_agent_ephemeral_key_set_enabled(&self, enabled: bool) {
147        unsafe { otBorderAgentEphemeralKeySetEnabled(self.as_ot_ptr(), enabled) }
148    }
149
150    fn border_agent_ephemeral_key_start(&self, key: &CStr, timeout: u32, port: u16) -> Result {
151        unsafe {
152            Error::from(otBorderAgentEphemeralKeyStart(
153                self.as_ot_ptr(),
154                key.as_ptr(),
155                timeout,
156                port,
157            ))
158            .into()
159        }
160    }
161
162    fn border_agent_ephemeral_key_stop(&self) {
163        unsafe { otBorderAgentEphemeralKeyStop(self.as_ot_ptr()) }
164    }
165
166    fn border_agent_ephemeral_key_get_udp_port(&self) -> u16 {
167        unsafe { otBorderAgentEphemeralKeyGetUdpPort(self.as_ot_ptr()) }
168    }
169
170    fn border_agent_set_ephemeral_key_callback<'a, F>(&'a self, f: Option<F>)
171    where
172        F: FnMut() + 'a,
173    {
174        unsafe extern "C" fn _border_agent_set_ephemeral_key_callback<'a, F: FnMut() + 'a>(
175            context: *mut ::std::os::raw::c_void,
176        ) {
177            trace!("_border_agent_set_ephemeral_key_callback");
178
179            // Reconstitute a reference to our closure.
180            let sender = &mut *(context as *mut F);
181
182            sender()
183        }
184
185        let (fn_ptr, fn_box, cb): (_, _, otBorderAgentEphemeralKeyCallback) = if let Some(f) = f {
186            let mut x = Box::new(f);
187
188            (
189                x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
190                Some(x as Box<dyn FnMut() + 'a>),
191                Some(_border_agent_set_ephemeral_key_callback::<F>),
192            )
193        } else {
194            (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
195        };
196
197        unsafe {
198            otBorderAgentEphemeralKeySetCallback(self.as_ot_ptr(), cb, fn_ptr);
199
200            // Make sure our object eventually gets cleaned up.
201            // Here we must also transmute our closure to have a 'static lifetime.
202            // We need to do this because the borrow checker cannot infer the
203            // proper lifetime for the singleton instance backing, but
204            // this is guaranteed by the API.
205            self.borrow_backing().ephemeral_key_callback.set(std::mem::transmute::<
206                Option<Box<dyn FnMut() + 'a>>,
207                Option<Box<dyn FnMut() + 'static>>,
208            >(fn_box));
209        }
210    }
211}