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