wlan_common/stats/
signal.rs
1use crate::energy::*;
6
7const N: usize = 20;
10
11#[derive(Debug)]
13pub struct SignalStrengthAverage {
14 sum: FemtoWatt,
15 samples: [DecibelMilliWatt; N],
16 n: usize,
17 i: usize,
18}
19
20impl SignalStrengthAverage {
21 pub fn new() -> Self {
22 Self { sum: FemtoWatt(0), n: 0, i: 0, samples: [DecibelMilliWatt(std::i8::MIN); N] }
23 }
24
25 pub fn avg_dbm(&self) -> DecibelMilliWatt {
26 self.avg_femto_watt().into()
27 }
28
29 pub fn avg_femto_watt(&self) -> FemtoWatt {
30 FemtoWatt(match self.n {
31 0 => 0,
32 _ => self.sum.0 / (self.n as u64),
33 })
34 }
35
36 pub fn add(&mut self, dbm: DecibelMilliWatt) {
37 if self.n < N {
38 self.n += 1;
39 } else {
40 self.sum -= self.samples[self.i].into();
41 }
42 self.sum += dbm.into();
43 self.samples[self.i] = dbm;
44 self.i = (self.i + 1) % N;
45 }
46
47 pub fn reset(&mut self) {
48 self.n = 0;
49 self.sum = FemtoWatt(0);
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
61 fn avg() {
62 let mut signal_avg = SignalStrengthAverage::new();
63 for dbm_abs in (21..=30).rev() {
66 let dbm = -dbm_abs;
67 print!("{} + ", FemtoWatt::from(DecibelMilliWatt(dbm)).0);
68 signal_avg.add(DecibelMilliWatt(dbm));
69 }
70 assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(3_421_503_488));
73 assert_eq!(signal_avg.avg_dbm(), FemtoWatt(3_421_503_488).into());
74
75 for dbm_abs in (11..=20).rev() {
78 let dbm = -dbm_abs;
79 print!("{} + ", FemtoWatt::from(DecibelMilliWatt(dbm)).0);
80 signal_avg.add(DecibelMilliWatt(dbm));
81 }
82 assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(18_811_768_012));
85 assert_eq!(signal_avg.avg_dbm(), FemtoWatt(18_811_768_012).into());
86
87 for dbm_abs in (1..=10).rev() {
90 let dbm = -dbm_abs;
91 signal_avg.add(DecibelMilliWatt(dbm));
92 }
93 assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(187_852_809_830));
96 assert_eq!(signal_avg.avg_dbm(), FemtoWatt(187_852_809_830).into());
97 }
98
99 #[fuchsia::test]
100 fn reset() {
101 let mut signal_avg = SignalStrengthAverage::new();
102 for dbm_abs in 1..=30 {
104 let dbm = -dbm_abs;
105 signal_avg.add(DecibelMilliWatt(dbm));
106 }
107 signal_avg.reset();
108
109 assert_eq!(signal_avg.avg_dbm(), DecibelMilliWatt(-128));
110 assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(0));
111
112 signal_avg.add(DecibelMilliWatt(-30));
113 assert_eq!(signal_avg.avg_dbm(), DecibelMilliWatt(-30));
114 assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(983_564_288));
115 }
116}