Skip to main content

wlan_sme/
lib.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Turn on additional lints that could lead to unexpected crashes in production code
6#![warn(clippy::indexing_slicing)]
7#![cfg_attr(test, allow(clippy::indexing_slicing))]
8#![warn(clippy::unwrap_used)]
9#![cfg_attr(test, allow(clippy::unwrap_used))]
10#![warn(clippy::expect_used)]
11#![cfg_attr(test, allow(clippy::expect_used))]
12#![warn(clippy::unreachable)]
13#![cfg_attr(test, allow(clippy::unreachable))]
14#![warn(clippy::unimplemented)]
15#![cfg_attr(test, allow(clippy::unimplemented))]
16
17pub mod ap;
18pub mod client;
19pub mod serve;
20#[cfg(test)]
21pub mod test_utils;
22
23use fidl_fuchsia_wlan_common as fidl_common;
24use fidl_fuchsia_wlan_ieee80211 as fidl_ieee80211;
25use fidl_fuchsia_wlan_mlme::{self as fidl_mlme, MlmeEvent};
26use fidl_fuchsia_wlan_stats as fidl_stats;
27use futures::channel::mpsc;
28use thiserror::Error;
29use wlan_common::sink::UnboundedSink;
30use wlan_common::timer;
31
32#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
33pub struct Config {
34    pub wep_supported: bool,
35    pub wpa1_supported: bool,
36}
37
38impl Config {
39    pub fn with_wep(mut self) -> Self {
40        self.wep_supported = true;
41        self
42    }
43
44    pub fn with_wpa1(mut self) -> Self {
45        self.wpa1_supported = true;
46        self
47    }
48}
49
50#[derive(Debug)]
51pub enum MlmeRequest {
52    Scan(fidl_mlme::ScanRequest),
53    AuthResponse(fidl_mlme::AuthenticateResponse),
54    AssocResponse(fidl_mlme::AssociateResponse),
55    Connect(fidl_mlme::ConnectRequest),
56    Reconnect(fidl_mlme::ReconnectRequest),
57    Roam(fidl_mlme::RoamRequest),
58    Deauthenticate(fidl_mlme::DeauthenticateRequest),
59    Disassociate(fidl_mlme::DisassociateRequest),
60    Eapol(fidl_mlme::EapolRequest),
61    SetKeys(fidl_mlme::SetKeysRequest),
62    SetCtrlPort(fidl_mlme::SetControlledPortRequest),
63    Start(fidl_mlme::StartRequest),
64    Stop(fidl_mlme::StopRequest),
65    GetIfaceStats(responder::Responder<fidl_mlme::GetIfaceStatsResponse>),
66    GetIfaceHistogramStats(responder::Responder<fidl_mlme::GetIfaceHistogramStatsResponse>),
67    GetSignalReport(responder::Responder<Result<fidl_stats::SignalReport, i32>>),
68    ListMinstrelPeers(responder::Responder<fidl_mlme::MinstrelListResponse>),
69    GetMinstrelStats(
70        fidl_mlme::MinstrelStatsRequest,
71        responder::Responder<fidl_mlme::MinstrelStatsResponse>,
72    ),
73    SaeHandshakeResp(fidl_mlme::SaeHandshakeResponse),
74    SaeFrameTx(fidl_mlme::SaeFrame),
75    WmmStatusReq,
76    FinalizeAssociation(fidl_mlme::NegotiatedCapabilities),
77    QueryDeviceInfo(responder::Responder<fidl_mlme::DeviceInfo>),
78    QueryMacSublayerSupport(responder::Responder<fidl_common::MacSublayerSupport>),
79    QuerySecuritySupport(responder::Responder<fidl_common::SecuritySupport>),
80    QuerySpectrumManagementSupport(responder::Responder<fidl_common::SpectrumManagementSupport>),
81    QueryTelemetrySupport(responder::Responder<Result<fidl_stats::TelemetrySupport, i32>>),
82    QueryApfPacketFilterSupport(
83        responder::Responder<Result<fidl_common::ApfPacketFilterSupport, i32>>,
84    ),
85    SetMacAddress(fidl_ieee80211::MacAddr, responder::Responder<Result<(), i32>>),
86    InstallApfPacketFilter(
87        fidl_mlme::MlmeInstallApfPacketFilterRequest,
88        responder::Responder<Result<(), i32>>,
89    ),
90    ReadApfPacketFilterData(
91        responder::Responder<Result<fidl_mlme::MlmeReadApfPacketFilterDataResponse, i32>>,
92    ),
93    SetApfPacketFilterEnabled(
94        fidl_mlme::MlmeSetApfPacketFilterEnabledRequest,
95        responder::Responder<Result<(), i32>>,
96    ),
97    GetApfPacketFilterEnabled(
98        responder::Responder<Result<fidl_mlme::MlmeGetApfPacketFilterEnabledResponse, i32>>,
99    ),
100    StartScheduledScan(
101        fidl_mlme::MlmeStartScheduledScanRequest,
102        responder::Responder<Result<(), i32>>,
103    ),
104    StopScheduledScan(
105        fidl_mlme::MlmeStopScheduledScanRequest,
106        responder::Responder<Result<(), i32>>,
107    ),
108    GetScheduledScanEnabled(
109        responder::Responder<Result<fidl_mlme::MlmeGetScheduledScanEnabledResponse, i32>>,
110    ),
111}
112
113impl MlmeRequest {
114    pub fn name(&self) -> &'static str {
115        match self {
116            Self::Scan(_) => "Scan",
117            Self::AuthResponse(_) => "AuthResponse",
118            Self::AssocResponse(_) => "AssocResponse",
119            Self::Connect(_) => "Connect",
120            Self::Reconnect(_) => "Reconnect",
121            Self::Roam(_) => "Roam",
122            Self::Deauthenticate(_) => "Deauthenticate",
123            Self::Disassociate(_) => "Disassociate",
124            Self::Eapol(_) => "Eapol",
125            Self::SetKeys(_) => "SetKeys",
126            Self::SetCtrlPort(_) => "SetCtrlPort",
127            Self::Start(_) => "Start",
128            Self::Stop(_) => "Stop",
129            Self::GetIfaceStats(_) => "GetIfaceStats",
130            Self::GetIfaceHistogramStats(_) => "GetIfaceHistogramStats",
131            Self::StartScheduledScan(..) => "StartScheduledScan",
132            Self::StopScheduledScan(..) => "StopScheduledScan",
133            Self::GetScheduledScanEnabled(_) => "GetScheduledScanEnabled",
134            Self::GetSignalReport(_) => "GetSignalReport",
135            Self::ListMinstrelPeers(_) => "ListMinstrelPeers",
136            Self::GetMinstrelStats(_, _) => "GetMinstrelStats",
137            Self::SaeHandshakeResp(_) => "SaeHandshakeResp",
138            Self::SaeFrameTx(_) => "SaeFrameTx",
139            Self::WmmStatusReq => "WmmStatusReq",
140            Self::FinalizeAssociation(_) => "FinalizeAssociation",
141            Self::QueryDeviceInfo(_) => "QueryDeviceInfo",
142            Self::QueryMacSublayerSupport(_) => "QueryMacSublayerSupport",
143            Self::QuerySecuritySupport(_) => "QuerySecuritySupport",
144            Self::QuerySpectrumManagementSupport(_) => "QuerySpectrumManagementSupport",
145            Self::QueryTelemetrySupport(_) => "QueryTelemetrySupport",
146            Self::QueryApfPacketFilterSupport(_) => "QueryApfPacketFilterSupport",
147            Self::SetMacAddress(..) => "SetMacAddress",
148            Self::InstallApfPacketFilter(..) => "InstallApfPacketFilter",
149            Self::ReadApfPacketFilterData(_) => "ReadApfPacketFilterData",
150            Self::SetApfPacketFilterEnabled(..) => "SetApfPacketFilterEnabled",
151            Self::GetApfPacketFilterEnabled(_) => "GetApfPacketFilterEnabled",
152        }
153    }
154}
155
156pub trait Station {
157    type Event;
158
159    fn on_mlme_event(&mut self, event: fidl_mlme::MlmeEvent);
160    fn on_timeout(&mut self, timed_event: timer::Event<Self::Event>);
161}
162
163pub type MlmeStream = mpsc::UnboundedReceiver<MlmeRequest>;
164pub type MlmeEventStream = mpsc::UnboundedReceiver<MlmeEvent>;
165pub type MlmeSink = UnboundedSink<MlmeRequest>;
166pub type MlmeEventSink = UnboundedSink<MlmeEvent>;
167
168pub mod responder {
169    use futures::channel::oneshot;
170
171    #[derive(Debug)]
172    pub struct Responder<T>(oneshot::Sender<T>);
173
174    impl<T> Responder<T> {
175        pub fn new() -> (Self, oneshot::Receiver<T>) {
176            let (sender, receiver) = oneshot::channel();
177            (Responder(sender), receiver)
178        }
179
180        pub fn respond(self, result: T) {
181            #[allow(
182                clippy::unnecessary_lazy_evaluations,
183                reason = "mass allow for https://fxbug.dev/381896734"
184            )]
185            self.0.send(result).unwrap_or_else(|_| ());
186        }
187    }
188}
189
190/// Safely log MlmeEvents without printing private information.
191fn mlme_event_name(event: &MlmeEvent) -> &str {
192    match event {
193        MlmeEvent::OnScanResult { .. } => "OnScanResult",
194        MlmeEvent::OnScanEnd { .. } => "OnScanEnd",
195        MlmeEvent::ConnectConf { .. } => "ConnectConf",
196        MlmeEvent::RoamConf { .. } => "RoamConf",
197        MlmeEvent::RoamStartInd { .. } => "RoamStartInd",
198        MlmeEvent::RoamResultInd { .. } => "RoamResultInd",
199        MlmeEvent::AuthenticateInd { .. } => "AuthenticateInd",
200        MlmeEvent::DeauthenticateConf { .. } => "DeauthenticateConf",
201        MlmeEvent::DeauthenticateInd { .. } => "DeauthenticateInd",
202        MlmeEvent::AssociateInd { .. } => "AssociateInd",
203        MlmeEvent::DisassociateConf { .. } => "DisassociateConf",
204        MlmeEvent::DisassociateInd { .. } => "DisassociateInd",
205        MlmeEvent::SetKeysConf { .. } => "SetKeysConf",
206        MlmeEvent::StartConf { .. } => "StartConf",
207        MlmeEvent::StopConf { .. } => "StopConf",
208        MlmeEvent::EapolConf { .. } => "EapolConf",
209        MlmeEvent::SignalReport { .. } => "SignalReport",
210        MlmeEvent::EapolInd { .. } => "EapolInd",
211        MlmeEvent::RelayCapturedFrame { .. } => "RelayCapturedFrame",
212        MlmeEvent::OnChannelSwitched { .. } => "OnChannelSwitched",
213        MlmeEvent::OnPmkAvailable { .. } => "OnPmkAvailable",
214        MlmeEvent::OnSaeHandshakeInd { .. } => "OnSaeHandshakeInd",
215        MlmeEvent::OnSaeFrameRx { .. } => "OnSaeFrameRx",
216        MlmeEvent::OnWmmStatusResp { .. } => "OnWmmStatusResp",
217        MlmeEvent::OnScheduledScanMatchesAvailable { .. } => "OnScheduledScanMatchesAvailable",
218        MlmeEvent::OnScheduledScanStoppedByFirmware { .. } => "OnScheduledScanStoppedByFirmware",
219    }
220}
221
222#[derive(Debug, Error)]
223pub enum Error {
224    #[error("scan end while not scanning")]
225    ScanEndNotScanning,
226    #[error("scan end with wrong txn id")]
227    ScanEndWrongTxnId,
228    #[error("scan result while not scanning")]
229    ScanResultNotScanning,
230    #[error("scan result with wrong txn id")]
231    ScanResultWrongTxnId,
232}