1use crate::prelude_internal::*;
6
7#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
9pub enum Icmp6EchoMode {
10 HandleAll = OT_ICMP6_ECHO_HANDLER_ALL as isize,
12
13 HandleDisabled = OT_ICMP6_ECHO_HANDLER_DISABLED as isize,
15
16 HandleMulticastOnly = OT_ICMP6_ECHO_HANDLER_MULTICAST_ONLY as isize,
18
19 HandleUnicastOnly = OT_ICMP6_ECHO_HANDLER_UNICAST_ONLY as isize,
21
22 HandleRlocAlocOnly = OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY as isize,
24}
25
26impl From<otIcmp6EchoMode> for Icmp6EchoMode {
27 fn from(x: otIcmp6EchoMode) -> Self {
28 use num::FromPrimitive;
29 Self::from_u32(x).unwrap_or_else(|| panic!("Unknown otIcmp6EchoMode value: {x}"))
30 }
31}
32
33impl From<Icmp6EchoMode> for otIcmp6EchoMode {
34 fn from(x: Icmp6EchoMode) -> Self {
35 x as otIcmp6EchoMode
36 }
37}
38
39#[derive(Default, Debug, Clone)]
41pub struct NetifAddressIterator<'a>(Option<&'a NetifAddress>);
42
43impl<'a> Iterator for NetifAddressIterator<'a> {
44 type Item = &'a NetifAddress;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 if let Some(addr_ref) = self.0 {
48 self.0 = unsafe { NetifAddress::ref_from_ot_ptr(addr_ref.0.mNext) };
52 Some(addr_ref)
53 } else {
54 None
55 }
56 }
57}
58
59#[derive(Default, Debug, Clone)]
61pub struct NetifMulticastAddressIterator<'a>(Option<&'a NetifMulticastAddress>);
62
63impl<'a> Iterator for NetifMulticastAddressIterator<'a> {
64 type Item = &'a NetifMulticastAddress;
65
66 fn next(&mut self) -> Option<Self::Item> {
67 if let Some(addr_ref) = self.0 {
68 self.0 = unsafe { NetifMulticastAddress::ref_from_ot_ptr(addr_ref.0.mNext) };
72 Some(addr_ref)
73 } else {
74 None
75 }
76 }
77}
78
79pub trait Ip6 {
81 fn ip6_send(&self, message: OtMessageBox<'_>) -> Result;
83
84 fn ip6_send_data(&self, data: &[u8]) -> Result;
87
88 fn ip6_send_data_direct(&self, data: &[u8]) -> Result;
90
91 fn ip6_is_enabled(&self) -> bool;
93
94 fn ip6_set_enabled(&self, enabled: bool) -> Result;
96
97 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result;
100
101 fn ip6_remove_unicast_address(&self, addr: &Ip6Address) -> Result;
104
105 fn ip6_join_multicast_group(&self, addr: &Ip6Address) -> Result;
108
109 fn ip6_leave_multicast_group(&self, addr: &Ip6Address) -> Result;
112
113 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
119 where
120 F: FnMut(OtMessageBox<'_>) + 'a;
121
122 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
133 where
134 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a;
135
136 fn ip6_is_slaac_enabled(&self) -> bool;
138
139 fn ip6_set_slaac_enabled(&self, enabled: bool);
142
143 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode;
146
147 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode);
150
151 fn ip6_set_receive_filter_enabled(&self, enabled: bool);
154
155 fn ip6_is_receive_filter_enabled(&self) -> bool;
158
159 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters;
162
163 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_>;
166
167 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_>;
170}
171
172impl<T: Ip6 + ot::Boxable> Ip6 for ot::Box<T> {
173 fn ip6_send(&self, message: OtMessageBox<'_>) -> Result<()> {
174 self.as_ref().ip6_send(message)
175 }
176
177 fn ip6_send_data(&self, data: &[u8]) -> Result {
178 self.as_ref().ip6_send_data(data)
179 }
180
181 fn ip6_send_data_direct(&self, data: &[u8]) -> Result {
182 self.as_ref().ip6_send_data_direct(data)
183 }
184
185 fn ip6_is_enabled(&self) -> bool {
186 self.as_ref().ip6_is_enabled()
187 }
188
189 fn ip6_set_enabled(&self, enabled: bool) -> Result {
190 self.as_ref().ip6_set_enabled(enabled)
191 }
192
193 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result {
194 self.as_ref().ip6_add_unicast_address(addr)
195 }
196
197 fn ip6_remove_unicast_address(&self, addr: &std::net::Ipv6Addr) -> Result {
198 self.as_ref().ip6_remove_unicast_address(addr)
199 }
200
201 fn ip6_join_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
202 self.as_ref().ip6_join_multicast_group(addr)
203 }
204
205 fn ip6_leave_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
206 self.as_ref().ip6_join_multicast_group(addr)
207 }
208
209 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
210 where
211 F: FnMut(OtMessageBox<'_>) + 'a,
212 {
213 self.as_ref().ip6_set_receive_fn(f)
214 }
215
216 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
217 where
218 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a,
219 {
220 self.as_ref().ip6_set_address_fn(f)
221 }
222
223 fn ip6_is_slaac_enabled(&self) -> bool {
224 self.as_ref().ip6_is_slaac_enabled()
225 }
226
227 fn ip6_set_slaac_enabled(&self, enabled: bool) {
228 self.as_ref().ip6_set_slaac_enabled(enabled);
229 }
230
231 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode {
232 self.as_ref().icmp6_get_echo_mode()
233 }
234
235 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode) {
236 self.as_ref().icmp6_set_echo_mode(mode)
237 }
238
239 fn ip6_set_receive_filter_enabled(&self, enabled: bool) {
240 self.as_ref().ip6_set_receive_filter_enabled(enabled);
241 }
242
243 fn ip6_is_receive_filter_enabled(&self) -> bool {
244 self.as_ref().ip6_is_receive_filter_enabled()
245 }
246
247 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters {
248 self.as_ref().ip6_get_border_routing_counters()
249 }
250
251 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_> {
252 self.as_ref().ip6_get_unicast_addresses()
253 }
254
255 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_> {
256 self.as_ref().ip6_get_multicast_addresses()
257 }
258}
259
260impl Ip6 for Instance {
261 fn ip6_send(&self, message: OtMessageBox<'_>) -> Result {
262 Error::from(unsafe { otIp6Send(self.as_ot_ptr(), message.take_ot_ptr()) }).into()
263 }
264
265 fn ip6_send_data(&self, data: &[u8]) -> Result {
266 if let Ok(msg) = Message::ip6_new_from_bytes(self, data, None) {
267 self.ip6_send(msg)
268 } else if self.get_buffer_info().0.mFreeBuffers == 0 {
269 Err(ot::Error::NoBufs)
270 } else {
271 Err(ot::Error::Failed)
272 }
273 }
274
275 fn ip6_send_data_direct(&self, data: &[u8]) -> Result {
276 if let Ok(mut msg) = Message::ip6_new_from_bytes(self, data, None) {
277 msg.set_direct_transmission(true);
278 self.ip6_send(msg)
279 } else if self.get_buffer_info().0.mFreeBuffers == 0 {
280 Err(ot::Error::NoBufs)
281 } else {
282 Err(ot::Error::Failed)
283 }
284 }
285
286 fn ip6_is_enabled(&self) -> bool {
287 unsafe { otIp6IsEnabled(self.as_ot_ptr()) }
288 }
289
290 fn ip6_set_enabled(&self, enabled: bool) -> Result {
291 Error::from(unsafe { otIp6SetEnabled(self.as_ot_ptr(), enabled) }).into()
292 }
293
294 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result {
295 Error::from(unsafe { otIp6AddUnicastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) }).into()
296 }
297
298 fn ip6_remove_unicast_address(&self, addr: &std::net::Ipv6Addr) -> Result {
299 Error::from(unsafe { otIp6RemoveUnicastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) }).into()
300 }
301
302 fn ip6_join_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
303 Error::from(unsafe { otIp6SubscribeMulticastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) })
304 .into()
305 }
306
307 fn ip6_leave_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
308 Error::from(unsafe { otIp6UnsubscribeMulticastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) })
309 .into()
310 }
311
312 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
313 where
314 F: FnMut(OtMessageBox<'_>) + 'a,
315 {
316 unsafe extern "C" fn _ot_ip6_receive_callback<'a, F: FnMut(OtMessageBox<'_>) + 'a>(
317 message: *mut otMessage,
318 context: *mut ::std::os::raw::c_void,
319 ) {
320 trace!("_ot_ip6_receive_callback");
321
322 let message = unsafe { OtMessageBox::from_ot_ptr(message) }
324 .expect("_ot_ip6_receive_callback: Got NULL otMessage");
325
326 let sender = unsafe { &mut *(context as *mut F) };
328
329 sender(message)
330 }
331
332 let (fn_ptr, fn_box, cb): (_, _, otIp6ReceiveCallback) = if let Some(f) = f {
333 let mut x = Box::new(f);
334
335 (
336 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
337 Some(x as Box<dyn FnMut(OtMessageBox<'_>) + 'a>),
338 Some(_ot_ip6_receive_callback::<F>),
339 )
340 } else {
341 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
342 };
343
344 unsafe {
345 otIp6SetReceiveCallback(self.as_ot_ptr(), cb, fn_ptr);
346
347 self.borrow_backing().ip6_receive_fn.set(std::mem::transmute::<
353 Option<Box<dyn FnMut(OtMessageBox<'_>) + 'a>>,
354 Option<Box<dyn FnMut(OtMessageBox<'_>) + 'static>>,
355 >(fn_box));
356 }
357 }
358
359 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
360 where
361 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a,
362 {
363 unsafe extern "C" fn _ot_ip6_address_callback<
364 'a,
365 F: FnMut(Ip6AddressInfo<'_>, bool) + 'a,
366 >(
367 info: *const otIp6AddressInfo,
368 is_added: bool,
369 context: *mut ::std::os::raw::c_void,
370 ) {
371 trace!("_ot_ip6_address_callback");
372
373 let info = unsafe { *Ip6AddressInfo::ref_from_ot_ptr(info).unwrap() };
375
376 let sender = unsafe { &mut *(context as *mut F) };
378
379 sender(info, is_added)
380 }
381
382 let (fn_ptr, fn_box, cb): (_, _, otIp6AddressCallback) = if let Some(f) = f {
383 let mut x = Box::new(f);
384
385 (
386 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
387 Some(x as Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'a>),
388 Some(_ot_ip6_address_callback::<F>),
389 )
390 } else {
391 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
392 };
393
394 unsafe {
395 otIp6SetAddressCallback(self.as_ot_ptr(), cb, fn_ptr);
396
397 self.borrow_backing().ip6_address_fn.set(std::mem::transmute::<
403 Option<Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'a>>,
404 Option<Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'static>>,
405 >(fn_box));
406 }
407 }
408
409 fn ip6_is_slaac_enabled(&self) -> bool {
410 unsafe { otIp6IsSlaacEnabled(self.as_ot_ptr()) }
411 }
412
413 fn ip6_set_slaac_enabled(&self, enabled: bool) {
414 unsafe { otIp6SetSlaacEnabled(self.as_ot_ptr(), enabled) }
415 }
416
417 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode {
418 unsafe { otIcmp6GetEchoMode(self.as_ot_ptr()) }.into()
419 }
420
421 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode) {
422 unsafe { otIcmp6SetEchoMode(self.as_ot_ptr(), mode.into()) }
423 }
424
425 fn ip6_set_receive_filter_enabled(&self, enabled: bool) {
426 unsafe { otIp6SetReceiveFilterEnabled(self.as_ot_ptr(), enabled) }
427 }
428
429 fn ip6_is_receive_filter_enabled(&self) -> bool {
430 unsafe { otIp6IsReceiveFilterEnabled(self.as_ot_ptr()) }
431 }
432
433 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters {
434 unsafe {
435 BorderRoutingCounters::ref_from_ot_ptr(otIp6GetBorderRoutingCounters(self.as_ot_ptr()))
436 .unwrap()
437 }
438 }
439
440 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_> {
441 NetifAddressIterator(unsafe {
442 NetifAddress::ref_from_ot_ptr(otIp6GetUnicastAddresses(self.as_ot_ptr()))
443 })
444 }
445
446 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_> {
447 NetifMulticastAddressIterator(unsafe {
448 NetifMulticastAddress::ref_from_ot_ptr(otIp6GetMulticastAddresses(self.as_ot_ptr()))
449 })
450 }
451}