smoltcp/iface/
socket_meta.rs1use super::SocketHandle;
2use crate::{
3 socket::PollAt,
4 time::{Duration, Instant},
5 wire::IpAddress,
6};
7
8#[derive(Debug, Default)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14enum NeighborState {
15 #[default]
17 Active,
18 Waiting {
21 neighbor: IpAddress,
22 silent_until: Instant,
23 },
24}
25
26#[derive(Debug, Default)]
32#[cfg_attr(feature = "defmt", derive(defmt::Format))]
33pub(crate) struct Meta {
34 pub(crate) handle: SocketHandle,
37 neighbor_state: NeighborState,
39}
40
41impl Meta {
42 pub(crate) const DISCOVERY_SILENT_TIME: Duration = Duration::from_millis(1_000);
47
48 pub(crate) fn poll_at<F>(&self, socket_poll_at: PollAt, has_neighbor: F) -> PollAt
49 where
50 F: Fn(IpAddress) -> bool,
51 {
52 match self.neighbor_state {
53 NeighborState::Active => socket_poll_at,
54 NeighborState::Waiting { neighbor, .. } if has_neighbor(neighbor) => socket_poll_at,
55 NeighborState::Waiting { silent_until, .. } => PollAt::Time(silent_until),
56 }
57 }
58
59 pub(crate) fn egress_permitted<F>(&mut self, timestamp: Instant, has_neighbor: F) -> bool
60 where
61 F: Fn(IpAddress) -> bool,
62 {
63 match self.neighbor_state {
64 NeighborState::Active => true,
65 NeighborState::Waiting {
66 neighbor,
67 silent_until,
68 } => {
69 if has_neighbor(neighbor) {
70 net_trace!(
71 "{}: neighbor {} discovered, unsilencing",
72 self.handle,
73 neighbor
74 );
75 self.neighbor_state = NeighborState::Active;
76 true
77 } else if timestamp >= silent_until {
78 net_trace!(
79 "{}: neighbor {} silence timer expired, rediscovering",
80 self.handle,
81 neighbor
82 );
83 true
84 } else {
85 false
86 }
87 }
88 }
89 }
90
91 pub(crate) fn neighbor_missing(&mut self, timestamp: Instant, neighbor: IpAddress) {
92 net_trace!(
93 "{}: neighbor {} missing, silencing until t+{}",
94 self.handle,
95 neighbor,
96 Self::DISCOVERY_SILENT_TIME
97 );
98 self.neighbor_state = NeighborState::Waiting {
99 neighbor,
100 silent_until: timestamp + Self::DISCOVERY_SILENT_TIME,
101 };
102 }
103}