wlan_common/mac/
frame_class.rs
1use crate::mac;
6use zerocopy::SplitByteSlice;
7
8#[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Ord, Eq)]
9pub enum FrameClass {
10 Class1 = 1,
11 Class2 = 2,
12 Class3 = 3,
13}
14
15impl<B: SplitByteSlice> From<&mac::MacFrame<B>> for FrameClass {
17 fn from(mac_frame: &mac::MacFrame<B>) -> FrameClass {
18 frame_class(&mac_frame.frame_ctrl())
19 }
20}
21
22pub fn frame_class(fc: &mac::FrameControl) -> FrameClass {
32 match fc.frame_type() {
34 mac::FrameType::CTRL => match fc.ctrl_subtype() {
35 mac::CtrlSubtype::RTS
38 | mac::CtrlSubtype::CTS
39 | mac::CtrlSubtype::ACK
40 | mac::CtrlSubtype::CF_END
41 | mac::CtrlSubtype::CF_END_ACK => return FrameClass::Class1,
42 _ => (),
43 },
44 mac::FrameType::MGMT => match fc.mgmt_subtype() {
45 mac::MgmtSubtype::ACTION
46 | mac::MgmtSubtype::PROBE_REQ
47 | mac::MgmtSubtype::PROBE_RESP
48 | mac::MgmtSubtype::BEACON
49 | mac::MgmtSubtype::AUTH
50 | mac::MgmtSubtype::DEAUTH
51 | mac::MgmtSubtype::ATIM => return FrameClass::Class1,
52 _ => (),
53 },
54 _ => (),
55 };
56
57 if let mac::FrameType::MGMT = fc.frame_type() {
60 match fc.mgmt_subtype() {
61 mac::MgmtSubtype::ASSOC_REQ
62 | mac::MgmtSubtype::ASSOC_RESP
63 | mac::MgmtSubtype::REASSOC_REQ
64 | mac::MgmtSubtype::REASSOC_RESP
65 | mac::MgmtSubtype::DISASSOC => return FrameClass::Class2,
66 _ => (),
67 }
68 };
69
70 FrameClass::Class3
71}
72
73pub fn action_frame_class(category: mac::ActionCategory) -> FrameClass {
75 match category {
76 mac::ActionCategory::PUBLIC | mac::ActionCategory::SELF_PROTECTED => FrameClass::Class1,
78 _ => FrameClass::Class3,
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn mgmt_frame_class() {
89 let mut fc = mac::FrameControl(0)
91 .with_frame_type(mac::FrameType::MGMT)
92 .with_mgmt_subtype(mac::MgmtSubtype::BEACON);
93 assert_eq!(FrameClass::Class1, frame_class(&fc));
94 fc.set_mgmt_subtype(mac::MgmtSubtype::AUTH);
95 assert_eq!(FrameClass::Class1, frame_class(&fc));
96 fc.set_mgmt_subtype(mac::MgmtSubtype::DEAUTH);
97 assert_eq!(FrameClass::Class1, frame_class(&fc));
98 fc.set_mgmt_subtype(mac::MgmtSubtype::PROBE_REQ);
99 assert_eq!(FrameClass::Class1, frame_class(&fc));
100 fc.set_mgmt_subtype(mac::MgmtSubtype::PROBE_RESP);
101 assert_eq!(FrameClass::Class1, frame_class(&fc));
102 fc.set_mgmt_subtype(mac::MgmtSubtype::ATIM);
103 assert_eq!(FrameClass::Class1, frame_class(&fc));
104 fc.set_mgmt_subtype(mac::MgmtSubtype::ACTION);
105 assert_eq!(FrameClass::Class1, frame_class(&fc));
106
107 fc.set_mgmt_subtype(mac::MgmtSubtype::ASSOC_REQ);
109 assert_eq!(FrameClass::Class2, frame_class(&fc));
110 fc.set_mgmt_subtype(mac::MgmtSubtype::ASSOC_RESP);
111 assert_eq!(FrameClass::Class2, frame_class(&fc));
112 fc.set_mgmt_subtype(mac::MgmtSubtype::REASSOC_REQ);
113 assert_eq!(FrameClass::Class2, frame_class(&fc));
114 fc.set_mgmt_subtype(mac::MgmtSubtype::REASSOC_RESP);
115 assert_eq!(FrameClass::Class2, frame_class(&fc));
116 fc.set_mgmt_subtype(mac::MgmtSubtype::DISASSOC);
117 assert_eq!(FrameClass::Class2, frame_class(&fc));
118
119 fc.set_mgmt_subtype(mac::MgmtSubtype::TIMING_AD);
121 assert_eq!(FrameClass::Class3, frame_class(&fc));
122 fc.set_mgmt_subtype(mac::MgmtSubtype::ACTION_NO_ACK);
123 assert_eq!(FrameClass::Class3, frame_class(&fc));
124 }
125
126 #[test]
127 fn data_frame_class() {
128 let fc = mac::FrameControl(0).with_frame_type(mac::FrameType::DATA);
130 assert_eq!(FrameClass::Class3, frame_class(&fc));
131 }
132
133 #[test]
134 fn ctrl_frame_class() {
135 let mut fc = mac::FrameControl(0)
137 .with_frame_type(mac::FrameType::CTRL)
138 .with_ctrl_subtype(mac::CtrlSubtype::ACK);
139 assert_eq!(FrameClass::Class1, frame_class(&fc));
140 fc.set_ctrl_subtype(mac::CtrlSubtype::RTS);
141 assert_eq!(FrameClass::Class1, frame_class(&fc));
142 fc.set_ctrl_subtype(mac::CtrlSubtype::CTS);
143 assert_eq!(FrameClass::Class1, frame_class(&fc));
144
145 fc.set_ctrl_subtype(mac::CtrlSubtype::PS_POLL);
147 assert_eq!(FrameClass::Class3, frame_class(&fc));
148 fc.set_ctrl_subtype(mac::CtrlSubtype::BLOCK_ACK);
149 assert_eq!(FrameClass::Class3, frame_class(&fc));
150 fc.set_ctrl_subtype(mac::CtrlSubtype::BLOCK_ACK_REQ);
151 assert_eq!(FrameClass::Class3, frame_class(&fc));
152 }
153
154 #[test]
155 fn action_frames() {
156 assert_eq!(FrameClass::Class1, action_frame_class(mac::ActionCategory::PUBLIC));
158 assert_eq!(FrameClass::Class1, action_frame_class(mac::ActionCategory::SELF_PROTECTED));
159
160 assert_eq!(FrameClass::Class3, action_frame_class(mac::ActionCategory::BLOCK_ACK));
162 assert_eq!(FrameClass::Class3, action_frame_class(mac::ActionCategory::MESH));
163 }
164}