openthread/ot/
backbone_router.rs1use crate::prelude_internal::*;
6
7#[allow(missing_debug_implementations)]
9pub struct MulticastListenerIterator<'a, T: ?Sized> {
10 ot_instance: &'a T,
11 ot_listener_iter: otBackboneRouterMulticastListenerIterator,
12}
13
14impl<T: ?Sized + BackboneRouter> Iterator for MulticastListenerIterator<'_, T> {
15 type Item = BackboneRouterMulticastListenerInfo;
16 fn next(&mut self) -> Option<Self::Item> {
17 self.ot_instance.multicast_listener_get_next(&mut self.ot_listener_iter)
18 }
19}
20
21pub trait BackboneRouter {
26 fn set_backbone_router_enabled(&self, enable: bool);
29
30 fn multicast_listener_get_next(
38 &self,
39 listener_iter: &mut otBackboneRouterMulticastListenerIterator,
40 ) -> Option<BackboneRouterMulticastListenerInfo>;
41
42 fn set_multicast_listener_callback<'a, F>(&'a self, f: Option<F>)
45 where
46 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a;
47
48 fn iter_multicast_listeners(&self) -> MulticastListenerIterator<'_, Self> {
50 MulticastListenerIterator {
51 ot_instance: self,
52 ot_listener_iter: OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ITERATOR_INIT
53 .try_into()
54 .unwrap(),
55 }
56 }
57}
58
59impl<T: BackboneRouter + Boxable> BackboneRouter for ot::Box<T> {
60 fn set_backbone_router_enabled(&self, enable: bool) {
61 self.as_ref().set_backbone_router_enabled(enable)
62 }
63
64 fn multicast_listener_get_next(
65 &self,
66 listener_iter: &mut otBackboneRouterMulticastListenerIterator,
67 ) -> Option<BackboneRouterMulticastListenerInfo> {
68 self.as_ref().multicast_listener_get_next(listener_iter)
69 }
70
71 fn set_multicast_listener_callback<'a, F>(&'a self, f: Option<F>)
72 where
73 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a,
74 {
75 self.as_ref().set_multicast_listener_callback(f)
76 }
77}
78
79impl BackboneRouter for Instance {
80 fn set_backbone_router_enabled(&self, enable: bool) {
81 unsafe { otBackboneRouterSetEnabled(self.as_ot_ptr(), enable) }
82 }
83
84 fn multicast_listener_get_next(
85 &self,
86 listener_iter: &mut otBackboneRouterMulticastListenerIterator,
87 ) -> Option<BackboneRouterMulticastListenerInfo> {
88 unsafe {
89 let mut ret = BackboneRouterMulticastListenerInfo::default();
90 match Error::from(otBackboneRouterMulticastListenerGetNext(
91 self.as_ot_ptr(),
92 listener_iter as *mut otBackboneRouterMulticastListenerIterator,
93 ret.as_ot_mut_ptr(),
94 )) {
95 Error::NotFound => None,
96 Error::None => Some(ret),
97 err => {
98 warn!(
101 "Unexpected error from otBackboneRouterMulticastListenerIterator: {err:?}"
102 );
103 None
104 }
105 }
106 }
107 }
108
109 fn set_multicast_listener_callback<'a, F>(&'a self, f: Option<F>)
110 where
111 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a,
112 {
113 unsafe extern "C" fn _ot_backbone_router_multicast_listener_callback<
114 'a,
115 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a,
116 >(
117 context: *mut ::std::os::raw::c_void,
118 event: otBackboneRouterMulticastListenerEvent,
119 address: *const otIp6Address,
120 ) {
121 trace!("_ot_backbone_router_multicast_listener_callback");
122
123 let address = unsafe { Ip6Address::ref_from_ot_ptr(address).unwrap() };
125
126 let event = BackboneRouterMulticastListenerEvent::from(event);
129
130 let sender = unsafe { &mut *(context as *mut F) };
132
133 sender(event, address)
134 }
135
136 let (fn_ptr, fn_box, cb): (_, _, otBackboneRouterMulticastListenerCallback) =
137 if let Some(f) = f {
138 let mut x = Box::new(f);
139
140 (
141 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
142 Some(
143 x as Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a>,
144 ),
145 Some(_ot_backbone_router_multicast_listener_callback::<F>),
146 )
147 } else {
148 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
149 };
150
151 unsafe {
152 otBackboneRouterSetMulticastListenerCallback(self.as_ot_ptr(), cb, fn_ptr);
153
154 self.borrow_backing().multicast_listener_callback.set(std::mem::transmute::<
160 Option<Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a>>,
161 Option<Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'static>>,
162 >(fn_box));
163 }
164 }
165}