1use crate::prelude_internal::*;
6
7use core::fmt::{Debug, Formatter};
8
9pub const TREL_DNSSD_SERVICE_NAME: &str = "_trel._udp";
11
12pub const TREL_DNSSD_SERVICE_NAME_WITH_DOT: &str = "_trel._udp.";
14
15#[allow(missing_debug_implementations)]
17pub struct TrelPeerIterator<'a, T: ?Sized> {
18 ot_instance: &'a T,
19 ot_iter: otTrelPeerIterator,
20}
21
22impl<T: ?Sized + Trel> Iterator for TrelPeerIterator<'_, T> {
23 type Item = TrelPeer;
24 fn next(&mut self) -> Option<Self::Item> {
25 self.ot_instance.iter_next_trel_peer(&mut self.ot_iter)
26 }
27}
28
29#[derive(Default, Clone)]
33#[repr(transparent)]
34pub struct TrelPeer(pub otTrelPeer);
35
36impl_ot_castable!(TrelPeer, otTrelPeer);
37
38impl Debug for TrelPeer {
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 f.debug_struct("TrelPeer")
41 .field("ext_address", &self.ext_address())
42 .field("ext_pan_id", &self.ext_pan_id())
43 .field("sock_addr", &self.sock_address())
44 .finish()
45 }
46}
47
48impl TrelPeer {
49 pub fn ext_address(&self) -> ExtAddress {
51 self.0.mExtAddress.into()
52 }
53
54 pub fn ext_pan_id(&self) -> ExtendedPanId {
56 self.0.mExtPanId.into()
57 }
58
59 pub fn sock_address(&self) -> SockAddr {
61 SockAddr::from_ot(self.0.mSockAddr)
62 }
63}
64
65pub trait Trel {
69 fn trel_set_enabled(&self, enabled: bool);
71
72 fn trel_is_enabled(&self) -> bool;
74
75 fn trel_get_counters(&self) -> Option<&TrelCounters>;
77
78 fn trel_reset_counters(&self);
80
81 fn trel_get_number_of_peers(&self) -> u16;
83
84 fn trel_init_peer_iterator(&self, iter: &mut otTrelPeerIterator);
87
88 fn trel_peer_get_iterator(&self) -> TrelPeerIterator<'_, Self> {
90 let mut ot_iter = otTrelPeerIterator::default();
91 self.trel_init_peer_iterator(&mut ot_iter);
92 TrelPeerIterator { ot_instance: self, ot_iter }
93 }
94
95 fn iter_next_trel_peer(&self, ot_iter: &mut otTrelPeerIterator) -> Option<TrelPeer>;
98}
99
100impl<T: Trel + Boxable> Trel for ot::Box<T> {
101 fn trel_set_enabled(&self, enabled: bool) {
102 self.as_ref().trel_set_enabled(enabled);
103 }
104
105 fn trel_is_enabled(&self) -> bool {
106 self.as_ref().trel_is_enabled()
107 }
108
109 fn trel_get_counters(&self) -> Option<&TrelCounters> {
110 self.as_ref().trel_get_counters()
111 }
112
113 fn trel_reset_counters(&self) {
114 self.as_ref().trel_reset_counters()
115 }
116
117 fn trel_get_number_of_peers(&self) -> u16 {
118 self.as_ref().trel_get_number_of_peers()
119 }
120
121 fn trel_init_peer_iterator(&self, iter: &mut otTrelPeerIterator) {
122 self.as_ref().trel_init_peer_iterator(iter)
123 }
124
125 fn iter_next_trel_peer(&self, ot_iter: &mut otTrelPeerIterator) -> Option<TrelPeer> {
126 self.as_ref().iter_next_trel_peer(ot_iter)
127 }
128}
129
130impl Trel for Instance {
131 fn trel_set_enabled(&self, enabled: bool) {
132 unsafe { otTrelSetEnabled(self.as_ot_ptr(), enabled) }
133 }
134
135 fn trel_is_enabled(&self) -> bool {
136 unsafe { otTrelIsEnabled(self.as_ot_ptr()) }
137 }
138
139 fn trel_get_counters(&self) -> Option<&TrelCounters> {
140 unsafe { TrelCounters::ref_from_ot_ptr(otTrelGetCounters(self.as_ot_ptr())) }
141 }
142
143 fn trel_reset_counters(&self) {
144 unsafe { otTrelResetCounters(self.as_ot_ptr()) }
145 }
146
147 fn trel_get_number_of_peers(&self) -> u16 {
148 unsafe { otTrelGetNumberOfPeers(self.as_ot_ptr()) }
149 }
150
151 fn trel_init_peer_iterator(&self, iter: &mut otTrelPeerIterator) {
152 unsafe { otTrelInitPeerIterator(self.as_ot_ptr(), iter) }
153 }
154
155 fn iter_next_trel_peer(&self, ot_iter: &mut otTrelPeerIterator) -> Option<TrelPeer> {
156 unsafe {
157 let peer_ptr = otTrelGetNextPeer(self.as_ot_ptr(), ot_iter as *mut otTrelPeerIterator);
158
159 peer_ptr.as_ref().map(|raw| TrelPeer(*raw))
160 }
161 }
162}
163
164#[derive(Clone)]
166#[repr(transparent)]
167pub struct PlatTrelPeerInfo<'a>(
168 otPlatTrelPeerInfo,
169 PhantomData<*mut otMessage>,
170 PhantomData<&'a ()>,
171);
172impl_ot_castable!(
173 lifetime
174 PlatTrelPeerInfo<'_>,
175 otPlatTrelPeerInfo,
176 PhantomData,
177 PhantomData
178);
179
180impl std::fmt::Debug for PlatTrelPeerInfo<'_> {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 f.debug_struct("PlatTrelPeerInfo")
183 .field("removed", &self.is_removed())
184 .field("txt", &self.txt_escaped())
185 .field("sockaddr", &self.sockaddr())
186 .finish()
187 }
188}
189
190impl<'a> PlatTrelPeerInfo<'a> {
191 pub fn new(removed: bool, txt: &[u8], sockaddr: ot::SockAddr) -> PlatTrelPeerInfo<'_> {
193 PlatTrelPeerInfo::from_ot(otPlatTrelPeerInfo {
194 mRemoved: removed,
195 mTxtData: txt.as_ptr(),
196 mTxtLength: txt.len().try_into().unwrap(),
197 mSockAddr: sockaddr.into_ot(),
198 })
199 }
200
201 pub fn is_removed(&self) -> bool {
203 self.0.mRemoved
204 }
205
206 pub fn txt(&self) -> &'a [u8] {
208 unsafe { core::slice::from_raw_parts(self.0.mTxtData, self.0.mTxtLength.into()) }
209 }
210
211 pub fn txt_escaped(&self) -> String {
213 self.txt()
214 .iter()
215 .map(Clone::clone)
216 .flat_map(std::ascii::escape_default)
217 .map(char::from)
218 .collect::<String>()
219 }
220
221 pub fn sockaddr(&self) -> SockAddr {
223 SockAddr::from_ot(self.0.mSockAddr)
224 }
225}
226
227pub trait PlatTrel {
231 fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr);
233
234 fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>);
236}
237
238impl<T: PlatTrel + Boxable> PlatTrel for ot::Box<T> {
239 fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr) {
240 self.as_ref().plat_trel_handle_received(packet, sock_addr);
241 }
242
243 fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>) {
244 self.as_ref().plat_trel_handle_discovered_peer_info(peer_info);
245 }
246}
247
248impl PlatTrel for Instance {
249 fn plat_trel_handle_received(&self, packet: &[u8], sock_addr: &ot::SockAddr) {
250 unsafe {
251 otPlatTrelHandleReceived(
252 self.as_ot_ptr(),
253 packet.as_ptr() as *mut u8,
255 packet.len().try_into().unwrap(),
256 sock_addr.as_ot_ptr(),
257 )
258 }
259 }
260
261 fn plat_trel_handle_discovered_peer_info(&self, peer_info: &PlatTrelPeerInfo<'_>) {
262 unsafe { otPlatTrelHandleDiscoveredPeerInfo(self.as_ot_ptr(), peer_info.as_ot_ptr()) }
263 }
264}