Skip to content

Commit

Permalink
Bitfield and DataPath changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Frostie314159 committed Oct 24, 2023
1 parent 3ace039 commit d15a3b7
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 70 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![feature(
iter_array_chunks,
iter_next_chunk,
iter_advance_by,
exact_size_is_empty,
more_qualified_paths,
array_chunks,
Expand Down
34 changes: 27 additions & 7 deletions src/tlvs/data/data_path_state_tlv/misc.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
use bin_utils::*;
use macro_bits::{bit, bitfield};
use macro_bits::{bit, bitfield, check_bit};

#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Clone, Default, PartialEq)]
pub struct DataPathMisc {
pub struct DataPathStats {
pub msec_since_activation: u32,
pub aw_seq_counter: u32,
pub pay_update_coutner: u32,
}
#[cfg(feature = "read")]
impl ReadFixed<12> for DataPathMisc {
impl ReadFixed<12> for DataPathStats {
fn from_bytes(data: &[u8; 12]) -> Result<Self, ParserError> {
let mut data = data.iter().copied();
Ok(DataPathMisc {
Ok(DataPathStats {
msec_since_activation: u32::from_le_bytes(data.next_chunk().unwrap()),
aw_seq_counter: u32::from_le_bytes(data.next_chunk().unwrap()),
pay_update_coutner: u32::from_le_bytes(data.next_chunk().unwrap()),
})
}
}
#[cfg(feature = "write")]
impl WriteFixed<12> for DataPathMisc {
impl WriteFixed<12> for DataPathStats {
fn to_bytes(&self) -> [u8; 12] {
self.msec_since_activation
.to_le_bytes()
Expand All @@ -47,8 +47,8 @@ pub enum DataPathChannel {
ChannelMap(ChannelMap),
}
impl DataPathChannel {
pub fn from_u16(value: u16, single_channel: bool) -> Self {
if single_channel {
pub fn from_u16(value: u16) -> Self {
if !check_bit!(value, bit!(0)) {
Self::SingleChannel {
channel: value as u8,
}
Expand All @@ -63,3 +63,23 @@ impl DataPathChannel {
}
}
}
bitfield! {
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Clone, Copy, Default, PartialEq)]
pub struct UnicastOptions: u32 {
pub start_airplay: bool => bit!(1),
pub jumpstart_dfs_proxy: bool => bit!(5),
pub airplay_on_dfs_channel: bool => bit!(6),
pub start_sidecar: bool => bit!(9),
pub sidecar_bg_request: bool => bit!(10),
pub sidecar_fg_request: bool => bit!(11),
pub stop_sidecar: bool => bit!(12),
pub start_multi_peer_steering: bool => bit!(13),
pub start_real_time_mode: bool => bit!(14),
pub start_airplay_recovery: bool => bit!(16),
pub start_ht_mode: bool => bit!(17),
pub stop_ht_mode: bool => bit!(18),
pub stop_airplay: bool => bit!(19),
pub failed_multi_peer_steering: bool => bit!(20)
}
}
103 changes: 42 additions & 61 deletions src/tlvs/data/data_path_state_tlv/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
mod misc;

use core::iter::repeat;

#[cfg(feature = "read")]
use try_take::try_take;

#[cfg(feature = "write")]
use alloc::vec;
use alloc::vec::Vec;
use bin_utils::*;
use mac_parser::MACAddress;
use macro_bits::{bit, bitfield};

use crate::tlvs::{impl_tlv_conversion, TLVType};

use self::misc::DataPathChannel;
pub use self::misc::DataPathMisc;
pub use self::misc::DataPathStats;
use self::misc::{DataPathChannel, UnicastOptions};

bitfield! {
#[cfg_attr(feature = "debug", derive(Debug))]
Expand All @@ -22,12 +23,14 @@ bitfield! {
pub infra_bssid_channel: bool => bit!(0),
pub infra_address: bool => bit!(1),
pub awdl_address: bool => bit!(2),
pub umi: bool => bit!(4),
pub is_umi: bool => bit!(4),
pub dualband_support: bool => bit!(5),
pub airplay_sink: bool => bit!(6),
pub follow_channel_sequence: bool => bit!(7),
pub country_code: bool => bit!(8),
pub channel_map: bool => bit!(9),
pub airplay_solo_mode: bool => bit!(10),
pub umi_support: bool => bit!(11),
pub unicast_options: bool => bit!(12),
pub is_realtime: bool => bit!(13),
pub rangeable: bool => bit!(14),
Expand All @@ -37,14 +40,14 @@ bitfield! {
bitfield! {
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Clone, Default, PartialEq)]
struct DataPathExtendedFlags: u16 {
pub log_trigger_id: bool => bit!(0),
pub ranging_discovery: bool => bit!(1),
struct DataPathExtendedFlags: u32 {
pub ranging_discovery_supported: bool => bit!(0),
pub log_trigger_id: bool => bit!(1),
pub rlfc: bool => bit!(2),
pub channel_map_changed: bool => bit!(3),
pub sdb_active: bool => bit!(4),
pub dfs_proxy_support: bool => bit!(5),
pub misc: bool => bit!(6)
pub dynamic_sdb_active: bool => bit!(4),
pub misc: bool => bit!(5),
pub dfs_proxy_supported: bool => bit!(6),
pub high_efficiency_supported: bool => bit!(8)
}
}

Expand All @@ -57,22 +60,21 @@ pub struct DataPathStateTLV {
pub infra_bssid_channel: Option<(MACAddress, u8)>,
pub infra_address: Option<MACAddress>,
pub awdl_address: Option<MACAddress>,
pub unicast_options: Option<Vec<u8>>,
pub umi: Option<u16>,
pub unicast_options: Option<UnicastOptions>,

pub airplay_sink: bool,
pub airplay_solo_mode: bool,
pub rangeable: bool,
pub dualband_support: bool,
pub is_realtime: bool,

pub rlfc: Option<u16>,
pub log_trigger_id: Option<u32>,
pub misc: Option<DataPathMisc>,
pub rlfc: Option<u32>,
pub log_trigger_id: Option<u16>,
pub misc: Option<DataPathStats>,

pub ranging_discovery: bool,
pub sdb: bool,
pub dfs_proxy_support: bool,
pub ranging_discovery_supported: bool,
pub dynamic_sdb_supported: bool,
pub dfs_proxy_supported: bool,
}
#[cfg(feature = "read")]
impl Read for DataPathStateTLV {
Expand All @@ -91,9 +93,8 @@ impl Read for DataPathStateTLV {
data_path_state_tlv.country_code = Some(data.next_chunk().unwrap());
let _ = data.next();
}
let mut channel = None;
if flags.channel_map {
channel = <u16 as ReadCtx<&Endian>>::from_bytes(data, &Endian::Little).ok();
data_path_state_tlv.channel = Some(DataPathChannel::from_u16(<u16 as ReadCtx<&Endian>>::from_bytes(data, &Endian::Little)?));
}
if flags.infra_bssid_channel {
let mut data = try_take(data, 8).map_err(ParserError::TooLittleData)?;
Expand All @@ -119,18 +120,10 @@ impl Read for DataPathStateTLV {
)?);
}
if flags.unicast_options {
let umi_options_length = <u16 as ReadCtx<&Endian>>::from_bytes(data, &Endian::Little)?;
data_path_state_tlv.unicast_options = Some(
try_take(data, umi_options_length as usize)
.map_err(ParserError::TooLittleData)?
.collect(),
);
}
if flags.umi {
data_path_state_tlv.umi = Some(<u16 as ReadCtx<&Endian>>::from_bytes(
data,
&Endian::Little,
)?);
let _ = data.advance_by(2);
data_path_state_tlv.unicast_options = Some(UnicastOptions::from_representation(
u32::from_le_bytes(data.chain(repeat(0)).next_chunk().unwrap()),
));
}
data_path_state_tlv.airplay_sink = flags.airplay_sink;
data_path_state_tlv.airplay_solo_mode = flags.airplay_solo_mode;
Expand All @@ -139,34 +132,28 @@ impl Read for DataPathStateTLV {
data_path_state_tlv.is_realtime = flags.is_realtime;
if flags.extension_flags {
let extended_flags =
DataPathExtendedFlags::from_representation(<u16 as ReadCtx<&Endian>>::from_bytes(
DataPathExtendedFlags::from_representation(<u32 as ReadCtx<&Endian>>::from_bytes(
data,
&Endian::Little,
)?);

if let Some(channel) = channel {
data_path_state_tlv.channel = Some(DataPathChannel::from_u16(
channel,
!extended_flags.channel_map_changed,
));
}
data_path_state_tlv.ranging_discovery = extended_flags.ranging_discovery;
data_path_state_tlv.sdb = extended_flags.sdb_active;
data_path_state_tlv.dfs_proxy_support = extended_flags.dfs_proxy_support;
data_path_state_tlv.ranging_discovery_supported =
extended_flags.ranging_discovery_supported;
data_path_state_tlv.dynamic_sdb_supported = extended_flags.dynamic_sdb_active;
data_path_state_tlv.dfs_proxy_supported = extended_flags.dfs_proxy_supported;
if extended_flags.rlfc {
data_path_state_tlv.rlfc = Some(<u16 as ReadCtx<&Endian>>::from_bytes(
data_path_state_tlv.rlfc = Some(<u32 as ReadCtx<&Endian>>::from_bytes(
data,
&Endian::Little,
)?);
}
if extended_flags.log_trigger_id {
data_path_state_tlv.log_trigger_id = Some(<u32 as ReadCtx<&Endian>>::from_bytes(
data_path_state_tlv.log_trigger_id = Some(<u16 as ReadCtx<&Endian>>::from_bytes(
data,
&Endian::Little,
)?)
}
if extended_flags.misc {
data_path_state_tlv.misc = DataPathMisc::from_bytes(
data_path_state_tlv.misc = DataPathStats::from_bytes(
&try_take(data, 12)
.map_err(ParserError::TooLittleData)?
.next_chunk()
Expand Down Expand Up @@ -217,16 +204,12 @@ impl Write for DataPathStateTLV {
if let Some(unicast_options) = &self.unicast_options {
flags.unicast_options = true;
bytes.extend(
(unicast_options.len() as u16)
4u16
.to_le_bytes()
.into_iter()
.chain(unicast_options.iter().copied()),
.chain(unicast_options.to_representation().to_le_bytes()),
)
}
if let Some(umi) = self.umi {
flags.umi = true;
bytes.extend(umi.to_le_bytes());
}
flags.airplay_sink = self.airplay_sink;
flags.rangeable = self.rangeable;
flags.dualband_support = self.dualband_support;
Expand All @@ -238,7 +221,7 @@ impl Write for DataPathStateTLV {
if let Some(rlfc) = self.rlfc {
extended_flags.rlfc = true;
extended_bytes.extend(rlfc.to_le_bytes());
}
}
if let Some(log_trigger_id) = self.log_trigger_id {
extended_flags.log_trigger_id = true;
extended_bytes.extend(log_trigger_id.to_le_bytes());
Expand All @@ -247,12 +230,9 @@ impl Write for DataPathStateTLV {
extended_flags.misc = true;
extended_bytes.extend(misc.to_bytes());
}
extended_flags.ranging_discovery = self.ranging_discovery;
extended_flags.channel_map_changed = self
.channel
.is_some_and(|x| matches!(x, DataPathChannel::SingleChannel { .. }));
extended_flags.sdb_active = self.sdb;
extended_flags.dfs_proxy_support = self.dfs_proxy_support;
extended_flags.ranging_discovery_supported = self.ranging_discovery_supported;
extended_flags.dynamic_sdb_active = self.dynamic_sdb_supported;
extended_flags.dfs_proxy_supported = self.dfs_proxy_supported;
flags
.to_representation()
.to_le_bytes()
Expand All @@ -267,5 +247,6 @@ impl_tlv_conversion!(false, DataPathStateTLV, TLVType::DataPathState, 2);
#[test]
fn test_data_path_state_tlv() {
let bytes = include_bytes!("../../../../test_bins/data_path_state_tlv.bin")[3..].to_vec();
let _ = DataPathStateTLV::from_bytes(&mut bytes.iter().copied()).unwrap();
let data_path_state = DataPathStateTLV::from_bytes(&mut bytes.iter().copied()).unwrap();
panic!("{data_path_state:#?}")
}
2 changes: 1 addition & 1 deletion src/tlvs/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ mod data_path_state_tlv;
mod ht_capabilities_tlv;
mod ieee80211_cntr_tlv;

pub use data_path_state_tlv::{DataPathMisc, DataPathStateTLV};
pub use data_path_state_tlv::{DataPathStateTLV, DataPathStats};
pub use ht_capabilities_tlv::{ampdu_parameters, ht_capabilities_info, HTCapabilitiesTLV};
pub use ieee80211_cntr_tlv::IEEE80211ContainerTLV;
2 changes: 1 addition & 1 deletion src/tlvs/sync_elect/channel_sequence_tlv/channel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use macro_bits::{serializable_enum, bitfield, bit};
use macro_bits::{bit, bitfield, serializable_enum};

serializable_enum! {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down
Binary file modified test_bins/data_path_state_tlv.bin
Binary file not shown.

0 comments on commit d15a3b7

Please sign in to comment.