wlan_common/stats/
signal.rsuse crate::energy::*;
const N: usize = 20;
#[derive(Debug)]
pub struct SignalStrengthAverage {
sum: FemtoWatt,
samples: [DecibelMilliWatt; N],
n: usize,
i: usize,
}
impl SignalStrengthAverage {
pub fn new() -> Self {
Self { sum: FemtoWatt(0), n: 0, i: 0, samples: [DecibelMilliWatt(std::i8::MIN); N] }
}
pub fn avg_dbm(&self) -> DecibelMilliWatt {
self.avg_femto_watt().into()
}
pub fn avg_femto_watt(&self) -> FemtoWatt {
FemtoWatt(match self.n {
0 => 0,
_ => self.sum.0 / (self.n as u64),
})
}
pub fn add(&mut self, dbm: DecibelMilliWatt) {
if self.n < N {
self.n += 1;
} else {
self.sum -= self.samples[self.i].into();
}
self.sum += dbm.into();
self.samples[self.i] = dbm;
self.i = (self.i + 1) % N;
}
pub fn reset(&mut self) {
self.n = 0;
self.sum = FemtoWatt(0);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn avg() {
let mut signal_avg = SignalStrengthAverage::new();
for dbm_abs in (21..=30).rev() {
let dbm = -dbm_abs;
print!("{} + ", FemtoWatt::from(DecibelMilliWatt(dbm)).0);
signal_avg.add(DecibelMilliWatt(dbm));
}
assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(3_421_503_488));
assert_eq!(signal_avg.avg_dbm(), FemtoWatt(3_421_503_488).into());
for dbm_abs in (11..=20).rev() {
let dbm = -dbm_abs;
print!("{} + ", FemtoWatt::from(DecibelMilliWatt(dbm)).0);
signal_avg.add(DecibelMilliWatt(dbm));
}
assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(18_811_768_012));
assert_eq!(signal_avg.avg_dbm(), FemtoWatt(18_811_768_012).into());
for dbm_abs in (1..=10).rev() {
let dbm = -dbm_abs;
signal_avg.add(DecibelMilliWatt(dbm));
}
assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(187_852_809_830));
assert_eq!(signal_avg.avg_dbm(), FemtoWatt(187_852_809_830).into());
}
#[fuchsia::test]
fn reset() {
let mut signal_avg = SignalStrengthAverage::new();
for dbm_abs in 1..=30 {
let dbm = -dbm_abs;
signal_avg.add(DecibelMilliWatt(dbm));
}
signal_avg.reset();
assert_eq!(signal_avg.avg_dbm(), DecibelMilliWatt(-128));
assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(0));
signal_avg.add(DecibelMilliWatt(-30));
assert_eq!(signal_avg.avg_dbm(), DecibelMilliWatt(-30));
assert_eq!(signal_avg.avg_femto_watt(), FemtoWatt(983_564_288));
}
}