1use crate::prelude_internal::*;
6
7#[allow(missing_debug_implementations)]
9pub struct NeighborInfoIterator<'a, T: ?Sized> {
10 ot_instance: &'a T,
11 ot_iter: otNeighborInfoIterator,
12}
13
14impl<T: ?Sized + Thread> Iterator for NeighborInfoIterator<'_, T> {
15 type Item = NeighborInfo;
16 fn next(&mut self) -> Option<Self::Item> {
17 self.ot_instance.iter_next_neighbor_info(&mut self.ot_iter)
18 }
19}
20
21pub trait Thread {
25 fn become_leader(&self) -> Result;
28
29 fn become_router(&self) -> Result;
32
33 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo>;
36
37 fn get_leader_data(&self) -> Result<LeaderData>;
40
41 fn get_leader_weight(&self) -> u8;
44
45 #[must_use]
48 fn get_network_key(&self) -> NetworkKey;
49
50 fn set_network_key(&self, key: &NetworkKey) -> Result;
53
54 #[must_use]
57 fn get_network_name(&self) -> NetworkName {
58 NetworkName::try_from_slice(self.get_network_name_as_slice()).unwrap()
59 }
60
61 #[must_use]
64 fn get_network_name_as_slice(&self) -> &[u8];
65
66 fn set_network_name(&self, name: &NetworkName) -> Result;
69
70 #[must_use]
73 fn is_singleton(&self) -> bool;
74
75 #[must_use]
78 fn get_extended_pan_id(&self) -> &ExtendedPanId;
79
80 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result;
83
84 fn thread_set_enabled(&self, enabled: bool) -> Result;
86
87 #[must_use]
90 fn get_device_role(&self) -> DeviceRole;
91
92 fn get_partition_id(&self) -> u32;
95
96 fn get_rloc16(&self) -> u16;
98
99 fn get_link_mode(&self) -> ot::LinkModeConfig;
101
102 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result;
104
105 fn get_rloc(&self) -> std::net::Ipv6Addr;
107
108 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr;
111
112 fn get_link_local_addr(&self) -> std::net::Ipv6Addr;
115
116 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr;
119
120 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix;
123
124 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo>;
127
128 fn get_max_router_id(&self) -> u8;
131
132 fn get_ip6_counters(&self) -> &IpCounters;
135
136 fn iter_next_neighbor_info(&self, ot_iter: &mut otNeighborInfoIterator)
144 -> Option<NeighborInfo>;
145
146 fn iter_neighbor_info(&self) -> NeighborInfoIterator<'_, Self> {
148 NeighborInfoIterator {
149 ot_instance: self,
150 ot_iter: OT_NEIGHBOR_INFO_ITERATOR_INIT.try_into().unwrap(),
151 }
152 }
153}
154
155impl<T: Thread + Boxable> Thread for ot::Box<T> {
156 fn become_leader(&self) -> Result<()> {
157 self.as_ref().become_leader()
158 }
159 fn become_router(&self) -> Result<()> {
160 self.as_ref().become_router()
161 }
162 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
163 self.as_ref().get_child_info_by_id(child_id)
164 }
165 fn get_leader_data(&self) -> Result<LeaderData> {
166 self.as_ref().get_leader_data()
167 }
168
169 fn get_leader_weight(&self) -> u8 {
170 self.as_ref().get_leader_weight()
171 }
172
173 fn get_network_key(&self) -> NetworkKey {
174 self.as_ref().get_network_key()
175 }
176
177 fn set_network_key(&self, key: &NetworkKey) -> Result {
178 self.as_ref().set_network_key(key)
179 }
180 fn get_network_name_as_slice(&self) -> &[u8] {
181 self.as_ref().get_network_name_as_slice()
182 }
183
184 fn set_network_name(&self, name: &NetworkName) -> Result {
185 self.as_ref().set_network_name(name)
186 }
187
188 fn is_singleton(&self) -> bool {
189 self.as_ref().is_singleton()
190 }
191
192 fn get_extended_pan_id(&self) -> &ExtendedPanId {
193 self.as_ref().get_extended_pan_id()
194 }
195
196 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
197 self.as_ref().set_extended_pan_id(xpanid)
198 }
199
200 fn thread_set_enabled(&self, enabled: bool) -> Result {
201 self.as_ref().thread_set_enabled(enabled)
202 }
203
204 fn get_device_role(&self) -> DeviceRole {
205 self.as_ref().get_device_role()
206 }
207
208 fn get_partition_id(&self) -> u32 {
209 self.as_ref().get_partition_id()
210 }
211
212 fn get_rloc16(&self) -> u16 {
213 self.as_ref().get_rloc16()
214 }
215
216 fn get_link_mode(&self) -> ot::LinkModeConfig {
217 self.as_ref().get_link_mode()
218 }
219
220 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
221 self.as_ref().set_link_mode(link_mode_config)
222 }
223
224 fn get_rloc(&self) -> std::net::Ipv6Addr {
225 self.as_ref().get_rloc()
226 }
227
228 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
229 self.as_ref().get_mesh_local_eid()
230 }
231
232 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
233 self.as_ref().get_link_local_addr()
234 }
235
236 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
237 self.as_ref().get_link_local_all_nodes_multicast_addr()
238 }
239
240 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
241 self.as_ref().get_mesh_local_prefix()
242 }
243
244 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
245 self.as_ref().get_router_info(router_id)
246 }
247
248 fn get_max_router_id(&self) -> u8 {
249 self.as_ref().get_max_router_id()
250 }
251
252 fn get_ip6_counters(&self) -> &IpCounters {
253 self.as_ref().get_ip6_counters()
254 }
255
256 fn iter_next_neighbor_info(
257 &self,
258 ot_iter: &mut otNeighborInfoIterator,
259 ) -> Option<NeighborInfo> {
260 self.as_ref().iter_next_neighbor_info(ot_iter)
261 }
262}
263
264impl Thread for Instance {
265 fn become_leader(&self) -> Result<()> {
266 Error::from(unsafe { otThreadBecomeLeader(self.as_ot_ptr()) }).into()
267 }
268
269 fn become_router(&self) -> Result<()> {
270 Error::from(unsafe { otThreadBecomeRouter(self.as_ot_ptr()) }).into()
271 }
272
273 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
274 let mut ret: otChildInfo = Default::default();
275 Error::from(unsafe { otThreadGetChildInfoById(self.as_ot_ptr(), child_id, &mut ret) })
276 .into_result()?;
277 Ok(ret)
278 }
279
280 fn get_leader_data(&self) -> Result<LeaderData> {
281 let mut ret = LeaderData::default();
282 Error::from(unsafe { otThreadGetLeaderData(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
283 .into_result()?;
284 Ok(ret)
285 }
286
287 fn get_leader_weight(&self) -> u8 {
288 unsafe { otThreadGetLeaderWeight(self.as_ot_ptr()) }
289 }
290
291 fn get_network_key(&self) -> NetworkKey {
292 let mut ret = NetworkKey::default();
293 unsafe { otThreadGetNetworkKey(self.as_ot_ptr(), ret.as_ot_mut_ptr()) }
294 ret
295 }
296
297 fn set_network_key(&self, key: &NetworkKey) -> Result {
298 Error::from(unsafe { otThreadSetNetworkKey(self.as_ot_ptr(), key.as_ot_ptr()) })
299 .into_result()
300 }
301
302 #[allow(clippy::unnecessary_cast)]
303 fn get_network_name_as_slice(&self) -> &[u8] {
304 unsafe {
305 let slice = std::slice::from_raw_parts(
306 otThreadGetNetworkName(self.as_ot_ptr()) as *const u8,
307 OT_NETWORK_NAME_MAX_SIZE as usize,
308 );
309 let first_zero_index =
310 slice.iter().position(|&x| x == 0).unwrap_or(OT_NETWORK_NAME_MAX_SIZE as usize);
311 &slice[0..first_zero_index]
312 }
313 }
314
315 fn set_network_name(&self, name: &NetworkName) -> Result {
316 Error::from(unsafe { otThreadSetNetworkName(self.as_ot_ptr(), name.as_c_str()) })
317 .into_result()
318 }
319
320 fn is_singleton(&self) -> bool {
321 unsafe { otThreadIsSingleton(self.as_ot_ptr()) }
322 }
323
324 fn get_extended_pan_id(&self) -> &ExtendedPanId {
325 unsafe {
326 let xpanid = otThreadGetExtendedPanId(self.as_ot_ptr());
327 ExtendedPanId::ref_from_ot_ptr(xpanid)
328 }
329 .unwrap()
330 }
331
332 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
333 Error::from(unsafe { otThreadSetExtendedPanId(self.as_ot_ptr(), xpanid.as_ot_ptr()) })
334 .into_result()
335 }
336
337 fn thread_set_enabled(&self, enabled: bool) -> Result {
338 Error::from(unsafe { otThreadSetEnabled(self.as_ot_ptr(), enabled) }).into_result()
339 }
340
341 fn get_device_role(&self) -> ot::DeviceRole {
342 unsafe { otThreadGetDeviceRole(self.as_ot_ptr()) }.into()
343 }
344
345 fn get_partition_id(&self) -> u32 {
346 unsafe { otThreadGetPartitionId(self.as_ot_ptr()) }
347 }
348
349 fn get_rloc16(&self) -> u16 {
350 unsafe { otThreadGetRloc16(self.as_ot_ptr()) }
351 }
352
353 fn get_link_mode(&self) -> ot::LinkModeConfig {
354 unsafe { otThreadGetLinkMode(self.as_ot_ptr()) }.into()
355 }
356
357 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
358 Error::from(unsafe { otThreadSetLinkMode(self.as_ot_ptr(), link_mode_config.into()) })
359 .into_result()
360 }
361
362 fn get_rloc(&self) -> std::net::Ipv6Addr {
363 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetRloc(self.as_ot_ptr()) })
364 }
365
366 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
367 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetMeshLocalEid(self.as_ot_ptr()) })
368 }
369
370 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
371 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetLinkLocalIp6Address(self.as_ot_ptr()) })
372 }
373
374 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
375 std::net::Ipv6Addr::from_ot(unsafe {
376 *otThreadGetLinkLocalAllThreadNodesMulticastAddress(self.as_ot_ptr())
377 })
378 }
379
380 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
381 unsafe { MeshLocalPrefix::ref_from_ot_ptr(otThreadGetMeshLocalPrefix(self.as_ot_ptr())) }
382 .unwrap()
383 }
384
385 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
386 let mut ret = RouterInfo::default();
387 Error::from(unsafe {
388 otThreadGetRouterInfo(self.as_ot_ptr(), router_id, ret.as_ot_mut_ptr())
389 })
390 .into_result()?;
391 Ok(ret)
392 }
393
394 fn get_max_router_id(&self) -> u8 {
395 unsafe { otThreadGetMaxRouterId(self.as_ot_ptr()) }
396 }
397
398 fn get_ip6_counters(&self) -> &IpCounters {
399 unsafe { IpCounters::ref_from_ot_ptr(otThreadGetIp6Counters(self.as_ot_ptr())) }.unwrap()
400 }
401
402 fn iter_next_neighbor_info(
403 &self,
404 ot_iter: &mut otNeighborInfoIterator,
405 ) -> Option<NeighborInfo> {
406 unsafe {
407 let mut ret = NeighborInfo::default();
408 match Error::from(otThreadGetNextNeighborInfo(
409 self.as_ot_ptr(),
410 ot_iter as *mut otNeighborInfoIterator,
411 ret.as_ot_mut_ptr(),
412 )) {
413 Error::NotFound => None,
414 Error::None => Some(ret),
415 err => unreachable!("Unexpected error from otThreadGetNextNeighborInfo: {:?}", err),
416 }
417 }
418 }
419}