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 fn set_vendor_name(&self, name: &str) -> Result;
157
158 fn set_vendor_model(&self, model: &str) -> Result;
161
162 fn set_vendor_sw_version(&self, version: &str) -> Result;
165
166 fn get_mle_counters(&self) -> &MleCounters;
169}
170
171impl<T: Thread + Boxable> Thread for ot::Box<T> {
172 fn become_leader(&self) -> Result<()> {
173 self.as_ref().become_leader()
174 }
175 fn become_router(&self) -> Result<()> {
176 self.as_ref().become_router()
177 }
178 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
179 self.as_ref().get_child_info_by_id(child_id)
180 }
181 fn get_leader_data(&self) -> Result<LeaderData> {
182 self.as_ref().get_leader_data()
183 }
184
185 fn get_leader_weight(&self) -> u8 {
186 self.as_ref().get_leader_weight()
187 }
188
189 fn get_network_key(&self) -> NetworkKey {
190 self.as_ref().get_network_key()
191 }
192
193 fn set_network_key(&self, key: &NetworkKey) -> Result {
194 self.as_ref().set_network_key(key)
195 }
196 fn get_network_name_as_slice(&self) -> &[u8] {
197 self.as_ref().get_network_name_as_slice()
198 }
199
200 fn set_network_name(&self, name: &NetworkName) -> Result {
201 self.as_ref().set_network_name(name)
202 }
203
204 fn is_singleton(&self) -> bool {
205 self.as_ref().is_singleton()
206 }
207
208 fn get_extended_pan_id(&self) -> &ExtendedPanId {
209 self.as_ref().get_extended_pan_id()
210 }
211
212 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
213 self.as_ref().set_extended_pan_id(xpanid)
214 }
215
216 fn thread_set_enabled(&self, enabled: bool) -> Result {
217 self.as_ref().thread_set_enabled(enabled)
218 }
219
220 fn get_device_role(&self) -> DeviceRole {
221 self.as_ref().get_device_role()
222 }
223
224 fn get_partition_id(&self) -> u32 {
225 self.as_ref().get_partition_id()
226 }
227
228 fn get_rloc16(&self) -> u16 {
229 self.as_ref().get_rloc16()
230 }
231
232 fn get_link_mode(&self) -> ot::LinkModeConfig {
233 self.as_ref().get_link_mode()
234 }
235
236 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
237 self.as_ref().set_link_mode(link_mode_config)
238 }
239
240 fn get_rloc(&self) -> std::net::Ipv6Addr {
241 self.as_ref().get_rloc()
242 }
243
244 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
245 self.as_ref().get_mesh_local_eid()
246 }
247
248 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
249 self.as_ref().get_link_local_addr()
250 }
251
252 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
253 self.as_ref().get_link_local_all_nodes_multicast_addr()
254 }
255
256 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
257 self.as_ref().get_mesh_local_prefix()
258 }
259
260 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
261 self.as_ref().get_router_info(router_id)
262 }
263
264 fn get_max_router_id(&self) -> u8 {
265 self.as_ref().get_max_router_id()
266 }
267
268 fn get_ip6_counters(&self) -> &IpCounters {
269 self.as_ref().get_ip6_counters()
270 }
271
272 fn iter_next_neighbor_info(
273 &self,
274 ot_iter: &mut otNeighborInfoIterator,
275 ) -> Option<NeighborInfo> {
276 self.as_ref().iter_next_neighbor_info(ot_iter)
277 }
278
279 fn set_vendor_name(&self, name: &str) -> Result {
280 self.as_ref().set_vendor_name(name)
281 }
282
283 fn set_vendor_model(&self, model: &str) -> Result {
284 self.as_ref().set_vendor_model(model)
285 }
286
287 fn set_vendor_sw_version(&self, version: &str) -> Result {
288 self.as_ref().set_vendor_sw_version(version)
289 }
290
291 fn get_mle_counters(&self) -> &MleCounters {
292 self.as_ref().get_mle_counters()
293 }
294}
295
296impl Thread for Instance {
297 fn become_leader(&self) -> Result<()> {
298 Error::from(unsafe { otThreadBecomeLeader(self.as_ot_ptr()) }).into()
299 }
300
301 fn become_router(&self) -> Result<()> {
302 Error::from(unsafe { otThreadBecomeRouter(self.as_ot_ptr()) }).into()
303 }
304
305 fn get_child_info_by_id(&self, child_id: u16) -> Result<otChildInfo> {
306 let mut ret: otChildInfo = Default::default();
307 Error::from(unsafe { otThreadGetChildInfoById(self.as_ot_ptr(), child_id, &mut ret) })
308 .into_result()?;
309 Ok(ret)
310 }
311
312 fn get_leader_data(&self) -> Result<LeaderData> {
313 let mut ret = LeaderData::default();
314 Error::from(unsafe { otThreadGetLeaderData(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
315 .into_result()?;
316 Ok(ret)
317 }
318
319 fn get_leader_weight(&self) -> u8 {
320 unsafe { otThreadGetLeaderWeight(self.as_ot_ptr()) }
321 }
322
323 fn get_network_key(&self) -> NetworkKey {
324 let mut ret = NetworkKey::default();
325 unsafe { otThreadGetNetworkKey(self.as_ot_ptr(), ret.as_ot_mut_ptr()) }
326 ret
327 }
328
329 fn set_network_key(&self, key: &NetworkKey) -> Result {
330 Error::from(unsafe { otThreadSetNetworkKey(self.as_ot_ptr(), key.as_ot_ptr()) })
331 .into_result()
332 }
333
334 #[allow(clippy::unnecessary_cast)]
335 fn get_network_name_as_slice(&self) -> &[u8] {
336 unsafe {
337 let slice = std::slice::from_raw_parts(
338 otThreadGetNetworkName(self.as_ot_ptr()) as *const u8,
339 OT_NETWORK_NAME_MAX_SIZE as usize,
340 );
341 let first_zero_index =
342 slice.iter().position(|&x| x == 0).unwrap_or(OT_NETWORK_NAME_MAX_SIZE as usize);
343 &slice[0..first_zero_index]
344 }
345 }
346
347 fn set_network_name(&self, name: &NetworkName) -> Result {
348 Error::from(unsafe { otThreadSetNetworkName(self.as_ot_ptr(), name.as_c_str()) })
349 .into_result()
350 }
351
352 fn is_singleton(&self) -> bool {
353 unsafe { otThreadIsSingleton(self.as_ot_ptr()) }
354 }
355
356 fn get_extended_pan_id(&self) -> &ExtendedPanId {
357 unsafe {
358 let xpanid = otThreadGetExtendedPanId(self.as_ot_ptr());
359 ExtendedPanId::ref_from_ot_ptr(xpanid)
360 }
361 .unwrap()
362 }
363
364 fn set_extended_pan_id(&self, xpanid: &ExtendedPanId) -> Result {
365 Error::from(unsafe { otThreadSetExtendedPanId(self.as_ot_ptr(), xpanid.as_ot_ptr()) })
366 .into_result()
367 }
368
369 fn thread_set_enabled(&self, enabled: bool) -> Result {
370 Error::from(unsafe { otThreadSetEnabled(self.as_ot_ptr(), enabled) }).into_result()
371 }
372
373 fn get_device_role(&self) -> ot::DeviceRole {
374 unsafe { otThreadGetDeviceRole(self.as_ot_ptr()) }.into()
375 }
376
377 fn get_partition_id(&self) -> u32 {
378 unsafe { otThreadGetPartitionId(self.as_ot_ptr()) }
379 }
380
381 fn get_rloc16(&self) -> u16 {
382 unsafe { otThreadGetRloc16(self.as_ot_ptr()) }
383 }
384
385 fn get_link_mode(&self) -> ot::LinkModeConfig {
386 unsafe { otThreadGetLinkMode(self.as_ot_ptr()) }.into()
387 }
388
389 fn set_link_mode(&self, link_mode_config: ot::LinkModeConfig) -> Result {
390 Error::from(unsafe { otThreadSetLinkMode(self.as_ot_ptr(), link_mode_config.into()) })
391 .into_result()
392 }
393
394 fn get_rloc(&self) -> std::net::Ipv6Addr {
395 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetRloc(self.as_ot_ptr()) })
396 }
397
398 fn get_mesh_local_eid(&self) -> std::net::Ipv6Addr {
399 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetMeshLocalEid(self.as_ot_ptr()) })
400 }
401
402 fn get_link_local_addr(&self) -> std::net::Ipv6Addr {
403 std::net::Ipv6Addr::from_ot(unsafe { *otThreadGetLinkLocalIp6Address(self.as_ot_ptr()) })
404 }
405
406 fn get_link_local_all_nodes_multicast_addr(&self) -> std::net::Ipv6Addr {
407 std::net::Ipv6Addr::from_ot(unsafe {
408 *otThreadGetLinkLocalAllThreadNodesMulticastAddress(self.as_ot_ptr())
409 })
410 }
411
412 fn get_mesh_local_prefix(&self) -> &MeshLocalPrefix {
413 unsafe { MeshLocalPrefix::ref_from_ot_ptr(otThreadGetMeshLocalPrefix(self.as_ot_ptr())) }
414 .unwrap()
415 }
416
417 fn get_router_info(&self, router_id: u16) -> Result<RouterInfo> {
418 let mut ret = RouterInfo::default();
419 Error::from(unsafe {
420 otThreadGetRouterInfo(self.as_ot_ptr(), router_id, ret.as_ot_mut_ptr())
421 })
422 .into_result()?;
423 Ok(ret)
424 }
425
426 fn get_max_router_id(&self) -> u8 {
427 unsafe { otThreadGetMaxRouterId(self.as_ot_ptr()) }
428 }
429
430 fn get_ip6_counters(&self) -> &IpCounters {
431 unsafe { IpCounters::ref_from_ot_ptr(otThreadGetIp6Counters(self.as_ot_ptr())) }.unwrap()
432 }
433
434 fn iter_next_neighbor_info(
435 &self,
436 ot_iter: &mut otNeighborInfoIterator,
437 ) -> Option<NeighborInfo> {
438 unsafe {
439 let mut ret = NeighborInfo::default();
440 match Error::from(otThreadGetNextNeighborInfo(
441 self.as_ot_ptr(),
442 ot_iter as *mut otNeighborInfoIterator,
443 ret.as_ot_mut_ptr(),
444 )) {
445 Error::NotFound => None,
446 Error::None => Some(ret),
447 err => unreachable!("Unexpected error from otThreadGetNextNeighborInfo: {:?}", err),
448 }
449 }
450 }
451
452 fn set_vendor_name(&self, name: &str) -> Result {
453 let vendor_name = CString::new(name).expect("Vendor name must not contain null bytes");
454 Error::from(unsafe {
455 otThreadSetVendorName(
456 self.as_ot_ptr(),
457 vendor_name.as_ptr() as *const ::std::os::raw::c_char,
458 )
459 })
460 .into_result()
461 }
462
463 fn set_vendor_model(&self, model: &str) -> Result {
464 let vendor_model = CString::new(model).expect("Vendor model must not contain null bytes");
465 Error::from(unsafe {
466 otThreadSetVendorModel(
467 self.as_ot_ptr(),
468 vendor_model.as_ptr() as *const ::std::os::raw::c_char,
469 )
470 })
471 .into_result()
472 }
473
474 fn set_vendor_sw_version(&self, version: &str) -> Result {
475 let vendor_sw_version =
476 CString::new(version).expect("Vendor SW Version must not contain null bytes");
477 Error::from(unsafe {
478 otThreadSetVendorSwVersion(
479 self.as_ot_ptr(),
480 vendor_sw_version.as_ptr() as *const ::std::os::raw::c_char,
481 )
482 })
483 .into_result()
484 }
485
486 fn get_mle_counters(&self) -> &MleCounters {
487 unsafe { MleCounters::ref_from_ot_ptr(otThreadGetMleCounters(self.as_ot_ptr())) }.unwrap()
488 }
489}