wlan_common/
wmm.rs
1use crate::mac;
6
7pub fn derive_tid(ether_type: u16, payload: &[u8]) -> Option<u8> {
12 if ether_type == mac::ETHER_TYPE_IPV4 || ether_type == mac::ETHER_TYPE_IPV6 {
13 return get_ds_field(ether_type, payload).map(|ds| dscp_to_up(ds >> 2));
15 }
16 None
17}
18
19pub fn dscp_to_up(dscp: u8) -> u8 {
23 match dscp {
24 0b110000 | 0b111000 => 7,
26 0b101110 => 6,
28 0b101100 => 6,
30 0b101000 => 5,
32 0b100010 | 0b100100 | 0b100110 => 4,
34 0b100000 => 4,
36 0b011010 | 0b011100 | 0b011110 => 4,
38 0b011000 => 4,
40 0b010010 | 0b010100 | 0b010110 => 3,
42 0b001000 => 1,
44 _ => 0,
46 }
47}
48
49fn get_ds_field(ether_type: u16, payload: &[u8]) -> Option<u8> {
50 if payload.len() < 2 {
51 return None;
52 }
53 match ether_type {
54 mac::ETHER_TYPE_IPV4 => Some(payload[1]),
55 mac::ETHER_TYPE_IPV6 => Some(((payload[0] & 0x0f) << 4) | ((payload[1] & 0xf0) >> 4)),
56 _ => None,
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_derive_tid_ipv4() {
66 let tid = derive_tid(mac::ETHER_TYPE_IPV4, &[0xff, 0b10110000]);
67 assert_eq!(tid, Some(6));
68 }
69
70 #[test]
71 fn test_derive_tid_ipv6() {
72 let tid = derive_tid(mac::ETHER_TYPE_IPV6, &[0b11110101, 0b10000000]);
73 assert_eq!(tid, Some(3));
74 }
75
76 #[test]
77 fn test_derive_tid_payload_too_short() {
78 assert!(derive_tid(mac::ETHER_TYPE_IPV4, &[0xff]).is_none());
79 }
80
81 #[test]
82 fn test_dscp_to_up() {
83 assert_eq!(dscp_to_up(0b110000), 7);
84 assert_eq!(dscp_to_up(0b010000), 0);
86 assert_eq!(dscp_to_up(0b001010), 0);
87 assert_eq!(dscp_to_up(0b001100), 0);
88 assert_eq!(dscp_to_up(0b001110), 0);
89 assert_eq!(dscp_to_up(0b001110), 0);
90 assert_eq!(dscp_to_up(0b000000), 0);
91
92 assert_eq!(dscp_to_up(0b111110), 0);
94 }
95}