sl4f_lib/wlan_policy/
commands.rs1use crate::server::Facade;
6use crate::wlan_policy::facade::WlanPolicyFacade;
7use anyhow::{Error, format_err};
8use async_trait::async_trait;
9use fidl_fuchsia_wlan_policy as fidl_policy;
10use log::*;
11use serde_json::{Value, to_value};
12
13#[async_trait(?Send)]
14impl Facade for WlanPolicyFacade {
15 async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
16 match method.as_ref() {
17 "scan_for_networks" => {
18 info!(tag = "WlanPolicyFacade"; "performing scan for networks");
19 let result = self.scan_for_networks().await?;
20 to_value(result).map_err(|e| format_err!("error handling scan result: {}", e))
21 }
22 "connect" => {
23 let target_ssid = parse_target_ssid(&args)?;
24 let security_type = parse_security_type(&args)?;
25
26 info!(
27 tag = "WlanPolicyFacade";
28 "performing wlan connect to SSID: {:?}", target_ssid
29 );
30 let result = self.connect(target_ssid, security_type).await?;
31 to_value(result).map_err(|e| format_err!("error parsing connection result: {}", e))
32 }
33 "remove_network" => {
34 let target_ssid = parse_target_ssid(&args)?;
35 let security_type = parse_security_type(&args)?;
36 let target_pwd = parse_target_pwd(&args)?;
37
38 info!(tag = "WlanPolicyFacade"; "removing network with SSID: {:?}", target_ssid);
39 let result = self.remove_network(target_ssid, security_type, target_pwd).await?;
40 to_value(result)
41 .map_err(|e| format_err!("error parsing remove network result: {}", e))
42 }
43 "start_client_connections" => {
44 info!(tag = "WlanPolicyFacade"; "attempting to start client connections");
45 let result = self.start_client_connections().await?;
46 to_value(result).map_err(|e| {
47 format_err!("error handling start client connections result: {}", e)
48 })
49 }
50 "stop_client_connections" => {
51 info!(tag = "WlanPolicyFacade"; "attempting to stop client connections");
52 let result = self.stop_client_connections().await?;
53 to_value(result).map_err(|e| {
54 format_err!("error handling stop client connections result: {}", e)
55 })
56 }
57 "save_network" => {
58 let target_ssid = parse_target_ssid(&args)?;
59 let security_type = parse_security_type(&args)?;
60 let target_pwd = parse_target_pwd(&args)?;
61
62 info!(tag = "WlanPolicyFacade"; "saving network with SSID: {:?}", target_ssid);
63 let result = self.save_network(target_ssid, security_type, target_pwd).await?;
64 to_value(result)
65 .map_err(|e| format_err!("error parsing save network result: {}", e))
66 }
67 "get_saved_networks" => {
68 info!(tag = "WlanPolicyFacade"; "attempting to get saved networks");
69 let result = self.get_saved_networks_json().await?;
70 to_value(result)
71 .map_err(|e| format_err!("error handling get saved networks result: {}", e))
72 }
73 "create_client_controller" => {
74 info!(tag = "WlanPolicyFacade"; "initializing client controller");
75 let result = self.create_client_controller().await?;
76 to_value(result)
77 .map_err(|e| format_err!("error initializing client controller: {}", e))
78 }
79 "drop_client_controller" => {
80 info!(tag = "WlanPolicyFacade"; "dropping client controller");
81 let result = self.drop_client_controller();
82 to_value(result).map_err(|e| format_err!("error dropping client controller: {}", e))
83 }
84 "remove_all_networks" => {
85 info!(tag = "WlanPolicyFacade"; "Removing all saved client network configs");
86 let result = self.remove_all_networks().await?;
87 to_value(result)
88 .map_err(|e| format_err!("error removing all saved networks: {}", e))
89 }
90 "get_update" => {
91 info!(tag = "WlanPolicyFacade"; "getting client update");
92 let result = self.get_update().await?;
93 to_value(result).map_err(|e| format_err!("error handling listener update: {}", e))
94 }
95 "set_new_update_listener" => {
96 info!(tag = "WlanPolicyFacade"; "initializing new update listener");
97 let result = self.set_new_listener()?;
98 to_value(result)
99 .map_err(|e| format_err!("error initializing new update listener: {}", e))
100 }
101 _ => return Err(format_err!("unsupported command!")),
102 }
103 }
104}
105
106fn parse_target_ssid(args: &Value) -> Result<Vec<u8>, Error> {
107 args.get("target_ssid")
108 .and_then(|ssid| ssid.as_str().map(|ssid| ssid.as_bytes().to_vec()))
109 .ok_or_else(|| format_err!("Please provide a target ssid"))
110}
111
112fn parse_security_type(args: &Value) -> Result<fidl_policy::SecurityType, Error> {
115 let security_type = match args.get("security_type") {
116 Some(Value::String(security)) => security.as_bytes().to_vec(),
117 Some(value) => {
118 info!(tag = "WlanFacade"; "Please check provided security type, must be String");
119 bail!("provided security type arg is not a string, cannot parse {}", value);
120 }
121 None => {
122 info!(tag = "WlanFacade"; "Please check provided security type, none found");
123 bail!("no security type is provided");
124 }
125 };
126
127 match std::str::from_utf8(&security_type)? {
129 "none" => Ok(fidl_policy::SecurityType::None),
130 "wep" => Ok(fidl_policy::SecurityType::Wep),
131 "wpa" => Ok(fidl_policy::SecurityType::Wpa),
132 "wpa2" => Ok(fidl_policy::SecurityType::Wpa2),
133 "wpa3" => Ok(fidl_policy::SecurityType::Wpa3),
134 _ => Err(format_err!("failed to parse security type (None, WEP, WPA, WPA2, or WPA3")),
135 }
136}
137
138fn parse_target_pwd(args: &Value) -> Result<fidl_policy::Credential, Error> {
145 let target_pwd = match args.get("target_pwd") {
146 Some(Value::String(pwd)) => pwd.as_bytes().to_vec(),
147 Some(value) => {
148 info!(tag = "WlanFacade"; "Please check provided credential, must be String");
149 bail!("provided credential is not a string, cannot parse {}", value);
150 }
151 None => {
152 info!(tag = "WlanFacade"; "Please check provided credential, none provided");
153 bail!("no credential argument provided");
154 }
155 };
156
157 const PSK_LEN: usize = 64;
158 let credential = match target_pwd.len() {
159 0 => fidl_policy::Credential::None(fidl_policy::Empty),
160 PSK_LEN => {
161 let psk = hex::decode(target_pwd).map_err(|e| {
162 info!(
163 tag = "WlanFacade";
164 "Please check provided credential, PSK must be valid hexadecimal string"
165 );
166 format_err!("provided credential length matches PSK, failed to decode: {:?}", e)
167 })?;
168 fidl_policy::Credential::Psk(psk)
169 }
170 _ => fidl_policy::Credential::Password(target_pwd),
171 };
172 Ok(credential)
173}