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_traits::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;
86
87 fn ip6_send_data(&self, data: &[u8], origin: ot::message::Origin) -> Result;
97
98 fn ip6_send_data_direct(&self, data: &[u8], origin: ot::message::Origin) -> Result;
100
101 fn ip6_is_enabled(&self) -> bool;
103
104 fn ip6_set_enabled(&self, enabled: bool) -> Result;
106
107 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result;
110
111 fn ip6_remove_unicast_address(&self, addr: &Ip6Address) -> Result;
114
115 fn ip6_join_multicast_group(&self, addr: &Ip6Address) -> Result;
118
119 fn ip6_leave_multicast_group(&self, addr: &Ip6Address) -> Result;
122
123 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
129 where
130 F: FnMut(OtMessageBox<'_>) + 'a;
131
132 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
143 where
144 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a;
145
146 fn ip6_is_slaac_enabled(&self) -> bool;
148
149 fn ip6_set_slaac_enabled(&self, enabled: bool);
152
153 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode;
156
157 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode);
160
161 fn ip6_set_receive_filter_enabled(&self, enabled: bool);
164
165 fn ip6_is_receive_filter_enabled(&self) -> bool;
168
169 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters;
172
173 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_>;
176
177 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_>;
180}
181
182impl<T: Ip6 + ot::Boxable> Ip6 for ot::Box<T> {
183 fn ip6_send(&self, message: OtMessageBox<'_>) -> Result<()> {
184 self.as_ref().ip6_send(message)
185 }
186
187 fn ip6_send_data(&self, data: &[u8], origin: ot::message::Origin) -> Result {
188 self.as_ref().ip6_send_data(data, origin)
189 }
190
191 fn ip6_send_data_direct(&self, data: &[u8], origin: ot::message::Origin) -> Result {
192 self.as_ref().ip6_send_data_direct(data, origin)
193 }
194
195 fn ip6_is_enabled(&self) -> bool {
196 self.as_ref().ip6_is_enabled()
197 }
198
199 fn ip6_set_enabled(&self, enabled: bool) -> Result {
200 self.as_ref().ip6_set_enabled(enabled)
201 }
202
203 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result {
204 self.as_ref().ip6_add_unicast_address(addr)
205 }
206
207 fn ip6_remove_unicast_address(&self, addr: &std::net::Ipv6Addr) -> Result {
208 self.as_ref().ip6_remove_unicast_address(addr)
209 }
210
211 fn ip6_join_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
212 self.as_ref().ip6_join_multicast_group(addr)
213 }
214
215 fn ip6_leave_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
216 self.as_ref().ip6_join_multicast_group(addr)
217 }
218
219 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
220 where
221 F: FnMut(OtMessageBox<'_>) + 'a,
222 {
223 self.as_ref().ip6_set_receive_fn(f)
224 }
225
226 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
227 where
228 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a,
229 {
230 self.as_ref().ip6_set_address_fn(f)
231 }
232
233 fn ip6_is_slaac_enabled(&self) -> bool {
234 self.as_ref().ip6_is_slaac_enabled()
235 }
236
237 fn ip6_set_slaac_enabled(&self, enabled: bool) {
238 self.as_ref().ip6_set_slaac_enabled(enabled);
239 }
240
241 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode {
242 self.as_ref().icmp6_get_echo_mode()
243 }
244
245 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode) {
246 self.as_ref().icmp6_set_echo_mode(mode)
247 }
248
249 fn ip6_set_receive_filter_enabled(&self, enabled: bool) {
250 self.as_ref().ip6_set_receive_filter_enabled(enabled);
251 }
252
253 fn ip6_is_receive_filter_enabled(&self) -> bool {
254 self.as_ref().ip6_is_receive_filter_enabled()
255 }
256
257 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters {
258 self.as_ref().ip6_get_border_routing_counters()
259 }
260
261 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_> {
262 self.as_ref().ip6_get_unicast_addresses()
263 }
264
265 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_> {
266 self.as_ref().ip6_get_multicast_addresses()
267 }
268}
269
270impl Ip6 for Instance {
271 fn ip6_send(&self, message: OtMessageBox<'_>) -> Result {
272 if message.origin() == ot::message::Origin::ThreadNetif {
277 return Err(Error::InvalidArgs);
278 }
279 Error::from(unsafe { otIp6Send(self.as_ot_ptr(), message.take_ot_ptr()) }).into()
280 }
281
282 fn ip6_send_data(&self, data: &[u8], origin: ot::message::Origin) -> Result {
283 if origin == ot::message::Origin::ThreadNetif {
284 return Err(Error::InvalidArgs);
285 }
286 if let Ok(mut msg) = Message::ip6_new_from_bytes(self, data, None) {
287 msg.set_origin(origin);
288 self.ip6_send(msg)
289 } else if self.get_buffer_info().0.mFreeBuffers == 0 {
290 Err(ot::Error::NoBufs)
291 } else {
292 Err(ot::Error::Failed)
293 }
294 }
295
296 fn ip6_send_data_direct(&self, data: &[u8], origin: ot::message::Origin) -> Result {
297 if origin == ot::message::Origin::ThreadNetif {
298 return Err(Error::InvalidArgs);
299 }
300 if let Ok(mut msg) = Message::ip6_new_from_bytes(self, data, None) {
301 msg.set_direct_transmission(true);
302 msg.set_origin(origin);
303 self.ip6_send(msg)
304 } else if self.get_buffer_info().0.mFreeBuffers == 0 {
305 Err(ot::Error::NoBufs)
306 } else {
307 Err(ot::Error::Failed)
308 }
309 }
310
311 fn ip6_is_enabled(&self) -> bool {
312 unsafe { otIp6IsEnabled(self.as_ot_ptr()) }
313 }
314
315 fn ip6_set_enabled(&self, enabled: bool) -> Result {
316 Error::from(unsafe { otIp6SetEnabled(self.as_ot_ptr(), enabled) }).into()
317 }
318
319 fn ip6_add_unicast_address(&self, addr: &NetifAddress) -> Result {
320 Error::from(unsafe { otIp6AddUnicastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) }).into()
321 }
322
323 fn ip6_remove_unicast_address(&self, addr: &std::net::Ipv6Addr) -> Result {
324 Error::from(unsafe { otIp6RemoveUnicastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) }).into()
325 }
326
327 fn ip6_join_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
328 Error::from(unsafe { otIp6SubscribeMulticastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) })
329 .into()
330 }
331
332 fn ip6_leave_multicast_group(&self, addr: &std::net::Ipv6Addr) -> Result {
333 Error::from(unsafe { otIp6UnsubscribeMulticastAddress(self.as_ot_ptr(), addr.as_ot_ptr()) })
334 .into()
335 }
336
337 fn ip6_set_receive_fn<'a, F>(&'a self, f: Option<F>)
338 where
339 F: FnMut(OtMessageBox<'_>) + 'a,
340 {
341 unsafe extern "C" fn _ot_ip6_receive_callback<'a, F: FnMut(OtMessageBox<'_>) + 'a>(
342 message: *mut otMessage,
343 context: *mut ::std::os::raw::c_void,
344 ) {
345 trace!("_ot_ip6_receive_callback");
346
347 let message = unsafe { OtMessageBox::from_ot_ptr(message) }
349 .expect("_ot_ip6_receive_callback: Got NULL otMessage");
350
351 let sender = unsafe { &mut *(context as *mut F) };
353
354 sender(message)
355 }
356
357 let (fn_ptr, fn_box, cb): (_, _, otIp6ReceiveCallback) = if let Some(f) = f {
358 let mut x = Box::new(f);
359
360 (
361 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
362 Some(x as Box<dyn FnMut(OtMessageBox<'_>) + 'a>),
363 Some(_ot_ip6_receive_callback::<F>),
364 )
365 } else {
366 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
367 };
368
369 unsafe {
370 otIp6SetReceiveCallback(self.as_ot_ptr(), cb, fn_ptr);
371
372 self.borrow_backing().ip6_receive_fn.set(std::mem::transmute::<
378 Option<Box<dyn FnMut(OtMessageBox<'_>) + 'a>>,
379 Option<Box<dyn FnMut(OtMessageBox<'_>) + 'static>>,
380 >(fn_box));
381 }
382 }
383
384 fn ip6_set_address_fn<'a, F>(&'a self, f: Option<F>)
385 where
386 F: for<'r> FnMut(Ip6AddressInfo<'r>, bool) + 'a,
387 {
388 unsafe extern "C" fn _ot_ip6_address_callback<
389 'a,
390 F: FnMut(Ip6AddressInfo<'_>, bool) + 'a,
391 >(
392 info: *const otIp6AddressInfo,
393 is_added: bool,
394 context: *mut ::std::os::raw::c_void,
395 ) {
396 trace!("_ot_ip6_address_callback");
397
398 let info = unsafe { *Ip6AddressInfo::ref_from_ot_ptr(info).unwrap() };
400
401 let sender = unsafe { &mut *(context as *mut F) };
403
404 sender(info, is_added)
405 }
406
407 let (fn_ptr, fn_box, cb): (_, _, otIp6AddressCallback) = if let Some(f) = f {
408 let mut x = Box::new(f);
409
410 (
411 x.as_mut() as *mut F as *mut ::std::os::raw::c_void,
412 Some(x as Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'a>),
413 Some(_ot_ip6_address_callback::<F>),
414 )
415 } else {
416 (std::ptr::null_mut() as *mut ::std::os::raw::c_void, None, None)
417 };
418
419 unsafe {
420 otIp6SetAddressCallback(self.as_ot_ptr(), cb, fn_ptr);
421
422 self.borrow_backing().ip6_address_fn.set(std::mem::transmute::<
428 Option<Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'a>>,
429 Option<Box<dyn FnMut(Ip6AddressInfo<'_>, bool) + 'static>>,
430 >(fn_box));
431 }
432 }
433
434 fn ip6_is_slaac_enabled(&self) -> bool {
435 unsafe { otIp6IsSlaacEnabled(self.as_ot_ptr()) }
436 }
437
438 fn ip6_set_slaac_enabled(&self, enabled: bool) {
439 unsafe { otIp6SetSlaacEnabled(self.as_ot_ptr(), enabled) }
440 }
441
442 fn icmp6_get_echo_mode(&self) -> Icmp6EchoMode {
443 unsafe { otIcmp6GetEchoMode(self.as_ot_ptr()) }.into()
444 }
445
446 fn icmp6_set_echo_mode(&self, mode: Icmp6EchoMode) {
447 unsafe { otIcmp6SetEchoMode(self.as_ot_ptr(), mode.into()) }
448 }
449
450 fn ip6_set_receive_filter_enabled(&self, enabled: bool) {
451 unsafe { otIp6SetReceiveFilterEnabled(self.as_ot_ptr(), enabled) }
452 }
453
454 fn ip6_is_receive_filter_enabled(&self) -> bool {
455 unsafe { otIp6IsReceiveFilterEnabled(self.as_ot_ptr()) }
456 }
457
458 fn ip6_get_border_routing_counters(&self) -> &BorderRoutingCounters {
459 unsafe {
460 BorderRoutingCounters::ref_from_ot_ptr(otIp6GetBorderRoutingCounters(self.as_ot_ptr()))
461 .unwrap()
462 }
463 }
464
465 fn ip6_get_unicast_addresses(&self) -> NetifAddressIterator<'_> {
466 NetifAddressIterator(unsafe {
467 NetifAddress::ref_from_ot_ptr(otIp6GetUnicastAddresses(self.as_ot_ptr()))
468 })
469 }
470
471 fn ip6_get_multicast_addresses(&self) -> NetifMulticastAddressIterator<'_> {
472 NetifMulticastAddressIterator(unsafe {
473 NetifMulticastAddress::ref_from_ot_ptr(otIp6GetMulticastAddresses(self.as_ot_ptr()))
474 })
475 }
476}