wlan_common/
sequence.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use ieee80211::MacAddr;
6use std::collections::HashMap;
7
8const SEQ_START_NUM: SequenceNum = 1;
9pub type SequenceNum = u32;
10
11/// IEEE Std 802.11-2016, 10.3.2.11.2, 10.3.2.11.3
12/// A specific Sequence Number Space such as SNS1, SNS2, etc.
13/// A STA owns multiple of such SNS maps, each of which holds
14/// sequence numbers for its peers.
15struct 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
51/// Manages all SNS for a STA.
52pub 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    // Sns3 optional
78
79    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        // Arbitrary value by spec. Increment to assist debugging.
85        self.sns5 = (self.sns5 + 1) % 4096;
86        self.sns5
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use lazy_static::lazy_static;
94
95    lazy_static! {
96        static ref FIRST_PEER: MacAddr = MacAddr::from([1; 6]);
97        static ref SECOND_PEER: MacAddr = MacAddr::from([2; 6]);
98    }
99
100    #[test]
101    fn sns1_next() {
102        let mut seq_mgr = SequenceManager::new();
103
104        for i in 0..4095 {
105            let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
106            assert_eq!(i + 1, seq_num);
107        }
108
109        let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
110        assert_eq!(0, seq_num); // wrapped
111
112        let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
113        assert_eq!(0 + 1, seq_num);
114    }
115
116    #[test]
117    fn sns1_next_multiple_peers() {
118        let mut seq_mgr = SequenceManager::new();
119
120        seq_mgr.next_sns1(&FIRST_PEER);
121        seq_mgr.next_sns1(&FIRST_PEER);
122        let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
123        assert_eq!(3, seq_num);
124
125        seq_mgr.next_sns1(&SECOND_PEER);
126        let seq_num = seq_mgr.next_sns1(&SECOND_PEER);
127        assert_eq!(2, seq_num);
128
129        let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
130        assert_eq!(4, seq_num);
131    }
132
133    #[test]
134    fn sns2_next_multiple_tids() {
135        let mut seq_mgr = SequenceManager::new();
136
137        seq_mgr.next_sns2(&FIRST_PEER, 0);
138        seq_mgr.next_sns2(&FIRST_PEER, 0);
139        let seq_num = seq_mgr.next_sns2(&&FIRST_PEER, 0);
140        assert_eq!(3, seq_num);
141
142        seq_mgr.next_sns2(&FIRST_PEER, 1);
143        let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 1);
144        assert_eq!(2, seq_num);
145
146        let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 0);
147        assert_eq!(4, seq_num);
148    }
149
150    #[test]
151    fn sns4_next_multiple_acis() {
152        let mut seq_mgr = SequenceManager::new();
153
154        seq_mgr.next_sns4(&FIRST_PEER, 0);
155        seq_mgr.next_sns4(&FIRST_PEER, 0);
156        let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 0);
157        assert_eq!(3, seq_num);
158
159        seq_mgr.next_sns4(&FIRST_PEER, 1);
160        let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 1);
161        assert_eq!(2, seq_num);
162
163        let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 0);
164        assert_eq!(4, seq_num);
165    }
166
167    #[test]
168    fn sns1_sns2_sns4_next() {
169        let mut seq_mgr = SequenceManager::new();
170
171        seq_mgr.next_sns1(&FIRST_PEER);
172        seq_mgr.next_sns1(&FIRST_PEER);
173        let seq_num = seq_mgr.next_sns1(&FIRST_PEER);
174        assert_eq!(3, seq_num);
175
176        seq_mgr.next_sns2(&FIRST_PEER, 0);
177        let seq_num = seq_mgr.next_sns2(&FIRST_PEER, 0);
178        assert_eq!(2, seq_num);
179
180        let seq_num = seq_mgr.next_sns4(&FIRST_PEER, 3);
181        assert_eq!(1, seq_num);
182    }
183}