ndn_faces/l2/
neighbor.rs

1use super::af_packet::MacAddr;
2use ndn_packet::Name;
3use ndn_transport::FaceId;
4use std::collections::HashMap;
5
6/// A discovered neighbor and its per-radio face bindings.
7#[derive(Clone, Debug)]
8pub struct NeighborEntry {
9    /// NDN node name of the neighbor.
10    pub node_name: Name,
11    /// Per-radio face bindings: each entry is (FaceId, MAC, interface).
12    pub radio_faces: Vec<(FaceId, MacAddr, String)>,
13    /// Timestamp of last successful hello (ns since Unix epoch).
14    pub last_seen: u64,
15}
16
17/// Neighbor discovery task.
18///
19/// Sends a broadcast hello Interest, captures the UDP/Ethernet source address
20/// of each responding neighbor, creates a unicast `NamedEtherFace` per peer,
21/// and maintains the neighbor table.
22///
23/// The broadcast rate is kept minimal — just enough for initial bootstrap and
24/// re-discovery after mobility events. All subsequent traffic uses per-neighbor
25/// unicast faces at full 802.11 rate adaptation.
26pub struct NeighborDiscovery {
27    neighbors: HashMap<Name, NeighborEntry>,
28}
29
30impl NeighborDiscovery {
31    pub fn new() -> Self {
32        Self {
33            neighbors: HashMap::new(),
34        }
35    }
36
37    pub fn neighbors(&self) -> impl Iterator<Item = &NeighborEntry> {
38        self.neighbors.values()
39    }
40
41    pub fn get(&self, name: &Name) -> Option<&NeighborEntry> {
42        self.neighbors.get(name)
43    }
44
45    pub fn upsert(&mut self, entry: NeighborEntry) {
46        self.neighbors.insert(entry.node_name.clone(), entry);
47    }
48
49    pub fn remove(&mut self, name: &Name) {
50        self.neighbors.remove(name);
51    }
52}
53
54impl Default for NeighborDiscovery {
55    fn default() -> Self {
56        Self::new()
57    }
58}