wlan_mlme/
probe_sequence.rs
1use rand::seq::SliceRandom;
6use wlan_common::tx_vector::{TxVecIdx, MAX_VALID_IDX, START_IDX};
7
8const NUM_PROBE_SEQUENCE: usize = 8;
9const SEQUENCE_LENGTH: usize = 1 + (MAX_VALID_IDX - START_IDX) as usize;
10
11pub struct ProbeEntry {
12 sequence_idx: usize,
13 probe_idx: usize,
14}
15
16impl Default for ProbeEntry {
17 fn default() -> Self {
18 Self { sequence_idx: NUM_PROBE_SEQUENCE - 1, probe_idx: SEQUENCE_LENGTH - 1 }
19 }
20}
21
22impl ProbeEntry {
23 pub fn cycle_complete(&self) -> bool {
24 self.probe_idx == SEQUENCE_LENGTH - 1
25 }
26}
27
28pub type ProbeTable = [[TxVecIdx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
29
30pub struct ProbeSequence {
31 probe_table: ProbeTable,
32}
33
34impl ProbeSequence {
35 pub fn sequential() -> Self {
36 let default_idx = TxVecIdx::new(START_IDX).unwrap();
38 let mut probe_table = [[default_idx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
39 for i in 0..NUM_PROBE_SEQUENCE {
40 for j in START_IDX..=MAX_VALID_IDX {
41 probe_table[i][(j - START_IDX) as usize] = TxVecIdx::new(j).unwrap();
43 }
44 }
45 Self { probe_table }
46 }
47
48 pub fn random_new() -> Self {
49 let mut rng = rand::thread_rng();
50 let default_idx = TxVecIdx::new(START_IDX).unwrap();
52 let mut probe_table = [[default_idx; SEQUENCE_LENGTH]; NUM_PROBE_SEQUENCE];
53 for i in 0..NUM_PROBE_SEQUENCE {
54 for j in START_IDX..=MAX_VALID_IDX {
55 probe_table[i][(j - START_IDX) as usize] = TxVecIdx::new(j).unwrap();
58 }
59 (&mut probe_table[i][..]).shuffle(&mut rng);
60 }
61 Self { probe_table }
62 }
63
64 pub fn next(&self, entry: &mut ProbeEntry) -> TxVecIdx {
65 entry.probe_idx = (entry.probe_idx + 1) % SEQUENCE_LENGTH;
66 if entry.probe_idx == 0 {
67 entry.sequence_idx = (entry.sequence_idx + 1) % NUM_PROBE_SEQUENCE;
68 }
69 self.probe_table[entry.sequence_idx][entry.probe_idx]
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use std::collections::HashSet;
77
78 #[test]
79 fn random_new() {
80 let probe_seq = ProbeSequence::random_new();
81 for i in 0..NUM_PROBE_SEQUENCE {
83 let seq = &probe_seq.probe_table[i];
84 let mut seen_tx_idx = HashSet::new();
85 for tx_vector_idx in seq {
86 seen_tx_idx.insert(*tx_vector_idx);
87 }
88 assert_eq!(seen_tx_idx.len(), (MAX_VALID_IDX - START_IDX + 1) as usize);
89 }
90 }
91
92 #[test]
93 fn probe_entries() {
94 let probe_seq = ProbeSequence::random_new();
95 let mut entry = ProbeEntry::default();
96 let mut seen_tx_idx = HashSet::new();
97 for _ in 0..SEQUENCE_LENGTH - 1 {
98 seen_tx_idx.insert(probe_seq.next(&mut entry));
99 assert!(!entry.cycle_complete());
100 }
101 seen_tx_idx.insert(probe_seq.next(&mut entry));
103 assert!(entry.cycle_complete());
104 assert_eq!(seen_tx_idx.len(), (MAX_VALID_IDX - START_IDX + 1) as usize);
105
106 assert!(seen_tx_idx.contains(&probe_seq.next(&mut entry)));
108 assert!(!entry.cycle_complete());
109 }
110}