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_multicaster_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 => panic!(
98 "Unexpected error from otBackboneRouterMulticastListenerIterator: {err:?}"
99 ),
100 }
101 }
102 }
103
104 fn set_multicast_listener_callback<'a, F>(&'a self, f: Option<F>)
105 where
106 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a,
107 {
108 unsafe extern "C" fn _ot_backbone_router_multicast_listener_callback<
109 'a,
110 F: FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a,
111 >(
112 context: *mut ::std::os::raw::c_void,
113 event: otBackboneRouterMulticastListenerEvent,
114 address: *const otIp6Address,
115 ) {
116 trace!("_ot_backbone_router_multicast_listener_callback");
117
118 let address = Ip6Address::ref_from_ot_ptr(address).unwrap();
120
121 let event = BackboneRouterMulticastListenerEvent::from(event);
124
125 let sender = &mut *(context as *mut F);
127
128 sender(event, address)
129 }
130
131 let (fn_ptr, fn_box, cb): (_, _, otBackboneRouterMulticastListenerCallback) =
132 if let Some(f) = f {
133 let mut x = Box::new(f);
134
135 (
136 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
137 Some(
138 x as Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a>,
139 ),
140 Some(_ot_backbone_router_multicast_listener_callback::<F>),
141 )
142 } else {
143 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
144 };
145
146 unsafe {
147 otBackboneRouterSetMulticastListenerCallback(self.as_ot_ptr(), cb, fn_ptr);
148
149 self.borrow_backing().multicast_listener_callback.set(std::mem::transmute::<
155 Option<Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'a>>,
156 Option<Box<dyn FnMut(BackboneRouterMulticastListenerEvent, &Ip6Address) + 'static>>,
157 >(fn_box));
158 }
159 }
160}