Skip to main content

fullmac_helpers/
lib.rs

1// Copyright 2024 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
5use assert_matches::assert_matches;
6use fidl::endpoints::{create_endpoints, create_proxy};
7use fidl_fuchsia_wlan_fullmac as fidl_fullmac;
8use fidl_fuchsia_wlan_sme as fidl_sme;
9use fidl_test_wlan_testcontroller as fidl_testcontroller;
10use futures::StreamExt;
11use std::sync::LazyLock;
12use wlan_common::test_utils::fake_stas::FakeProtectionCfg;
13use wlan_common::{bss, fake_fidl_bss_description};
14
15pub mod config;
16pub mod fake_ap;
17pub mod recorded_request_stream;
18
19// Compatible BSS descriptions are defined here.
20// "Compatible" here means that that an SME  with default configuration
21// will accept a connect request to a BSS with the returned BssDescription.
22pub static COMPATIBLE_OPEN_BSS: LazyLock<bss::BssDescription> = LazyLock::new(|| {
23    fake_fidl_bss_description!(
24        protection => FakeProtectionCfg::Open,
25        channel: wlan_common::channel::Channel::new(1, wlan_common::channel::Cbw::Cbw20, fidl_fuchsia_wlan_ieee80211::WlanBand::TwoGhz),
26        rates: vec![2, 4, 11],
27    )
28    .try_into()
29    .expect("Could not convert BSS description from FIDL")
30});
31pub static COMPATIBLE_WPA2_BSS: LazyLock<bss::BssDescription> = LazyLock::new(|| {
32    fake_fidl_bss_description!(
33        protection => FakeProtectionCfg::Wpa2,
34        channel: wlan_common::channel::Channel::new(1, wlan_common::channel::Cbw::Cbw20, fidl_fuchsia_wlan_ieee80211::WlanBand::TwoGhz),
35        rates: vec![2, 4, 11],
36    )
37    .try_into()
38    .expect("Could not convert BSS description from FIDL")
39});
40pub static COMPATIBLE_WPA3_BSS: LazyLock<bss::BssDescription> = LazyLock::new(|| {
41    fake_fidl_bss_description!(
42        protection => FakeProtectionCfg::Wpa3,
43        channel: wlan_common::channel::Channel::new(1, wlan_common::channel::Cbw::Cbw20, fidl_fuchsia_wlan_ieee80211::WlanBand::TwoGhz),
44        rates: vec![2, 4, 11],
45    )
46    .try_into()
47    .expect("Could not convert BSS description from FIDL")
48});
49
50/// Creates and starts fullmac driver using |testcontroller_proxy|.
51/// This handles the request to start SME through the UsmeBootstrap protocol,
52/// and the sequence of query requests that SME makes to the fullmac driver on startup.
53///
54/// After this function is called, the fullmac driver is ready to be used in the test suite.
55pub async fn create_fullmac_driver(
56    testcontroller_proxy: &fidl_testcontroller::TestControllerProxy,
57    config: &config::FullmacDriverConfig,
58) -> (
59    fidl_testcontroller::FullmacId,
60    fidl_fullmac::WlanFullmacImpl_RequestStream,
61    fidl_fullmac::WlanFullmacImplIfcProxy,
62    fidl_sme::GenericSmeProxy,
63) {
64    let (fullmac_bridge_client, fullmac_bridge_server) = create_endpoints();
65
66    let fullmac_id = testcontroller_proxy
67        .create_fullmac(fullmac_bridge_client)
68        .await
69        .expect("FIDL error on create_fullmac")
70        .expect("TestController returned an error on create fullmac");
71
72    let mut fullmac_bridge_stream = fullmac_bridge_server.into_stream();
73
74    // Fullmac MLME queries driver before starting
75    let (fullmac_ifc_proxy, generic_sme_proxy) =
76        handle_fullmac_startup(&mut fullmac_bridge_stream, config).await;
77
78    (fullmac_id, fullmac_bridge_stream, fullmac_ifc_proxy, generic_sme_proxy)
79}
80
81pub async fn handle_fullmac_startup(
82    fullmac_bridge_stream: &mut fidl_fullmac::WlanFullmacImpl_RequestStream,
83    config: &config::FullmacDriverConfig,
84) -> (fidl_fullmac::WlanFullmacImplIfcProxy, fidl_sme::GenericSmeProxy) {
85    let (usme_bootstrap_proxy, usme_bootstrap_server) =
86        create_proxy::<fidl_sme::UsmeBootstrapMarker>();
87
88    let fullmac_ifc_proxy = assert_matches!(fullmac_bridge_stream.next().await,
89        Some(Ok(fidl_fullmac::WlanFullmacImpl_Request::Init { payload, responder })) => {
90            responder
91                .send(Ok(fidl_fullmac::WlanFullmacImplInitResponse {
92                    sme_channel: Some(usme_bootstrap_server.into_channel()),
93                    ..Default::default()
94                }))
95                .expect("Failed to respond to Init");
96            let ifc = payload.ifc.expect("Init response missing ifc");
97            ifc.into_proxy()
98        }
99    );
100
101    let (generic_sme_proxy, generic_sme_server) = create_proxy::<fidl_sme::GenericSmeMarker>();
102
103    let _bootstrap_result = usme_bootstrap_proxy
104        .start(generic_sme_server, &config.sme_legacy_privacy_support)
105        .await
106        .expect("Failed to call usme_bootstrap.start");
107
108    assert_matches!(fullmac_bridge_stream.next().await,
109        Some(Ok(fidl_fullmac::WlanFullmacImpl_Request::Query { responder })) => {
110            responder
111                .send(Ok(&config.query_info))
112                .expect("Failed to respond to Query");
113        }
114    );
115
116    assert_matches!(fullmac_bridge_stream.next().await,
117        Some(Ok(fidl_fullmac::WlanFullmacImpl_Request::QuerySecuritySupport {
118            responder,
119        })) => {
120            let resp = fidl_fullmac::WlanFullmacImplQuerySecuritySupportResponse {
121                resp: Some(config.security_support.clone()),
122                ..Default::default()
123            };
124            responder.send(Ok(&resp)).expect("Failed to respond to QuerySecuritySupport");
125        }
126    );
127
128    assert_matches!(fullmac_bridge_stream.next().await,
129        Some(Ok(fidl_fullmac::WlanFullmacImpl_Request::QuerySpectrumManagementSupport {
130                responder,
131        })) => {
132            let resp = fidl_fullmac::WlanFullmacImplQuerySpectrumManagementSupportResponse {
133                resp: Some(config.spectrum_management_support.clone()),
134                ..Default::default()
135            };
136            responder.send(Ok(&resp)).expect("Failed to respond to QuerySpectrumManagementSupport");
137        }
138    );
139
140    assert_matches!(fullmac_bridge_stream.next().await,
141        Some(Ok(fidl_fullmac::WlanFullmacImpl_Request::Query { responder })) => {
142            responder
143                .send(Ok(&config.query_info))
144                .expect("Failed to respond to Query");
145        }
146    );
147
148    (fullmac_ifc_proxy, generic_sme_proxy)
149}