xref: /aosp_15_r20/tools/netsim/rust/daemon/src/wifi/frame.rs (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::wifi::hwsim_attr_set::HwsimAttrSet;
16 use anyhow::Context;
17 use netsim_packets::ieee80211::{Ieee80211, MacAddress};
18 use netsim_packets::mac80211_hwsim::{HwsimCmd, HwsimMsg, TxRate};
19 use pdl_runtime::Packet;
20 
21 /// Parser for the hwsim Frame command (HWSIM_CMD_FRAME).
22 ///
23 /// The Frame command is sent by the kernel's mac80211_hwsim subsystem
24 /// and contains the IEEE 802.11 frame along with hwsim attributes.
25 ///
26 /// This module parses the required and optional hwsim attributes and
27 /// returns errors if any required attributes are missing.
28 
29 // The Frame struct contains parsed attributes along with the raw and
30 // parsed 802.11 frame in `data` and `ieee80211.`
31 #[derive(Debug)]
32 pub struct Frame {
33     pub transmitter: Option<MacAddress>,
34     pub flags: Option<u32>,
35     pub tx_info: Option<Vec<TxRate>>,
36     pub cookie: Option<u64>,
37     pub signal: Option<u32>,
38     pub freq: Option<u32>,
39     pub data: Vec<u8>,
40     pub ieee80211: Ieee80211,
41     pub hwsim_msg: HwsimMsg,
42     pub attrs: HwsimAttrSet,
43 }
44 
45 impl Frame {
46     // Builds and validates the Frame from the attributes in the
47     // packet. Called when a hwsim packet with HwsimCmd::Frame is
48     // found.
parse(msg: &HwsimMsg) -> anyhow::Result<Frame>49     pub fn parse(msg: &HwsimMsg) -> anyhow::Result<Frame> {
50         // Only expected to be called with HwsimCmd::Frame
51         if msg.hwsim_hdr.hwsim_cmd != HwsimCmd::Frame {
52             panic!("Invalid hwsim_cmd");
53         }
54         let attrs = HwsimAttrSet::parse(&msg.attributes).context("HwsimAttrSet")?;
55         let frame = attrs.frame.clone().context("Frame")?;
56         let ieee80211 = Ieee80211::decode_full(&frame).context("Ieee80211")?;
57         // Required attributes are unwrapped and return an error if
58         // they are not present.
59         Ok(Frame {
60             transmitter: attrs.transmitter,
61             flags: attrs.flags,
62             tx_info: attrs.tx_info.clone(),
63             cookie: attrs.cookie,
64             signal: attrs.signal,
65             freq: attrs.freq,
66             data: frame,
67             ieee80211,
68             hwsim_msg: msg.clone(),
69             attrs,
70         })
71     }
72 }
73