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
21#[allow(missing_debug_implementations)]
23pub struct CacheEntryIterator<'a, T: ?Sized> {
24 ot_instance: &'a T,
25 ot_iter: otCacheEntryIterator,
26}
27
28impl<T: ?Sized + Thread> Iterator for CacheEntryIterator<'_, T> {
29 type Item = CacheEntryInfo;
30 fn next(&mut self) -> Option<Self::Item> {
31 self.ot_instance.iter_next_cache_entry_info(&mut self.ot_iter)
32 }
33}
34
35pub trait Thread {
39 fn become_leader(&self) -> Result;
42
43 fn become_router(&self) -> Result;
46
47 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo>;
50
51 fn get_leader_data(&self) -> Result<LeaderData>;
54
55 fn get_leader_weight(&self) -> u8;
58
59 #[must_use]
62 fn get_network_key(&self) -> NetworkKey;
63
64 fn set_network_key(&self, key: &NetworkKey) -> Result;
67
68 #[must_use]
71 fn get_network_name(&self) -> NetworkName {
72 NetworkName::try_from_slice(self.get_network_name_as_slice()).unwrap()
73 }
74
75 #[must_use]
78 fn get_network_name_as_slice(&self) -> &[u8];
79
80 fn set_network_name(&self, name: &NetworkName) -> Result;
83
84 #[must_use]
87 fn is_singleton(&self) -> bool;
88
89 #[must_use]
92 fn get_extended_pan_id(&self) -> &ExtendedPanId;
93
94 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result;
97
98 fn thread_set_enabled(&self, enabled: bool) -> Result;
100
101 #[must_use]
104 fn get_device_role(&self) -> DeviceRole;
105
106 fn get_partition_id(&self) -> u32;
109
110 fn get_rloc16(&self) -> u16;
112
113 fn get_link_mode(&self) -> ot::LinkModeConfig;
115
116 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result;
118
119 fn get_rloc(&self) -> std::net::Ipv6Addr;
121
122 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr;
125
126 fn get_link_local_addr(&self) -> std::net::Ipv6Addr;
129
130 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr;
133
134 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix;
137
138 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo>;
141
142 fn get_max_router_id(&self) -> u8;
145
146 fn get_ip6_counters(&self) -> &IpCounters;
149
150 fn iter_next_neighbor_info(&self, ot_iter: &mut otNeighborInfoIterator)
158 -> Option<NeighborInfo>;
159
160 fn iter_neighbor_info(&self) -> NeighborInfoIterator<'_, Self> {
162 NeighborInfoIterator {
163 ot_instance: self,
164 ot_iter: OT_NEIGHBOR_INFO_ITERATOR_INIT.try_into().unwrap(),
165 }
166 }
167
168 fn set_vendor_name(&self, name: &str) -> Result;
171
172 fn set_vendor_model(&self, model: &str) -> Result;
175
176 fn set_vendor_sw_version(&self, version: &str) -> Result;
179
180 fn get_mle_counters(&self) -> &MleCounters;
183
184 fn iter_next_cache_entry_info(
186 &self,
187 ot_iter: &mut otCacheEntryIterator,
188 ) -> Option<CacheEntryInfo>;
189
190 fn iter_cache_entry_info(&self) -> CacheEntryIterator<'_, Self> {
192 CacheEntryIterator { ot_instance: self, ot_iter: otCacheEntryIterator::default() }
193 }
194}
195
196impl<T: Thread + Boxable> Thread for ot::Box<T> {
197 fn become_leader(&self) -> Result<()> {
198 self.as_ref().become_leader()
199 }
200 fn become_router(&self) -> Result<()> {
201 self.as_ref().become_router()
202 }
203 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
204 self.as_ref().get_child_info_by_id(child_id)
205 }
206 fn get_leader_data(&self) -> Result<LeaderData> {
207 self.as_ref().get_leader_data()
208 }
209
210 fn get_leader_weight(&self) -> u8 {
211 self.as_ref().get_leader_weight()
212 }
213
214 fn get_network_key(&self) -> NetworkKey {
215 self.as_ref().get_network_key()
216 }
217
218 fn set_network_key(&self, key: &NetworkKey) -> Result {
219 self.as_ref().set_network_key(key)
220 }
221 fn get_network_name_as_slice(&self) -> &[u8] {
222 self.as_ref().get_network_name_as_slice()
223 }
224
225 fn set_network_name(&self, name: &NetworkName) -> Result {
226 self.as_ref().set_network_name(name)
227 }
228
229 fn is_singleton(&self) -> bool {
230 self.as_ref().is_singleton()
231 }
232
233 fn get_extended_pan_id(&self) -> &ExtendedPanId {
234 self.as_ref().get_extended_pan_id()
235 }
236
237 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
238 self.as_ref().set_extended_pan_id(xpanid)
239 }
240
241 fn thread_set_enabled(&self, enabled: bool) -> Result {
242 self.as_ref().thread_set_enabled(enabled)
243 }
244
245 fn get_device_role(&self) -> DeviceRole {
246 self.as_ref().get_device_role()
247 }
248
249 fn get_partition_id(&self) -> u32 {
250 self.as_ref().get_partition_id()
251 }
252
253 fn get_rloc16(&self) -> u16 {
254 self.as_ref().get_rloc16()
255 }
256
257 fn get_link_mode(&self) -> ot::LinkModeConfig {
258 self.as_ref().get_link_mode()
259 }
260
261 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
262 self.as_ref().set_link_mode(link_mode_config)
263 }
264
265 fn get_rloc(&self) -> std::net::Ipv6Addr {
266 self.as_ref().get_rloc()
267 }
268
269 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
270 self.as_ref().get_mesh_local_eid()
271 }
272
273 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
274 self.as_ref().get_link_local_addr()
275 }
276
277 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
278 self.as_ref().get_link_local_all_nodes_multicast_addr()
279 }
280
281 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
282 self.as_ref().get_mesh_local_prefix()
283 }
284
285 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
286 self.as_ref().get_router_info(router_id)
287 }
288
289 fn get_max_router_id(&self) -> u8 {
290 self.as_ref().get_max_router_id()
291 }
292
293 fn get_ip6_counters(&self) -> &IpCounters {
294 self.as_ref().get_ip6_counters()
295 }
296
297 fn iter_next_neighbor_info(
298 &self,
299 ot_iter: &mut otNeighborInfoIterator,
300 ) -> Option<NeighborInfo> {
301 self.as_ref().iter_next_neighbor_info(ot_iter)
302 }
303
304 fn set_vendor_name(&self, name: &str) -> Result {
305 self.as_ref().set_vendor_name(name)
306 }
307
308 fn set_vendor_model(&self, model: &str) -> Result {
309 self.as_ref().set_vendor_model(model)
310 }
311
312 fn set_vendor_sw_version(&self, version: &str) -> Result {
313 self.as_ref().set_vendor_sw_version(version)
314 }
315
316 fn get_mle_counters(&self) -> &MleCounters {
317 self.as_ref().get_mle_counters()
318 }
319
320 fn iter_next_cache_entry_info(
321 &self,
322 ot_iter: &mut otCacheEntryIterator,
323 ) -> Option<CacheEntryInfo> {
324 self.as_ref().iter_next_cache_entry_info(ot_iter)
325 }
326}
327
328impl Thread for Instance {
329 fn become_leader(&self) -> Result<()> {
330 Error::from(unsafe { otThreadBecomeLeader(self.as_ot_ptr()) }).into()
331 }
332
333 fn become_router(&self) -> Result<()> {
334 Error::from(unsafe { otThreadBecomeRouter(self.as_ot_ptr()) }).into()
335 }
336
337 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
338 let mut ret: otChildInfo = Default::default();
339 Error::from(unsafe { otThreadGetChildInfoById(self.as_ot_ptr(), child_id, &mut ret) })
340 .into_result()?;
341 Ok(ret)
342 }
343
344 fn get_leader_data(&self) -> Result<LeaderData> {
345 let mut ret = LeaderData::default();
346 Error::from(unsafe { otThreadGetLeaderData(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
347 .into_result()?;
348 Ok(ret)
349 }
350
351 fn get_leader_weight(&self) -> u8 {
352 unsafe { otThreadGetLeaderWeight(self.as_ot_ptr()) }
353 }
354
355 fn get_network_key(&self) -> NetworkKey {
356 let mut ret = NetworkKey::default();
357 unsafe { otThreadGetNetworkKey(self.as_ot_ptr(), ret.as_ot_mut_ptr()) }
358 ret
359 }
360
361 fn set_network_key(&self, key: &NetworkKey) -> Result {
362 Error::from(unsafe { otThreadSetNetworkKey(self.as_ot_ptr(), key.as_ot_ptr()) })
363 .into_result()
364 }
365
366 #[allow(clippy::unnecessary_cast)]
367 fn get_network_name_as_slice(&self) -> &[u8] {
368 unsafe {
369 let slice = std::slice::from_raw_parts(
370 otThreadGetNetworkName(self.as_ot_ptr()) as *const u8,
371 OT_NETWORK_NAME_MAX_SIZE as usize,
372 );
373 let first_zero_index =
374 slice.iter().position(|&x| x == 0).unwrap_or(OT_NETWORK_NAME_MAX_SIZE as usize);
375 &slice[0..first_zero_index]
376 }
377 }
378
379 fn set_network_name(&self, name: &NetworkName) -> Result {
380 Error::from(unsafe { otThreadSetNetworkName(self.as_ot_ptr(), name.as_c_str()) })
381 .into_result()
382 }
383
384 fn is_singleton(&self) -> bool {
385 unsafe { otThreadIsSingleton(self.as_ot_ptr()) }
386 }
387
388 fn get_extended_pan_id(&self) -> &ExtendedPanId {
389 unsafe {
390 let xpanid = otThreadGetExtendedPanId(self.as_ot_ptr());
391 ExtendedPanId::ref_from_ot_ptr(xpanid)
392 }
393 .unwrap()
394 }
395
396 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
397 Error::from(unsafe { otThreadSetExtendedPanId(self.as_ot_ptr(), xpanid.as_ot_ptr()) })
398 .into_result()
399 }
400
401 fn thread_set_enabled(&self, enabled: bool) -> Result {
402 Error::from(unsafe { otThreadSetEnabled(self.as_ot_ptr(), enabled) }).into_result()
403 }
404
405 fn get_device_role(&self) -> ot::DeviceRole {
406 unsafe { otThreadGetDeviceRole(self.as_ot_ptr()) }.into()
407 }
408
409 fn get_partition_id(&self) -> u32 {
410 unsafe { otThreadGetPartitionId(self.as_ot_ptr()) }
411 }
412
413 fn get_rloc16(&self) -> u16 {
414 unsafe { otThreadGetRloc16(self.as_ot_ptr()) }
415 }
416
417 fn get_link_mode(&self) -> ot::LinkModeConfig {
418 unsafe { otThreadGetLinkMode(self.as_ot_ptr()) }.into()
419 }
420
421 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
422 Error::from(unsafe { otThreadSetLinkMode(self.as_ot_ptr(), link_mode_config.into()) })
423 .into_result()
424 }
425
426 fn get_rloc(&self) -> std::net::Ipv6Addr {
427 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetRloc(self.as_ot_ptr()) })
428 }
429
430 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
431 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetMeshLocalEid(self.as_ot_ptr()) })
432 }
433
434 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
435 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetLinkLocalIp6Address(self.as_ot_ptr()) })
436 }
437
438 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
439 std::net::Ipv6Addr::from_ot(unsafe {
440 *otThreadGetLinkLocalAllThreadNodesMulticastAddress(self.as_ot_ptr())
441 })
442 }
443
444 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
445 unsafe { MeshLocalPrefix::ref_from_ot_ptr(otThreadGetMeshLocalPrefix(self.as_ot_ptr())) }
446 .unwrap()
447 }
448
449 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
450 let mut ret = RouterInfo::default();
451 Error::from(unsafe {
452 otThreadGetRouterInfo(self.as_ot_ptr(), router_id, ret.as_ot_mut_ptr())
453 })
454 .into_result()?;
455 Ok(ret)
456 }
457
458 fn get_max_router_id(&self) -> u8 {
459 unsafe { otThreadGetMaxRouterId(self.as_ot_ptr()) }
460 }
461
462 fn get_ip6_counters(&self) -> &IpCounters {
463 unsafe { IpCounters::ref_from_ot_ptr(otThreadGetIp6Counters(self.as_ot_ptr())) }.unwrap()
464 }
465
466 fn iter_next_neighbor_info(
467 &self,
468 ot_iter: &mut otNeighborInfoIterator,
469 ) -> Option<NeighborInfo> {
470 unsafe {
471 let mut ret = NeighborInfo::default();
472 match Error::from(otThreadGetNextNeighborInfo(
473 self.as_ot_ptr(),
474 ot_iter as *mut otNeighborInfoIterator,
475 ret.as_ot_mut_ptr(),
476 )) {
477 Error::NotFound => None,
478 Error::None => Some(ret),
479 err => unreachable!("Unexpected error from otThreadGetNextNeighborInfo: {:?}", err),
480 }
481 }
482 }
483
484 fn set_vendor_name(&self, name: &str) -> Result {
485 let vendor_name = CString::new(name).expect("Vendor name must not contain null bytes");
486 Error::from(unsafe {
487 otThreadSetVendorName(
488 self.as_ot_ptr(),
489 vendor_name.as_ptr() as *const ::std::os::raw::c_char,
490 )
491 })
492 .into_result()
493 }
494
495 fn set_vendor_model(&self, model: &str) -> Result {
496 let vendor_model = CString::new(model).expect("Vendor model must not contain null bytes");
497 Error::from(unsafe {
498 otThreadSetVendorModel(
499 self.as_ot_ptr(),
500 vendor_model.as_ptr() as *const ::std::os::raw::c_char,
501 )
502 })
503 .into_result()
504 }
505
506 fn set_vendor_sw_version(&self, version: &str) -> Result {
507 let vendor_sw_version =
508 CString::new(version).expect("Vendor SW Version must not contain null bytes");
509 Error::from(unsafe {
510 otThreadSetVendorSwVersion(
511 self.as_ot_ptr(),
512 vendor_sw_version.as_ptr() as *const ::std::os::raw::c_char,
513 )
514 })
515 .into_result()
516 }
517
518 fn get_mle_counters(&self) -> &MleCounters {
519 unsafe { MleCounters::ref_from_ot_ptr(otThreadGetMleCounters(self.as_ot_ptr())) }.unwrap()
520 }
521
522 fn iter_next_cache_entry_info(
523 &self,
524 ot_iter: &mut otCacheEntryIterator,
525 ) -> Option<CacheEntryInfo> {
526 unsafe {
527 let mut ret = CacheEntryInfo::default();
528 match Error::from(otThreadGetNextCacheEntry(
529 self.as_ot_ptr(),
530 ret.as_ot_mut_ptr(),
531 ot_iter as *mut otCacheEntryIterator,
532 )) {
533 Error::NotFound => None,
534 Error::None => Some(ret),
535 err => unreachable!("Unexpected error from otThreadGetNextCacheEntry: {:?}", err),
536 }
537 }
538 }
539}