From 8e6b5919b0875d5c4359bb90b356d4ed5bfea065 Mon Sep 17 00:00:00 2001 From: Juraj Sadel Date: Mon, 22 Sep 2025 17:50:31 +0200 Subject: [PATCH] esp-radio: Wrap C types that are needed fot pub API (#4148) --- esp-radio/src/wifi/event.rs | 87 ++++++++++++++++++++++++++++++++++--- esp-radio/src/wifi/mod.rs | 3 ++ 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/esp-radio/src/wifi/event.rs b/esp-radio/src/wifi/event.rs index af76d2864..8f807bc14 100644 --- a/esp-radio/src/wifi/event.rs +++ b/esp-radio/src/wifi/event.rs @@ -281,6 +281,22 @@ impl StaDisconnected<'_> { } } +/// All AP credentials received from WPS handshake. +#[repr(transparent)] +pub struct ApCredential(wifi_event_sta_wps_er_success_t__bindgen_ty_1); + +impl ApCredential { + /// Get the SSID of an AP. + pub fn ssid(&self) -> &[u8] { + &self.0.ssid + } + + /// Get passphrase for the AP. + pub fn passphrase(&self) -> &[u8] { + &self.0.passphrase + } +} + impl StaAuthmodeChange<'_> { /// Get the old authentication mode. pub fn old_mode(&self) -> u32 { @@ -300,8 +316,12 @@ impl StaWpsErSuccess<'_> { } /// Get all AP credentials received. - pub fn ap_cred(&self) -> &[wifi_event_sta_wps_er_success_t__bindgen_ty_1] { - &self.0.ap_cred + pub fn ap_cred(&self) -> &[ApCredential] { + let array_ref: &[ApCredential; 3] = + // cast reference of fixed-size array to wrapper type + unsafe { &*(&self.0.ap_cred as *const _ as *const [ApCredential; 3]) }; + + &array_ref[..] } } @@ -312,6 +332,47 @@ impl StaWpsErPin<'_> { } } +/// A safe, read-only wrapper for a single FTM report entry. +#[repr(transparent)] +pub struct FtmReportEntry<'a>(&'a wifi_ftm_report_entry_t); + +impl FtmReportEntry<'_> { + /// Gets the Dialog Token of the FTM frame. + pub fn dialog_token(&self) -> u8 { + self.0.dlog_token + } + + /// Gets the Received Signal Strength Indicator (RSSI) of the FTM frame. + pub fn rssi(&self) -> i8 { + self.0.rssi + } + + /// Gets the Round Trip Time (RTT) in picoseconds. + pub fn rtt(&self) -> u32 { + self.0.rtt + } + + /// Gets T1: Time of departure of the FTM frame from the Responder (in picoseconds). + pub fn t1(&self) -> u64 { + self.0.t1 + } + + /// Gets T2: Time of arrival of the FTM frame at the Initiator (in picoseconds). + pub fn t2(&self) -> u64 { + self.0.t2 + } + + /// Gets T3: Time of departure of the ACK from the Initiator (in picoseconds). + pub fn t3(&self) -> u64 { + self.0.t3 + } + + /// Gets T4: Time of arrival of the ACK at the Responder (in picoseconds). + pub fn t4(&self) -> u64 { + self.0.t4 + } +} + impl FtmReport<'_> { /// Get the MAC address of the FTM peer. pub fn peer_mac(&self) -> &[u8] { @@ -338,15 +399,27 @@ impl FtmReport<'_> { self.0.dist_est } - /// Get Pointer to FTM Report, should be freed after use. - pub fn report_data(&self) -> *mut wifi_ftm_report_entry_t { - self.0.ftm_report_data - } - /// Get the number of entries in the FTM report data. pub fn report_num_entries(&self) -> u8 { self.0.ftm_report_num_entries } + + /// Returns an iterator over the detailed FTM report entries. + pub fn entries(&self) -> impl Iterator> + '_ { + let ptr = self.0.ftm_report_data; + let len = self.0.ftm_report_num_entries as usize; + + // Return an empty slice when there are no entries. + let entries_slice = if ptr.is_null() || len == 0 { + &[] + } else { + // Otherwise, it's the slice from the data. + // Can we trust the C API to provide a valid pointer and length? + unsafe { core::slice::from_raw_parts(ptr, len) } + }; + + entries_slice.iter().map(FtmReportEntry) + } } impl ApProbeReqReceived<'_> { diff --git a/esp-radio/src/wifi/mod.rs b/esp-radio/src/wifi/mod.rs index 571dfcfef..068de0a0d 100644 --- a/esp-radio/src/wifi/mod.rs +++ b/esp-radio/src/wifi/mod.rs @@ -909,6 +909,7 @@ impl TryFrom<&Config> for WifiMode { } } +#[doc(hidden)] impl TryFrom for WifiMode { type Error = WifiError; @@ -924,6 +925,7 @@ impl TryFrom for WifiMode { } } +#[doc(hidden)] impl From for wifi_mode_t { fn from(val: WifiMode) -> Self { #[allow(non_upper_case_globals)] @@ -1048,6 +1050,7 @@ impl Default for CsiConfig { } } +#[doc(hidden)] #[cfg(feature = "csi")] impl From for wifi_csi_config_t { fn from(config: CsiConfig) -> Self {