1use 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#[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#[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#[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#[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#[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#[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
97pub trait BorderRouter {
101 fn add_external_route(&self, route: &ExternalRouteConfig) -> Result;
104
105 fn add_on_mesh_prefix(&self, route: &BorderRouterConfig) -> Result;
108
109 fn remove_external_route(&self, prefix: &Ip6Prefix) -> Result;
112
113 fn remove_on_mesh_prefix(&self, prefix: &Ip6Prefix) -> Result;
116
117 fn border_router_register(&self) -> Result;
120
121 fn border_routing_init(&self, infra_if: u32, infra_is_running: bool) -> Result;
124
125 fn border_routing_set_enabled(&self, enabled: bool) -> Result;
128
129 fn border_routing_dhcp6_pd_set_enabled(&self, enabled: bool);
132
133 fn border_routing_dhcp6_pd_get_state(&self) -> BorderRoutingDhcp6PdState;
136
137 fn border_routing_dhcp6_pd_set_request_fn<'a, F>(&'a self, f: Option<F>)
141 where
142 F: FnMut(BorderRoutingDhcp6PdState) + 'a;
143
144 fn border_routing_dhcp6_pd_state_change_stream(&self)
146 -> BorderRoutingDhcp6PdStateChangedStream;
147
148 fn border_routing_get_pd_omr_prefix(&self) -> Result<ot::BorderRoutingPrefixTableEntry>;
151
152 fn border_routing_get_omr_prefix(&self) -> Result<ot::Ip6Prefix>;
155
156 fn border_routing_get_on_link_prefix(&self) -> Result<ot::Ip6Prefix>;
159
160 fn border_routing_process_icmp6_ra(&self, message: &[u8]) -> Result<(), WrongSize>;
164
165 fn border_routing_get_pd_processed_ra_info(&self) -> PdProcessedRaInfo;
169
170 fn border_routing_is_multi_ail_detected(&self) -> bool;
174
175 fn border_routing_prefix_table_init_iterator(
179 &self,
180 iter: &mut otBorderRoutingPrefixTableIterator,
181 );
182
183 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 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 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 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 fn iter_next_local_external_route(
221 &self,
222 ot_iter: &mut otNetworkDataIterator,
223 ) -> Option<ExternalRouteConfig>;
224
225 fn iter_next_local_on_mesh_prefix(
234 &self,
235 ot_iter: &mut otNetworkDataIterator,
236 ) -> Option<BorderRouterConfig>;
237
238 fn iter_next_border_routing_peer(
242 &self,
243 ot_iter: &mut otBorderRoutingPrefixTableIterator,
244 ) -> Option<BorderRoutingPeer>;
245
246 fn iter_next_border_routing_router(
250 &self,
251 ot_iter: &mut otBorderRoutingPrefixTableIterator,
252 ) -> Option<BorderRoutingRouter>;
253
254 fn iter_next_border_routing_prefix_table(
258 &self,
259 ot_iter: &mut otBorderRoutingPrefixTableIterator,
260 ) -> Option<BorderRoutingPrefixTableEntry>;
261
262 fn iter_next_border_routing_rdnss(
266 &self,
267 ot_iter: &mut otBorderRoutingPrefixTableIterator,
268 ) -> Option<BorderRoutingRdnss>;
269
270 fn iter_local_external_routes(&self) -> LocalExternalRouteIterator<'_, Self> {
272 LocalExternalRouteIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
273 }
274
275 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 let state = BorderRoutingDhcp6PdState::from(state);
466
467 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 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#[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}