openthread/ot/
trel.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::*;
6
7/// DNS-SD Service Name for TREL
8pub const TREL_DNSSD_SERVICE_NAME: &str = "_trel._udp";
9
10/// DNS-SD Service Name for TREL, with a dot at the end.
11pub const TREL_DNSSD_SERVICE_NAME_WITH_DOT: &str = "_trel._udp.";
12
13/// Methods from the [OpenThread TREL Module][1].
14///
15/// [1]: https://openthread.io/reference/group/api-trel
16pub trait Trel {
17    /// Enables or disables TREL operation.
18    fn trel_set_enabled(&self, enabled: bool);
19
20    /// Returns true if TREL is enabled.
21    fn trel_is_enabled(&self) -> bool;
22
23    /// Return all the TREL counters
24    fn trel_get_counters(&self) -> Option<&TrelCounters>;
25
26    /// Reset TREL counters
27    fn trel_reset_counters(&self);
28
29    /// Return the count of TREL peer
30    fn trel_get_number_of_peers(&self) -> u16;
31}
32
33impl<T: Trel + Boxable> Trel for ot::Box<T> {
34    fn trel_set_enabled(&self, enabled: bool) {
35        self.as_ref().trel_set_enabled(enabled);
36    }
37
38    fn trel_is_enabled(&self) -> bool {
39        self.as_ref().trel_is_enabled()
40    }
41
42    fn trel_get_counters(&self) -> Option<&TrelCounters> {
43        self.as_ref().trel_get_counters()
44    }
45
46    fn trel_reset_counters(&self) {
47        self.as_ref().trel_reset_counters()
48    }
49
50    fn trel_get_number_of_peers(&self) -> u16 {
51        self.as_ref().trel_get_number_of_peers()
52    }
53}
54
55impl Trel for Instance {
56    fn trel_set_enabled(&self, enabled: bool) {
57        unsafe { otTrelSetEnabled(self.as_ot_ptr(), enabled) }
58    }
59
60    fn trel_is_enabled(&self) -> bool {
61        unsafe { otTrelIsEnabled(self.as_ot_ptr()) }
62    }
63
64    fn trel_get_counters(&self) -> Option<&TrelCounters> {
65        unsafe { TrelCounters::ref_from_ot_ptr(otTrelGetCounters(self.as_ot_ptr())) }
66    }
67
68    fn trel_reset_counters(&self) {
69        unsafe { otTrelResetCounters(self.as_ot_ptr()) }
70    }
71
72    fn trel_get_number_of_peers(&self) -> u16 {
73        unsafe { otTrelGetNumberOfPeers(self.as_ot_ptr()) }
74    }
75}
76
77/// Functional equivalent of [`otsys::otPlatTrelPeerInfo`](crate::otsys::otPlatTrelPeerInfo).
78#[derive(Clone)]
79#[repr(transparent)]
80pub struct PlatTrelPeerInfo<'a>(
81    otPlatTrelPeerInfo,
82    PhantomData<*mut otMessage>,
83    PhantomData<&'a ()>,
84);
85impl_ot_castable!(
86    lifetime
87    PlatTrelPeerInfo<'_>,
88    otPlatTrelPeerInfo,
89    PhantomData,
90    PhantomData
91);
92
93impl std::fmt::Debug for PlatTrelPeerInfo<'_> {
94    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95        f.debug_struct("PlatTrelPeerInfo")
96            .field("removed", &self.is_removed())
97            .field("txt", &self.txt_escaped())
98            .field("sockaddr", &self.sockaddr())
99            .finish()
100    }
101}
102
103impl<'a> PlatTrelPeerInfo<'a> {
104    /// Creates a new instance of `PlatTrelPeerInfo`.
105    pub fn new(removed: bool, txt: &[u8], sockaddr: ot::SockAddr) -> PlatTrelPeerInfo<'_> {
106        PlatTrelPeerInfo::from_ot(otPlatTrelPeerInfo {
107            mRemoved: removed,
108            mTxtData: txt.as_ptr(),
109            mTxtLength: txt.len().try_into().unwrap(),
110            mSockAddr: sockaddr.into_ot(),
111        })
112    }
113
114    /// Returns true if this peer is being removed.
115    pub fn is_removed(&self) -> bool {
116        self.0.mRemoved
117    }
118
119    /// Returns the raw value of the TXT field.
120    pub fn txt(&self) -> &'a [u8] {
121        unsafe { core::slice::from_raw_parts(self.0.mTxtData, self.0.mTxtLength.into()) }
122    }
123
124    /// Returns the TXT field as an escaped ASCII string.
125    pub fn txt_escaped(&self) -> String {
126        self.txt()
127            .iter()
128            .map(Clone::clone)
129            .flat_map(std::ascii::escape_default)
130            .map(char::from)
131            .collect::<String>()
132    }
133
134    /// Returns the SockAddr for this peer.
135    pub fn sockaddr(&self) -> SockAddr {
136        SockAddr::from_ot(self.0.mSockAddr)
137    }
138}
139
140/// Platform methods from the [OpenThread TREL Module][1].
141///
142/// [1]: https://openthread.io/reference/group/plat-trel
143pub trait PlatTrel {
144    /// This function is a callback from platform to notify of a received TREL UDP packet.
145    fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr);
146
147    /// This is a callback function from platform layer to report a discovered TREL peer info.
148    fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>);
149}
150
151impl<T: PlatTrel + Boxable> PlatTrel for ot::Box<T> {
152    fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr) {
153        self.as_ref().plat_trel_handle_received(packet, sock_addr);
154    }
155
156    fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>) {
157        self.as_ref().plat_trel_handle_discovered_peer_info(peer_info);
158    }
159}
160
161impl PlatTrel for Instance {
162    fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr) {
163        unsafe {
164            otPlatTrelHandleReceived(
165                self.as_ot_ptr(),
166                // TODO(https://fxbug.dev/42175496): Make sure they won't actually mutate.
167                packet.as_ptr() as *mut u8,
168                packet.len().try_into().unwrap(),
169                sock_addr.as_ot_ptr(),
170            )
171        }
172    }
173
174    fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>) {
175        unsafe { otPlatTrelHandleDiscoveredPeerInfo(self.as_ot_ptr(), peer_info.as_ot_ptr()) }
176    }
177}