1use ieee80211::MacAddr;
6use std::collections::HashMap;
7
8const SEQ_START_NUM: SequenceNum = 1;
9pub type SequenceNum = u32;
10
11struct SnsMap<K> {
16 inner: HashMap<K, SequenceNum>,
17 modulo_divisor: SequenceNum,
18}
19
20impl<K: std::hash::Hash + Eq + Clone> SnsMap<K> {
21 pub fn new(modulo_divisor: SequenceNum) -> Self {
22 Self { inner: HashMap::new(), modulo_divisor }
23 }
24
25 pub fn next(&mut self, key: &K) -> SequenceNum {
26 match self.inner.get_mut(key) {
27 None => {
28 self.inner.insert(key.clone(), SEQ_START_NUM);
29 SEQ_START_NUM
30 }
31 Some(seq) => {
32 *seq = (*seq + 1) % self.modulo_divisor;
33 *seq
34 }
35 }
36 }
37}
38
39#[derive(Hash, PartialEq, Eq, Clone)]
40struct Sns2Key {
41 sta_addr: MacAddr,
42 tid: u16,
43}
44
45#[derive(Hash, PartialEq, Eq, Clone)]
46struct Sns4Key {
47 sta_addr: MacAddr,
48 aci: u8,
49}
50
51pub struct SequenceManager {
53 sns1: SnsMap<MacAddr>,
54 sns2: SnsMap<Sns2Key>,
55 sns4: SnsMap<Sns4Key>,
56 sns5: u32,
57}
58
59impl SequenceManager {
60 pub fn new() -> Self {
61 Self {
62 sns1: SnsMap::new(4096),
63 sns2: SnsMap::new(4096),
64 sns4: SnsMap::new(1024),
65 sns5: SEQ_START_NUM,
66 }
67 }
68
69 pub fn next_sns1(&mut self, sta_addr: &MacAddr) -> SequenceNum {
70 self.sns1.next(sta_addr)
71 }
72
73 pub fn next_sns2(&mut self, sta_addr: &MacAddr, tid: u16) -> SequenceNum {
74 self.sns2.next(&Sns2Key { sta_addr: sta_addr.clone(), tid })
75 }
76
77 pub fn next_sns4(&mut self, sta_addr: &MacAddr, aci: u8) -> SequenceNum {
80 self.sns4.next(&Sns4Key { sta_addr: sta_addr.clone(), aci })
81 }
82
83 pub fn next_sns5(&mut self) -> SequenceNum {
84 self.sns5 = (self.sns5 + 1) % 4096;
86 self.sns5
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use std::sync::LazyLock;
94
95 static FIRST_PEER: LazyLock<MacAddr> = LazyLock::new(|| MacAddr::from([1; 6]));
96 static SECOND_PEER: LazyLock<MacAddr> = LazyLock::new(|| MacAddr::from([2; 6]));
97
98 #[test]
99 fn sns1_next() {
100 let mut seq_mgr = SequenceManager::new();
101
102 for i in 0..4095 {
103 let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
104 assert_eq!(i + 1, seq_num);
105 }
106
107 let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
108 assert_eq!(0, seq_num); let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
111 assert_eq!(0 + 1, seq_num);
112 }
113
114 #[test]
115 fn sns1_next_multiple_peers() {
116 let mut seq_mgr = SequenceManager::new();
117
118 seq_mgr.next_sns1(&FIRST_PEER);
119 seq_mgr.next_sns1(&FIRST_PEER);
120 let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
121 assert_eq!(3, seq_num);
122
123 seq_mgr.next_sns1(&SECOND_PEER);
124 let seq_num = seq_mgr.next_sns1(&SECOND_PEER);
125 assert_eq!(2, seq_num);
126
127 let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
128 assert_eq!(4, seq_num);
129 }
130
131 #[test]
132 fn sns2_next_multiple_tids() {
133 let mut seq_mgr = SequenceManager::new();
134
135 seq_mgr.next_sns2(&FIRST_PEER, 0);
136 seq_mgr.next_sns2(&FIRST_PEER, 0);
137 let seq_num = seq_mgr.next_sns2(&&FIRST_PEER, 0);
138 assert_eq!(3, seq_num);
139
140 seq_mgr.next_sns2(&FIRST_PEER, 1);
141 let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 1);
142 assert_eq!(2, seq_num);
143
144 let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 0);
145 assert_eq!(4, seq_num);
146 }
147
148 #[test]
149 fn sns4_next_multiple_acis() {
150 let mut seq_mgr = SequenceManager::new();
151
152 seq_mgr.next_sns4(&FIRST_PEER, 0);
153 seq_mgr.next_sns4(&FIRST_PEER, 0);
154 let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 0);
155 assert_eq!(3, seq_num);
156
157 seq_mgr.next_sns4(&FIRST_PEER, 1);
158 let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 1);
159 assert_eq!(2, seq_num);
160
161 let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 0);
162 assert_eq!(4, seq_num);
163 }
164
165 #[test]
166 fn sns1_sns2_sns4_next() {
167 let mut seq_mgr = SequenceManager::new();
168
169 seq_mgr.next_sns1(&FIRST_PEER);
170 seq_mgr.next_sns1(&FIRST_PEER);
171 let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
172 assert_eq!(3, seq_num);
173
174 seq_mgr.next_sns2(&FIRST_PEER, 0);
175 let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 0);
176 assert_eq!(2, seq_num);
177
178 let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 3);
179 assert_eq!(1, seq_num);
180 }
181}