Skip to main content

openthread/ot/
border_router.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::ot::WrongSize;
6use crate::prelude_internal::*;
7use core::pin::Pin;
8use core::task::{Context, Poll};
9use fuchsia_sync::Mutex;
10use std::sync::Arc;
11use std::task::Waker;
12
13/// Iterator type for external routes.
14#[allow(missing_debug_implementations)]
15pub struct LocalExternalRouteIterator<'a, T: ?Sized> {
16    ot_instance: &'a T,
17    ot_iter: otNetworkDataIterator,
18}
19
20impl<T: ?Sized + BorderRouter> Iterator for LocalExternalRouteIterator<'_, T> {
21    type Item = ExternalRouteConfig;
22    fn next(&mut self) -> Option<Self::Item> {
23        self.ot_instance.iter_next_local_external_route(&mut self.ot_iter)
24    }
25}
26
27/// Iterator type for on-mesh prefixes.
28#[allow(missing_debug_implementations)]
29pub struct LocalOnMeshPrefixIterator<'a, T: ?Sized> {
30    ot_instance: &'a T,
31    ot_iter: otNetworkDataIterator,
32}
33
34impl<T: ?Sized + BorderRouter> Iterator for LocalOnMeshPrefixIterator<'_, T> {
35    type Item = BorderRouterConfig;
36    fn next(&mut self) -> Option<Self::Item> {
37        self.ot_instance.iter_next_local_on_mesh_prefix(&mut self.ot_iter)
38    }
39}
40
41/// Iterator type for border routing peer border router.
42#[allow(missing_debug_implementations)]
43pub struct BorderRoutingPeerIterator<'a, T: ?Sized> {
44    ot_instance: &'a T,
45    ot_iter: otBorderRoutingPrefixTableIterator,
46}
47
48impl<T: ?Sized + BorderRouter> Iterator for BorderRoutingPeerIterator<'_, T> {
49    type Item = BorderRoutingPeer;
50    fn next(&mut self) -> Option<Self::Item> {
51        self.ot_instance.iter_next_border_routing_peer(&mut self.ot_iter)
52    }
53}
54
55/// Iterator type for border routing router.
56#[allow(missing_debug_implementations)]
57pub struct BorderRoutingRouterIterator<'a, T: ?Sized> {
58    ot_instance: &'a T,
59    ot_iter: otBorderRoutingPrefixTableIterator,
60}
61
62impl<T: ?Sized + BorderRouter> Iterator for BorderRoutingRouterIterator<'_, T> {
63    type Item = BorderRoutingRouter;
64    fn next(&mut self) -> Option<Self::Item> {
65        self.ot_instance.iter_next_border_routing_router(&mut self.ot_iter)
66    }
67}
68
69/// Iterator type for border routing prefix table.
70#[allow(missing_debug_implementations)]
71pub struct BorderRoutingPrefixTableIterator<'a, T: ?Sized> {
72    ot_instance: &'a T,
73    ot_iter: otBorderRoutingPrefixTableIterator,
74}
75
76impl<T: ?Sized + BorderRouter> Iterator for BorderRoutingPrefixTableIterator<'_, T> {
77    type Item = BorderRoutingPrefixTableEntry;
78    fn next(&mut self) -> Option<Self::Item> {
79        self.ot_instance.iter_next_border_routing_prefix_table(&mut self.ot_iter)
80    }
81}
82
83/// Iterator type for border routing the Recursive DNS Server (RDNSS) address.
84#[allow(missing_debug_implementations)]
85pub struct BorderRoutingRdnssIterator<'a, T: ?Sized> {
86    ot_instance: &'a T,
87    ot_iter: otBorderRoutingPrefixTableIterator,
88}
89
90impl<T: ?Sized + BorderRouter> Iterator for BorderRoutingRdnssIterator<'_, T> {
91    type Item = BorderRoutingRdnss;
92    fn next(&mut self) -> Option<Self::Item> {
93        self.ot_instance.iter_next_border_routing_rdnss(&mut self.ot_iter)
94    }
95}
96
97/// Methods from the [OpenThread "Border Router" Module][1].
98///
99/// [1]: https://openthread.io/reference/group/api-border-router
100pub trait BorderRouter {
101    /// Functional equivalent of
102    /// [`otsys::otBorderRouterAddRoute`](crate::otsys::otBorderRouterAddRoute).
103    fn add_external_route(&self, route: &ExternalRouteConfig) -> Result;
104
105    /// Functional equivalent of
106    /// [`otsys::otBorderRouterAddOnMeshPrefix`](crate::otsys::otBorderRouterAddOnMeshPrefix).
107    fn add_on_mesh_prefix(&self, route: &BorderRouterConfig) -> Result;
108
109    /// Functional equivalent of
110    /// [`otsys::otBorderRouterRemoveRoute`](crate::otsys::otBorderRouterRemoveRoute).
111    fn remove_external_route(&self, prefix: &Ip6Prefix) -> Result;
112
113    /// Functional equivalent of
114    /// [`otsys::otBorderRouterRemoveOnMeshPrefix`](crate::otsys::otBorderRouterRemoveOnMeshPrefix).
115    fn remove_on_mesh_prefix(&self, prefix: &Ip6Prefix) -> Result;
116
117    /// Functional equivalent of
118    /// [`otsys::otBorderRouterRegister`](crate::otsys::otBorderRouterRegister).
119    fn border_router_register(&self) -> Result;
120
121    /// Functional equivalent of
122    /// [`otsys::otBorderRoutingInit`](crate::otsys::otBorderRoutingInit).
123    fn border_routing_init(&self, infra_if: u32, infra_is_running: bool) -> Result;
124
125    /// Functional equivalent of
126    /// [`otsys::otBorderRoutingSetEnabled`](crate::otsys::otBorderRoutingSetEnabled).
127    fn border_routing_set_enabled(&self, enabled: bool) -> Result;
128
129    /// Functional equivalent of
130    /// [`otsys::otBorderRoutingDhcp6PdSetEnabled`](crate::otsys::otBorderRoutingDhcp6PdSetEnabled).
131    fn border_routing_dhcp6_pd_set_enabled(&self, enabled: bool);
132
133    /// Functional equivalent of
134    /// [`otsys::otBorderRoutingDhcp6PdGetState`](crate::otsys::otBorderRoutingDhcp6PdGetState).
135    fn border_routing_dhcp6_pd_get_state(&self) -> BorderRoutingDhcp6PdState;
136
137    /// Functional equivalent of
138    /// [`otsys::otBorderRoutingDhcp6PdSetRequestCallback`]
139    /// (crate::otsys::otBorderRoutingDhcp6PdSetRequestCallback).
140    fn border_routing_dhcp6_pd_set_request_fn<'a, F>(&'a self, f: Option<F>)
141    where
142        F: FnMut(BorderRoutingDhcp6PdState) + 'a;
143
144    /// Get the DHCPv6 PD state change stream
145    fn border_routing_dhcp6_pd_state_change_stream(&self)
146    -> BorderRoutingDhcp6PdStateChangedStream;
147
148    /// Functional equivalent of
149    /// [`otsys::otBorderRoutingGetPdOmrPrefix`](crate::otsys::otBorderRoutingGetPdOmrPrefix).
150    fn border_routing_get_pd_omr_prefix(&self) -> Result<ot::BorderRoutingPrefixTableEntry>;
151
152    /// Functional equivalent of
153    /// [`otsys::otBorderRoutingGetOmrPrefix`](crate::otsys::otBorderRoutingGetOmrPrefix).
154    fn border_routing_get_omr_prefix(&self) -> Result<ot::Ip6Prefix>;
155
156    /// Functional equivalent of
157    /// [`otsys::otBorderRoutingGetOnLinkPrefix`](crate::otsys::otBorderRoutingGetOnLinkPrefix).
158    fn border_routing_get_on_link_prefix(&self) -> Result<ot::Ip6Prefix>;
159
160    /// Functional equivalent of
161    /// [`otsys::otPlatBorderRoutingProcessIcmp6Ra`]
162    /// (crate::otsys::otPlatBorderRoutingProcessIcmp6Ra).
163    fn border_routing_process_icmp6_ra(&self, message: &[u8]) -> Result<(), WrongSize>;
164
165    /// Functional equivalent of
166    /// [`otsys::otBorderRoutingGetPdProcessedRaInfo`]
167    /// (crate::otsys::otBorderRoutingGetPdProcessedRaInfo).
168    fn border_routing_get_pd_processed_ra_info(&self) -> PdProcessedRaInfo;
169
170    /// Functional equivalent of
171    /// [`otsys::otBorderRoutingIsMultiAilDetected`]
172    /// (crate::otsys::otBorderRoutingIsMultiAilDetected).
173    fn border_routing_is_multi_ail_detected(&self) -> bool;
174
175    /// Functional equivalent of
176    /// [`otsys::otBorderRoutingPrefixTableInitIterator`]
177    /// (crate::otsys::otBorderRoutingPrefixTableInitIterator).
178    fn border_routing_prefix_table_init_iterator(
179        &self,
180        iter: &mut otBorderRoutingPrefixTableIterator,
181    );
182
183    /// Get the border routing peer iterator instance.
184    fn border_routing_peer_get_iterator(&self) -> BorderRoutingPeerIterator<'_, Self> {
185        let mut ot_iter = otBorderRoutingPrefixTableIterator::default();
186        self.border_routing_prefix_table_init_iterator(&mut ot_iter);
187        BorderRoutingPeerIterator { ot_instance: self, ot_iter }
188    }
189
190    /// Get the border routing router iterator instance.
191    fn border_routing_router_get_iterator(&self) -> BorderRoutingRouterIterator<'_, Self> {
192        let mut ot_iter = otBorderRoutingPrefixTableIterator::default();
193        self.border_routing_prefix_table_init_iterator(&mut ot_iter);
194        BorderRoutingRouterIterator { ot_instance: self, ot_iter }
195    }
196
197    /// Get the border routing prefix table iterator instance.
198    fn border_routing_prefix_table_get_iterator(
199        &self,
200    ) -> BorderRoutingPrefixTableIterator<'_, Self> {
201        let mut ot_iter = otBorderRoutingPrefixTableIterator::default();
202        self.border_routing_prefix_table_init_iterator(&mut ot_iter);
203        BorderRoutingPrefixTableIterator { ot_instance: self, ot_iter }
204    }
205
206    /// Get the border routing rdnss iterator instance.
207    fn border_routing_rdnss_get_iterator(&self) -> BorderRoutingRdnssIterator<'_, Self> {
208        let mut ot_iter = otBorderRoutingPrefixTableIterator::default();
209        self.border_routing_prefix_table_init_iterator(&mut ot_iter);
210        BorderRoutingRdnssIterator { ot_instance: self, ot_iter }
211    }
212
213    /// Functional equivalent of
214    /// [`otsys::otBorderRouterGetNextRoute`](crate::otsys::otBorderRouterGetNextRoute).
215    // TODO: Determine if the underlying implementation of
216    //       this method has undefined behavior when network data
217    //       is being mutated while iterating. If it is undefined,
218    //       we may need to make it unsafe and provide a safe method
219    //       that collects the results.
220    fn iter_next_local_external_route(
221        &self,
222        ot_iter: &mut otNetworkDataIterator,
223    ) -> Option<ExternalRouteConfig>;
224
225    /// Functional equivalent of
226    /// [`otsys::otBorderRouterGetNextOnMeshPrefix`]
227    /// (crate::otsys::otBorderRouterGetNextOnMeshPrefix).
228    // TODO: Determine if the underlying implementation of
229    //       this method has undefined behavior when network data
230    //       is being mutated while iterating. If it is undefined,
231    //       we may need to make it unsafe and provide a safe method
232    //       that collects the results.
233    fn iter_next_local_on_mesh_prefix(
234        &self,
235        ot_iter: &mut otNetworkDataIterator,
236    ) -> Option<BorderRouterConfig>;
237
238    /// Functional equivalent of
239    /// [`otsys::otBorderRoutingGetNextPeerBrEntry`]
240    /// (crate::otsys::otBorderRoutingGetNextPeerBrEntry).
241    fn iter_next_border_routing_peer(
242        &self,
243        ot_iter: &mut otBorderRoutingPrefixTableIterator,
244    ) -> Option<BorderRoutingPeer>;
245
246    /// Functional equivalent of
247    /// [`otsys::otBorderRoutingGetNextRouterEntry`]
248    /// (crate::otsys::otBorderRoutingGetNextRouterEntry).
249    fn iter_next_border_routing_router(
250        &self,
251        ot_iter: &mut otBorderRoutingPrefixTableIterator,
252    ) -> Option<BorderRoutingRouter>;
253
254    /// Functional equivalent of
255    /// [`otsys::otBorderRoutingGetNextPrefixTableEntry`]
256    /// (crate::otsys::otBorderRoutingGetNextPrefixTableEntry).
257    fn iter_next_border_routing_prefix_table(
258        &self,
259        ot_iter: &mut otBorderRoutingPrefixTableIterator,
260    ) -> Option<BorderRoutingPrefixTableEntry>;
261
262    /// Functional equivalent of
263    /// [`otsys::otBorderRoutingGetNextRdnssAddrEntry`]
264    /// (crate::otsys::otBorderRoutingGetNextRdnssAddrEntry).
265    fn iter_next_border_routing_rdnss(
266        &self,
267        ot_iter: &mut otBorderRoutingPrefixTableIterator,
268    ) -> Option<BorderRoutingRdnss>;
269
270    /// Returns an iterator for iterating over external routes.
271    fn iter_local_external_routes(&self) -> LocalExternalRouteIterator<'_, Self> {
272        LocalExternalRouteIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
273    }
274
275    /// Returns an iterator for iterating over on-mesh prefixes
276    fn iter_local_on_mesh_prefixes(&self) -> LocalOnMeshPrefixIterator<'_, Self> {
277        LocalOnMeshPrefixIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
278    }
279}
280
281impl<T: BorderRouter + Boxable> BorderRouter for ot::Box<T> {
282    fn add_external_route(&self, route: &ExternalRouteConfig) -> Result {
283        self.as_ref().add_external_route(route)
284    }
285
286    fn add_on_mesh_prefix(&self, route: &BorderRouterConfig) -> Result {
287        self.as_ref().add_on_mesh_prefix(route)
288    }
289
290    fn remove_external_route(&self, prefix: &Ip6Prefix) -> Result {
291        self.as_ref().remove_external_route(prefix)
292    }
293
294    fn remove_on_mesh_prefix(&self, prefix: &Ip6Prefix) -> Result {
295        self.as_ref().remove_on_mesh_prefix(prefix)
296    }
297
298    fn border_router_register(&self) -> Result {
299        self.as_ref().border_router_register()
300    }
301
302    fn border_routing_init(&self, infra_if: u32, infra_is_running: bool) -> Result {
303        self.as_ref().border_routing_init(infra_if, infra_is_running)
304    }
305
306    fn border_routing_set_enabled(&self, enabled: bool) -> Result {
307        self.as_ref().border_routing_set_enabled(enabled)
308    }
309
310    fn border_routing_dhcp6_pd_set_enabled(&self, enabled: bool) {
311        self.as_ref().border_routing_dhcp6_pd_set_enabled(enabled)
312    }
313
314    fn border_routing_dhcp6_pd_get_state(&self) -> BorderRoutingDhcp6PdState {
315        self.as_ref().border_routing_dhcp6_pd_get_state()
316    }
317
318    fn border_routing_dhcp6_pd_set_request_fn<'a, F>(&'a self, f: Option<F>)
319    where
320        F: FnMut(BorderRoutingDhcp6PdState) + 'a,
321    {
322        self.as_ref().border_routing_dhcp6_pd_set_request_fn(f)
323    }
324
325    fn border_routing_dhcp6_pd_state_change_stream(
326        &self,
327    ) -> BorderRoutingDhcp6PdStateChangedStream {
328        self.as_ref().border_routing_dhcp6_pd_state_change_stream()
329    }
330
331    fn border_routing_get_pd_omr_prefix(&self) -> Result<ot::BorderRoutingPrefixTableEntry> {
332        self.as_ref().border_routing_get_pd_omr_prefix()
333    }
334
335    fn border_routing_get_omr_prefix(&self) -> Result<ot::Ip6Prefix> {
336        self.as_ref().border_routing_get_omr_prefix()
337    }
338
339    fn border_routing_get_on_link_prefix(&self) -> Result<ot::Ip6Prefix> {
340        self.as_ref().border_routing_get_on_link_prefix()
341    }
342
343    fn border_routing_process_icmp6_ra(&self, message: &[u8]) -> Result<(), WrongSize> {
344        self.as_ref().border_routing_process_icmp6_ra(message)
345    }
346
347    fn border_routing_get_pd_processed_ra_info(&self) -> PdProcessedRaInfo {
348        self.as_ref().border_routing_get_pd_processed_ra_info()
349    }
350
351    fn border_routing_is_multi_ail_detected(&self) -> bool {
352        self.as_ref().border_routing_is_multi_ail_detected()
353    }
354
355    fn border_routing_prefix_table_init_iterator(
356        &self,
357        iter: &mut otBorderRoutingPrefixTableIterator,
358    ) {
359        self.as_ref().border_routing_prefix_table_init_iterator(iter)
360    }
361
362    fn iter_next_local_external_route(
363        &self,
364        ot_iter: &mut otNetworkDataIterator,
365    ) -> Option<ExternalRouteConfig> {
366        self.as_ref().iter_next_local_external_route(ot_iter)
367    }
368
369    fn iter_next_local_on_mesh_prefix(
370        &self,
371        ot_iter: &mut otNetworkDataIterator,
372    ) -> Option<BorderRouterConfig> {
373        self.as_ref().iter_next_local_on_mesh_prefix(ot_iter)
374    }
375
376    fn iter_next_border_routing_peer(
377        &self,
378        ot_iter: &mut otBorderRoutingPrefixTableIterator,
379    ) -> Option<BorderRoutingPeer> {
380        self.as_ref().iter_next_border_routing_peer(ot_iter)
381    }
382
383    fn iter_next_border_routing_router(
384        &self,
385        ot_iter: &mut otBorderRoutingPrefixTableIterator,
386    ) -> Option<BorderRoutingRouter> {
387        self.as_ref().iter_next_border_routing_router(ot_iter)
388    }
389
390    fn iter_next_border_routing_prefix_table(
391        &self,
392        ot_iter: &mut otBorderRoutingPrefixTableIterator,
393    ) -> Option<BorderRoutingPrefixTableEntry> {
394        self.as_ref().iter_next_border_routing_prefix_table(ot_iter)
395    }
396
397    fn iter_next_border_routing_rdnss(
398        &self,
399        ot_iter: &mut otBorderRoutingPrefixTableIterator,
400    ) -> Option<BorderRoutingRdnss> {
401        self.as_ref().iter_next_border_routing_rdnss(ot_iter)
402    }
403}
404
405impl BorderRouter for Instance {
406    fn add_external_route(&self, route: &ExternalRouteConfig) -> Result {
407        Error::from(unsafe { otBorderRouterAddRoute(self.as_ot_ptr(), route.as_ot_ptr()) }).into()
408    }
409
410    fn add_on_mesh_prefix(&self, route: &BorderRouterConfig) -> Result {
411        Error::from(unsafe { otBorderRouterAddOnMeshPrefix(self.as_ot_ptr(), route.as_ot_ptr()) })
412            .into()
413    }
414
415    fn remove_external_route(&self, prefix: &Ip6Prefix) -> Result {
416        Error::from(unsafe { otBorderRouterRemoveRoute(self.as_ot_ptr(), prefix.as_ot_ptr()) })
417            .into()
418    }
419
420    fn remove_on_mesh_prefix(&self, prefix: &Ip6Prefix) -> Result {
421        Error::from(unsafe {
422            otBorderRouterRemoveOnMeshPrefix(self.as_ot_ptr(), prefix.as_ot_ptr())
423        })
424        .into()
425    }
426
427    fn border_router_register(&self) -> Result {
428        Error::from(unsafe { otBorderRouterRegister(self.as_ot_ptr()) }).into()
429    }
430
431    fn border_routing_init(&self, infra_if: u32, infra_is_running: bool) -> Result {
432        Error::from(unsafe { otBorderRoutingInit(self.as_ot_ptr(), infra_if, infra_is_running) })
433            .into()
434    }
435
436    fn border_routing_set_enabled(&self, enabled: bool) -> Result {
437        Error::from(unsafe { otBorderRoutingSetEnabled(self.as_ot_ptr(), enabled) }).into()
438    }
439
440    fn border_routing_dhcp6_pd_set_enabled(&self, enabled: bool) {
441        unsafe { otBorderRoutingDhcp6PdSetEnabled(self.as_ot_ptr(), enabled) }
442    }
443
444    fn border_routing_dhcp6_pd_get_state(&self) -> BorderRoutingDhcp6PdState {
445        BorderRoutingDhcp6PdState::from_isize(unsafe {
446            otBorderRoutingDhcp6PdGetState(self.as_ot_ptr())
447        } as isize)
448        .unwrap_or(BorderRoutingDhcp6PdState::Disabled)
449    }
450
451    fn border_routing_dhcp6_pd_set_request_fn<'a, F>(&'a self, f: Option<F>)
452    where
453        F: FnMut(BorderRoutingDhcp6PdState) + 'a,
454    {
455        unsafe extern "C" fn _ot_border_routing_dhcp6_pd_state_change_callback<
456            'a,
457            F: FnMut(BorderRoutingDhcp6PdState) + 'a,
458        >(
459            state: otBorderRoutingDhcp6PdState,
460            context: *mut ::std::os::raw::c_void,
461        ) {
462            trace!("_ot_border_routing_dhcp6_pd_state_change_callback");
463
464            // Convert `otBorderRoutingDhcp6PdState` to `BorderRoutingDhcp6PdState`
465            let state = BorderRoutingDhcp6PdState::from(state);
466
467            // Reconstitute a reference to our closure.
468            let sender = unsafe { &mut *(context as *mut F) };
469
470            sender(state)
471        }
472
473        let (fn_ptr, fn_box, cb): (_, _, otBorderRoutingRequestDhcp6PdCallback) = if let Some(f) = f
474        {
475            let mut x = Box::new(f);
476
477            (
478                x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
479                Some(x as Box<dyn FnMut(BorderRoutingDhcp6PdState) + 'a>),
480                Some(_ot_border_routing_dhcp6_pd_state_change_callback::<F>),
481            )
482        } else {
483            (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
484        };
485
486        unsafe {
487            otBorderRoutingDhcp6PdSetRequestCallback(self.as_ot_ptr(), cb, fn_ptr);
488
489            // Make sure our object eventually gets cleaned up.
490            // Here we must also transmute our closure to have a 'static lifetime.
491            // We need to do this because the borrow checker cannot infer the
492            // proper lifetime for the singleton instance backing, but
493            // this is guaranteed by the API.
494            self.borrow_backing().dhcp6pd_state_change_callback_fn.set(std::mem::transmute::<
495                Option<Box<dyn FnMut(BorderRoutingDhcp6PdState) + 'a>>,
496                Option<Box<dyn FnMut(BorderRoutingDhcp6PdState) + 'static>>,
497            >(fn_box));
498        }
499    }
500
501    fn border_routing_dhcp6_pd_state_change_stream(
502        &self,
503    ) -> BorderRoutingDhcp6PdStateChangedStream {
504        let state = Arc::new(Mutex::new((None, std::task::Waker::noop().clone())));
505
506        let state_copy = state.clone();
507
508        self.border_routing_dhcp6_pd_set_request_fn(Some(
509            move |pd_state: BorderRoutingDhcp6PdState| {
510                let mut borrowed = state_copy.lock();
511                borrowed.0 = Some(pd_state);
512                borrowed.1.wake_by_ref();
513            },
514        ));
515
516        BorderRoutingDhcp6PdStateChangedStream(state)
517    }
518
519    fn border_routing_get_pd_omr_prefix(&self) -> Result<ot::BorderRoutingPrefixTableEntry> {
520        let mut ret: BorderRoutingPrefixTableEntry = Default::default();
521        Error::from(unsafe {
522            otBorderRoutingGetPdOmrPrefix(self.as_ot_ptr(), ret.as_ot_mut_ptr())
523        })
524        .into_result()?;
525        Ok(ret)
526    }
527
528    fn border_routing_get_omr_prefix(&self) -> Result<ot::Ip6Prefix> {
529        let mut ret: Ip6Prefix = Default::default();
530        Error::from(unsafe { otBorderRoutingGetOmrPrefix(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
531            .into_result()?;
532        Ok(ret)
533    }
534
535    fn border_routing_get_on_link_prefix(&self) -> Result<ot::Ip6Prefix> {
536        let mut ret: Ip6Prefix = Default::default();
537        Error::from(unsafe {
538            otBorderRoutingGetOnLinkPrefix(self.as_ot_ptr(), ret.as_ot_mut_ptr())
539        })
540        .into_result()?;
541        Ok(ret)
542    }
543
544    fn border_routing_process_icmp6_ra(&self, message: &[u8]) -> Result<(), WrongSize> {
545        unsafe {
546            otPlatBorderRoutingProcessIcmp6Ra(
547                self.as_ot_ptr(),
548                message.as_ptr(),
549                message.len().try_into().map_err(|_| WrongSize)?,
550            )
551        }
552        Ok(())
553    }
554
555    fn border_routing_get_pd_processed_ra_info(&self) -> PdProcessedRaInfo {
556        let mut info = PdProcessedRaInfo::default();
557        unsafe {
558            otBorderRoutingGetPdProcessedRaInfo(self.as_ot_ptr(), info.as_ot_mut_ptr());
559        }
560        info
561    }
562
563    fn border_routing_is_multi_ail_detected(&self) -> bool {
564        unsafe { otBorderRoutingIsMultiAilDetected(self.as_ot_ptr()) }
565    }
566
567    fn border_routing_prefix_table_init_iterator(
568        &self,
569        iter: &mut otBorderRoutingPrefixTableIterator,
570    ) {
571        unsafe { otBorderRoutingPrefixTableInitIterator(self.as_ot_ptr(), iter) }
572    }
573
574    fn iter_next_local_external_route(
575        &self,
576        ot_iter: &mut otNetworkDataIterator,
577    ) -> Option<ExternalRouteConfig> {
578        unsafe {
579            let mut ret = ExternalRouteConfig::default();
580            match Error::from(otBorderRouterGetNextRoute(
581                self.as_ot_ptr(),
582                ot_iter as *mut otNetworkDataIterator,
583                ret.as_ot_mut_ptr(),
584            )) {
585                Error::NotFound => None,
586                Error::None => Some(ret),
587                err => panic!("Unexpected error from otBorderRouterGetNextRoute: {err:?}"),
588            }
589        }
590    }
591
592    fn iter_next_local_on_mesh_prefix(
593        &self,
594        ot_iter: &mut otNetworkDataIterator,
595    ) -> Option<BorderRouterConfig> {
596        unsafe {
597            let mut ret = BorderRouterConfig::default();
598            match Error::from(otBorderRouterGetNextOnMeshPrefix(
599                self.as_ot_ptr(),
600                ot_iter as *mut otNetworkDataIterator,
601                ret.as_ot_mut_ptr(),
602            )) {
603                Error::NotFound => None,
604                Error::None => Some(ret),
605                err => panic!("Unexpected error from otBorderRouterGetNextOnMeshPrefix: {err:?}"),
606            }
607        }
608    }
609
610    fn iter_next_border_routing_peer(
611        &self,
612        ot_iter: &mut otBorderRoutingPrefixTableIterator,
613    ) -> Option<BorderRoutingPeer> {
614        unsafe {
615            let mut ret = BorderRoutingPeer::default();
616            match Error::from(otBorderRoutingGetNextPeerBrEntry(
617                self.as_ot_ptr(),
618                ot_iter as *mut otBorderRoutingPrefixTableIterator,
619                ret.as_ot_mut_ptr(),
620            )) {
621                Error::NotFound => None,
622                Error::None => Some(ret),
623                err => panic!("Unexpected error from otBorderRoutingGetNextPeerBrEntry: {err:?}"),
624            }
625        }
626    }
627
628    fn iter_next_border_routing_router(
629        &self,
630        ot_iter: &mut otBorderRoutingPrefixTableIterator,
631    ) -> Option<BorderRoutingRouter> {
632        unsafe {
633            let mut ret = BorderRoutingRouter::default();
634            match Error::from(otBorderRoutingGetNextRouterEntry(
635                self.as_ot_ptr(),
636                ot_iter as *mut otBorderRoutingPrefixTableIterator,
637                ret.as_ot_mut_ptr(),
638            )) {
639                Error::NotFound => None,
640                Error::None => Some(ret),
641                err => panic!("Unexpected error from otBorderRoutingGetNextRouterEntry: {err:?}"),
642            }
643        }
644    }
645
646    fn iter_next_border_routing_prefix_table(
647        &self,
648        ot_iter: &mut otBorderRoutingPrefixTableIterator,
649    ) -> Option<BorderRoutingPrefixTableEntry> {
650        unsafe {
651            let mut ret = BorderRoutingPrefixTableEntry::default();
652            match Error::from(otBorderRoutingGetNextPrefixTableEntry(
653                self.as_ot_ptr(),
654                ot_iter as *mut otBorderRoutingPrefixTableIterator,
655                ret.as_ot_mut_ptr(),
656            )) {
657                Error::NotFound => None,
658                Error::None => Some(ret),
659                err => {
660                    panic!("Unexpected error from otBorderRoutingGetNextPrefixTableEntry: {err:?}")
661                }
662            }
663        }
664    }
665
666    fn iter_next_border_routing_rdnss(
667        &self,
668        ot_iter: &mut otBorderRoutingPrefixTableIterator,
669    ) -> Option<BorderRoutingRdnss> {
670        unsafe {
671            let mut ret = BorderRoutingRdnss::default();
672            match Error::from(otBorderRoutingGetNextRdnssAddrEntry(
673                self.as_ot_ptr(),
674                ot_iter as *mut otBorderRoutingPrefixTableIterator,
675                ret.as_ot_mut_ptr(),
676            )) {
677                Error::NotFound => None,
678                Error::None => Some(ret),
679                err => {
680                    panic!("Unexpected error from otBorderRoutingGetNextRdnssAddrEntry: {err:?}")
681                }
682            }
683        }
684    }
685}
686
687/// Stream for getting state changed events.
688#[derive(Debug, Clone)]
689pub struct BorderRoutingDhcp6PdStateChangedStream(
690    Arc<Mutex<(Option<BorderRoutingDhcp6PdState>, Waker)>>,
691);
692
693impl Stream for BorderRoutingDhcp6PdStateChangedStream {
694    type Item = BorderRoutingDhcp6PdState;
695
696    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
697        let mut state = self.0.lock();
698
699        state.1 = cx.waker().clone();
700
701        if let Some(pd_state) = state.0.take() {
702            Poll::Ready(Some(pd_state))
703        } else {
704            Poll::Pending
705        }
706    }
707}