wlan_mlme/
probe_sequence.rsuse rand::seq::SliceRandom;
use wlan_common::tx_vector::{TxVecIdx, MAX_VALID_IDX, START_IDX};
const NUM_PROBE_SEQUENCE: usize = 8;
const SEQUENCE_LENGTH: usize = 1 + (MAX_VALID_IDX - START_IDX) as usize;
pub struct ProbeEntry {
sequence_idx: usize,
probe_idx: usize,
}
impl Default for ProbeEntry {
fn default() -> Self {
Self { sequence_idx: NUM_PROBE_SEQUENCE - 1, probe_idx: SEQUENCE_LENGTH - 1 }
}
}
impl ProbeEntry {
pub fn cycle_complete(&self) -> bool {
self.probe_idx == SEQUENCE_LENGTH - 1
}
}
pub type ProbeTable = [[TxVecIdx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
pub struct ProbeSequence {
probe_table: ProbeTable,
}
impl ProbeSequence {
pub fn sequential() -> Self {
let default_idx = TxVecIdx::new(START_IDX).unwrap();
let mut probe_table = [[default_idx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
for i in 0..NUM_PROBE_SEQUENCE {
for j in START_IDX..=MAX_VALID_IDX {
probe_table[i][(j - START_IDX) as usize] = TxVecIdx::new(j).unwrap();
}
}
Self { probe_table }
}
pub fn random_new() -> Self {
let mut rng = rand::thread_rng();
let default_idx = TxVecIdx::new(START_IDX).unwrap();
let mut probe_table = [[default_idx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
for i in 0..NUM_PROBE_SEQUENCE {
for j in START_IDX..=MAX_VALID_IDX {
probe_table[i][(j - START_IDX) as usize] = TxVecIdx::new(j).unwrap();
}
(&mut probe_table[i][..]).shuffle(&mut rng);
}
Self { probe_table }
}
pub fn next(&self, entry: &mut ProbeEntry) -> TxVecIdx {
entry.probe_idx = (entry.probe_idx + 1) % SEQUENCE_LENGTH;
if entry.probe_idx == 0 {
entry.sequence_idx = (entry.sequence_idx + 1) % NUM_PROBE_SEQUENCE;
}
self.probe_table[entry.sequence_idx][entry.probe_idx]
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn random_new() {
let probe_seq = ProbeSequence::random_new();
for i in 0..NUM_PROBE_SEQUENCE {
let seq = &probe_seq.probe_table[i];
let mut seen_tx_idx = HashSet::new();
for tx_vector_idx in seq {
seen_tx_idx.insert(*tx_vector_idx);
}
assert_eq!(seen_tx_idx.len(), (MAX_VALID_IDX - START_IDX + 1) as usize);
}
}
#[test]
fn probe_entries() {
let probe_seq = ProbeSequence::random_new();
let mut entry = ProbeEntry::default();
let mut seen_tx_idx = HashSet::new();
for _ in 0..SEQUENCE_LENGTH - 1 {
seen_tx_idx.insert(probe_seq.next(&mut entry));
assert!(!entry.cycle_complete());
}
seen_tx_idx.insert(probe_seq.next(&mut entry));
assert!(entry.cycle_complete());
assert_eq!(seen_tx_idx.len(), (MAX_VALID_IDX - START_IDX + 1) as usize);
assert!(seen_tx_idx.contains(&probe_seq.next(&mut entry)));
assert!(!entry.cycle_complete());
}
}