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