hal::wifi
Wi-Fi station abstraction — the contract both radio backends satisfy.
FlintOS is growing two ways to be a Wi-Fi station, and this is the seam between them and the application:
- The blob backend (
radio/esp32): Espressif’s binary radio driver plus a supplicant. It works only on the ESP32 and pulls in vendor binaries, so it is an opt-in (“unsafe”) build. - The pure-Rust backend (later, in
drivers/): a first-party supplicant overcryptoand a radio driver trait, portable to any FlintOS target.
Both implement [Station]. An application says “join this network” against
the trait and does not know or care which backend answers — exactly as a
logical driver talks to Bus without knowing which
controller is underneath. The trait lives in hal for that reason: hal
is contracts and nothing else, and api re-exports it so a driver crate
(which may name api but not hal) can still implement it.
Asynchronous by nature
Section titled “Asynchronous by nature”Associating is not a function that returns when it is done — it is a
request, and the answer arrives later. [Station::connect] returns as soon
as the attempt is accepted; whether it succeeded comes back as a
[StationEvent::Connected] or [StationEvent::Disconnected] through the
handler the caller registered. Scanning is the same. This matches how the
driver actually behaves and avoids pretending a two-second, failure-prone
radio exchange is a blocking call.
Structs
Section titled “Structs”ApInfo
Section titled “ApInfo”struct ApInfo { pub ssid: Ssid, pub bssid: Bssid, pub channel: u8, pub rssi: i8, pub security: Security,}One access point a scan turned up.
Implements: Clone, Copy, Debug
References: Bssid, Security, Ssid
ConnectRequest
Section titled “ConnectRequest”struct ConnectRequest<'a> { pub ssid: Ssid, pub security: Security, pub credentials: Credentials<'a>, pub bssid: Option<Bssid>, pub channel: Option<u8>,}What to connect to.
Implements: Clone, Copy
References: Bssid, Credentials, Security, Ssid
ScanRequest
Section titled “ScanRequest”struct ScanRequest { pub ssid: Option<Ssid>, pub channel: Option<u8>, pub passive: bool,}How to scan.
Implements: Clone, Copy, Default
References: Ssid
struct Ssid { /* private fields */ }A network name.
Held as bytes and a length, not a string, because an SSID is octets and is not required to be UTF-8 — a station that could only join UTF-8 networks would be quietly broken in parts of the world.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
StationStatus
Section titled “StationStatus”struct StationStatus { pub state: StationState, pub ssid: Option<Ssid>, pub bssid: Option<Bssid>, pub channel: u8, pub rssi: i8, pub security: Security,}A live view of the station, read synchronously at any time.
Implements: Clone, Copy, Debug
References: Bssid, Security, Ssid, StationState
Credentials
Section titled “Credentials”enum Credentials<'a> { None, Passphrase(&'a [u8]), Psk([u8; 32]),}What a station presents to join a network.
Borrowed rather than owned: a passphrase lives in the caller’s memory for the moment of the connect call and should not be copied into a long-lived struct that outlives its usefulness.
Implements: Clone, Copy
DisconnectReason
Section titled “DisconnectReason”enum DisconnectReason { Unspecified, NoApFound, AuthFailed, AssocFailed, FourWayTimeout, HandshakeTimeout, ConnectionLost, AssocExpired, NotAssociated, Requested,}Why a station is not, or is no longer, connected.
A generalisation of the reason codes every driver reports, kept small and
meaningful rather than mirroring 802.11’s fifty-odd. The distinction that
matters to an application is whose fault and whether retrying helps:
a wrong passphrase (AuthFailed) will never succeed on
retry, a missing AP (NoApFound) might.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
Security
Section titled “Security”enum Security { Open, Wpa2Psk, Wpa3Sae, Wpa2Wpa3Psk,}The security a network uses, or a station asks for.
Deliberately small to start: the personal (pre-shared-key) modes that cover the overwhelming majority of networks. WPA3-only, enterprise/EAP and the legacy WEP modes are named as future work rather than half-supported — a security enum that lists a mode it cannot actually join is a lie the application would act on.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
StationEvent
Section titled “StationEvent”enum StationEvent { ScanDone { count: u16 }, Connected { bssid: Bssid, channel: u8 }, Disconnected { reason: DisconnectReason },}Something the station is telling the application about.
Delivered through the handler registered with
[Station::set_event_handler], on whatever task the backend dispatches
events on — never in an interrupt. Small and Copy so it can cross that
boundary by value.
Implements: Clone, Copy, Debug
References: Bssid, DisconnectReason
StationState
Section titled “StationState”enum StationState { Disconnected, Connecting, Connected,}Where the station is in the connect lifecycle.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
WifiError
Section titled “WifiError”enum WifiError { NotReady, BadCredentials, Busy, NotConnected, Backend(i32),}Why a station operation could not even be started.
Distinct from [DisconnectReason]: these are refusals at the call, before
the radio does anything — a malformed request, or the wrong state. The
outcome of an accepted request arrives as a [StationEvent], not here.
Implements: Clone, Copy, Debug, Display, Eq, From, PartialEq, StructuralPartialEq
Traits
Section titled “Traits”Station
Section titled “Station”trait Station { fn scan(&mut self, request: &ScanRequest) -> WifiResult<()> fn scan_results(&mut self, out: &mut [ApInfo]) -> WifiResult<usize> fn connect(&mut self, request: &ConnectRequest<'_>) -> WifiResult<()> fn disconnect(&mut self) -> WifiResult<()> fn status(&self) -> StationStatus fn set_event_handler(&mut self, handler: Option<EventHandler>) -> Option<EventHandler>}A Wi-Fi station: the operations an application performs to be on a network.
Every method that involves the air is initiating, not completing — see
the module docs. A backend implements this; an application holds a &mut dyn Station and does not know which one.
Constants
Section titled “Constants”SSID_MAX
Section titled “SSID_MAX”const SSID_MAX: usize;The largest an SSID may be: 32 octets (IEEE 802.11).
Type Aliases
Section titled “Type Aliases”type Bssid = [u8; 6];A BSSID — the MAC address of an access point.
EventHandler
Section titled “EventHandler”type EventHandler = fn(..);The handler an application registers to hear [StationEvent]s.
A plain fn, not a closure, because it runs on the backend’s event task
and must carry no borrowed environment across that boundary — the same
constraint the existing radio event dispatch has.
WifiResult
Section titled “WifiResult”type WifiResult<T> = Result<T, WifiError>;The result of a station operation.
References: WifiError