wlancfg_lib/legacy/
deprecated_configuration.rs1use crate::mode_management::phy_manager::PhyManagerApi;
6use fidl_fuchsia_wlan_product_deprecatedconfiguration as fidl_deprecated;
7use futures::lock::Mutex;
8use futures::{StreamExt, select};
9use ieee80211::MacAddr;
10use log::{error, info};
11use std::sync::Arc;
12
13#[derive(Clone)]
14pub struct DeprecatedConfigurator {
15 phy_manager: Arc<Mutex<dyn PhyManagerApi>>,
16}
17
18impl DeprecatedConfigurator {
19 pub fn new(phy_manager: Arc<Mutex<dyn PhyManagerApi>>) -> Self {
20 DeprecatedConfigurator { phy_manager }
21 }
22
23 pub async fn serve_deprecated_configuration(
24 self,
25 mut requests: fidl_deprecated::DeprecatedConfiguratorRequestStream,
26 ) {
27 loop {
28 select! {
29 req = requests.select_next_some() => match req {
30 Ok(req) => match req {
31 fidl_deprecated::DeprecatedConfiguratorRequest::SuggestAccessPointMacAddress{mac, responder} => {
32 info!("setting suggested AP MAC");
33 let mac = MacAddr::from(mac.octets);
34
35 if !mac.is_unicast() || mac == ieee80211::NULL_ADDR {
36 error!("rejecting invalid suggested AP MAC");
37 if let Err(e) = responder.send(Err(fidl_deprecated::SuggestMacAddressError::InvalidArguments)) {
38 error!("could not send SuggestAccessPointMacAddress response: {:?}", e);
39 }
40 continue;
41 }
42
43 let mut phy_manager = self.phy_manager.lock().await;
44 phy_manager.suggest_ap_mac(mac);
45
46 match responder.send(Ok(())) {
47 Ok(()) => {}
48 Err(e) => {
49 error!("could not send SuggestAccessPointMacAddress response: {:?}", e);
50 }
51 }
52 }
53 }
54 Err(e) => error!("encountered an error while serving deprecated configuration requests: {}", e)
55 },
56 complete => break,
57 }
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use crate::client::types as client_types;
66 use crate::mode_management::Defect;
67 use crate::mode_management::phy_manager::{CreateClientIfacesReason, PhyManagerError};
68 use crate::mode_management::recovery::RecoverySummary;
69 use assert_matches::assert_matches;
70 use async_trait::async_trait;
71 use fidl::endpoints::create_proxy;
72 use fuchsia_async as fasync;
73 use futures::task::Poll;
74 use std::collections::HashMap;
75 use std::pin::pin;
76 use std::unimplemented;
77 use test_case::test_case;
78
79 #[derive(Debug)]
80 struct StubPhyManager(Option<MacAddr>);
81
82 impl StubPhyManager {
83 fn new() -> Self {
84 StubPhyManager(None)
85 }
86 }
87
88 #[async_trait(?Send)]
89 impl PhyManagerApi for StubPhyManager {
90 async fn add_phy(&mut self, _phy_id: u16) -> Result<(), PhyManagerError> {
91 unimplemented!();
92 }
93
94 fn remove_phy(&mut self, _phy_id: u16) {
95 unimplemented!();
96 }
97
98 async fn on_iface_added(&mut self, _iface_id: u16) -> Result<(), PhyManagerError> {
99 unimplemented!();
100 }
101
102 fn on_iface_removed(&mut self, _iface_id: u16) {
103 unimplemented!();
104 }
105
106 async fn create_all_client_ifaces(
107 &mut self,
108 _reason: CreateClientIfacesReason,
109 ) -> HashMap<u16, Result<Vec<u16>, PhyManagerError>> {
110 unimplemented!();
111 }
112
113 fn client_connections_enabled(&self) -> bool {
114 unimplemented!();
115 }
116
117 async fn destroy_all_client_ifaces(&mut self) -> Result<(), PhyManagerError> {
118 unimplemented!();
119 }
120
121 fn get_client(&mut self) -> Option<u16> {
122 unimplemented!();
123 }
124
125 async fn create_or_get_ap_iface(&mut self) -> Result<Option<u16>, PhyManagerError> {
126 unimplemented!();
127 }
128
129 async fn destroy_ap_iface(&mut self, _iface_id: u16) -> Result<(), PhyManagerError> {
130 unimplemented!();
131 }
132
133 async fn destroy_all_ap_ifaces(&mut self) -> Result<(), PhyManagerError> {
134 unimplemented!();
135 }
136
137 fn suggest_ap_mac(&mut self, mac: MacAddr) {
138 self.0 = Some(mac);
139 }
140
141 fn get_phy_ids(&self) -> Vec<u16> {
142 unimplemented!();
143 }
144
145 fn log_phy_add_failure(&mut self) {
146 unimplemented!();
147 }
148
149 async fn set_country_code(
150 &mut self,
151 _country_code: Option<client_types::CountryCode>,
152 ) -> Result<(), PhyManagerError> {
153 unimplemented!();
154 }
155
156 fn record_defect(&mut self, _defect: Defect) {
157 unimplemented!();
158 }
159
160 async fn perform_recovery(&mut self, _summary: RecoverySummary) {
161 unimplemented!();
162 }
163 }
164
165 #[fuchsia::test]
166 fn test_suggest_mac_succeeds() {
167 let mut exec = fasync::TestExecutor::new();
168
169 let phy_manager = Arc::new(Mutex::new(StubPhyManager::new()));
171 let configurator = DeprecatedConfigurator::new(phy_manager.clone());
172
173 let (configurator_proxy, remote) =
175 create_proxy::<fidl_deprecated::DeprecatedConfiguratorMarker>();
176 let stream = remote.into_stream();
177
178 let fut = configurator.serve_deprecated_configuration(stream);
180 let mut fut = pin!(fut);
181 assert!(exec.run_until_stalled(&mut fut).is_pending());
182
183 let octets = [0xde, 0xad, 0xbe, 0xef, 0x00, 0x01];
185 let mac = fidl_fuchsia_net::MacAddress { octets };
186 let mut suggest_fut = configurator_proxy.suggest_access_point_mac_address(&mac);
187 assert!(exec.run_until_stalled(&mut fut).is_pending());
188
189 let lock_fut = phy_manager.lock();
191 let mut lock_fut = pin!(lock_fut);
192 let phy_manager = assert_matches!(
193 exec.run_until_stalled(&mut lock_fut),
194 Poll::Ready(phy_manager) => {
195 phy_manager
196 }
197 );
198 let expected_mac = MacAddr::from(octets);
199 assert_eq!(Some(expected_mac), phy_manager.0);
200
201 assert_matches!(exec.run_until_stalled(&mut suggest_fut), Poll::Ready(Ok(Ok(()))));
202 }
203
204 #[test_case([0xff, 0xff, 0xff, 0xff, 0xff, 0xff] ; "broadcast")]
205 #[test_case([0x01, 0x00, 0x5e, 0x00, 0x00, 0x01] ; "multicast")]
206 #[fuchsia::test]
207 fn test_suggest_mac_fails(octets: [u8; 6]) {
208 let mut exec = fasync::TestExecutor::new();
209
210 let phy_manager = Arc::new(Mutex::new(StubPhyManager::new()));
212 let configurator = DeprecatedConfigurator::new(phy_manager.clone());
213
214 let (configurator_proxy, remote) =
216 create_proxy::<fidl_deprecated::DeprecatedConfiguratorMarker>();
217 let stream = remote.into_stream();
218
219 let fut = configurator.serve_deprecated_configuration(stream);
221 let mut fut = pin!(fut);
222 assert!(exec.run_until_stalled(&mut fut).is_pending());
223
224 let mac = fidl_fuchsia_net::MacAddress { octets };
226 let mut suggest_fut = configurator_proxy.suggest_access_point_mac_address(&mac);
227 assert!(exec.run_until_stalled(&mut fut).is_pending());
228
229 let lock_fut = phy_manager.lock();
231 let mut lock_fut = pin!(lock_fut);
232 let phy_manager = assert_matches!(
233 exec.run_until_stalled(&mut lock_fut),
234 Poll::Ready(phy_manager) => {
235 phy_manager
236 }
237 );
238 assert_eq!(None, phy_manager.0);
239
240 assert_matches!(
241 exec.run_until_stalled(&mut suggest_fut),
242 Poll::Ready(Ok(Err(fidl_deprecated::SuggestMacAddressError::InvalidArguments)))
243 );
244 }
245}