Skip to main content

prns_runtime/runtime/packet_phy_retention/
mod.rs

1mod fixed;
2#[cfg(feature = "alloc")]
3mod heap;
4#[cfg(test)]
5mod tests;
6
7use core::num::NonZeroUsize;
8
9use crate::interfaces::{PacketPhyStats, RssiDbm, SignalQualityTenthsPercent, SnrQuarterDb};
10use crate::routing::dedup::PacketHash;
11
12pub use fixed::{fixed_packet_phy_retention, FixedPacketMetricStorage, FixedPacketPhyRetention};
13#[cfg(feature = "alloc")]
14pub use heap::{HeapPacketMetricStorage, HeapPacketPhyRetention, RNS_1_4_2_PACKET_PHY_CAPACITY};
15
16pub trait PacketMetricStorage {
17    type Metric: Copy;
18
19    fn capacity(&self) -> NonZeroUsize;
20    fn len(&self) -> usize;
21    fn is_empty(&self) -> bool {
22        self.len() == 0
23    }
24    fn append(&mut self, packet_hash: PacketHash, metric: Self::Metric);
25    fn replace(&mut self, slot: usize, packet_hash: PacketHash, metric: Self::Metric);
26    fn get(&self, packet_hash: PacketHash) -> Option<Self::Metric>;
27}
28
29struct PacketMetricRetention<Storage> {
30    storage: Storage,
31    next_evict: usize,
32}
33
34impl<Storage: PacketMetricStorage> PacketMetricRetention<Storage> {
35    const fn new(storage: Storage) -> Self {
36        Self {
37            storage,
38            next_evict: 0,
39        }
40    }
41
42    fn remember(&mut self, packet_hash: PacketHash, metric: Storage::Metric) {
43        let capacity = self.storage.capacity().get();
44        if self.storage.len() < capacity {
45            self.storage.append(packet_hash, metric);
46            return;
47        }
48        let slot = self.next_evict;
49        self.storage.replace(slot, packet_hash, metric);
50        self.next_evict = (self.next_evict + 1) % capacity;
51    }
52
53    fn get(&self, packet_hash: PacketHash) -> Option<Storage::Metric> {
54        self.storage.get(packet_hash)
55    }
56}
57
58pub struct PacketPhyRetention<RssiStorage, SnrStorage, QualityStorage> {
59    rssi: PacketMetricRetention<RssiStorage>,
60    snr: PacketMetricRetention<SnrStorage>,
61    quality: PacketMetricRetention<QualityStorage>,
62}
63
64impl<RssiStorage, SnrStorage, QualityStorage>
65    PacketPhyRetention<RssiStorage, SnrStorage, QualityStorage>
66where
67    RssiStorage: PacketMetricStorage<Metric = RssiDbm>,
68    SnrStorage: PacketMetricStorage<Metric = SnrQuarterDb>,
69    QualityStorage: PacketMetricStorage<Metric = SignalQualityTenthsPercent>,
70{
71    pub const fn from_storages(
72        rssi: RssiStorage,
73        snr: SnrStorage,
74        quality: QualityStorage,
75    ) -> Self {
76        Self {
77            rssi: PacketMetricRetention::new(rssi),
78            snr: PacketMetricRetention::new(snr),
79            quality: PacketMetricRetention::new(quality),
80        }
81    }
82
83    pub fn remember(&mut self, packet_hash: PacketHash, stats: PacketPhyStats) {
84        if let Some(rssi) = stats.rssi {
85            self.rssi.remember(packet_hash, rssi);
86        }
87        if let Some(snr) = stats.snr {
88            self.snr.remember(packet_hash, snr);
89        }
90        if let Some(quality) = stats.quality {
91            self.quality.remember(packet_hash, quality);
92        }
93    }
94
95    pub fn get(&self, packet_hash: PacketHash) -> Option<PacketPhyStats> {
96        let stats = PacketPhyStats {
97            rssi: self.rssi.get(packet_hash),
98            snr: self.snr.get(packet_hash),
99            quality: self.quality.get(packet_hash),
100        };
101        (!stats.is_empty()).then_some(stats)
102    }
103}
104
105impl<RssiStorage, SnrStorage, QualityStorage> Default
106    for PacketPhyRetention<RssiStorage, SnrStorage, QualityStorage>
107where
108    RssiStorage: Default + PacketMetricStorage<Metric = RssiDbm>,
109    SnrStorage: Default + PacketMetricStorage<Metric = SnrQuarterDb>,
110    QualityStorage: Default + PacketMetricStorage<Metric = SignalQualityTenthsPercent>,
111{
112    fn default() -> Self {
113        Self::from_storages(
114            RssiStorage::default(),
115            SnrStorage::default(),
116            QualityStorage::default(),
117        )
118    }
119}