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 info!(tag = "WlanPolicyFacade"; "removing network with SSID: {:?}", target_ssid);
37 let result = self.remove_network(target_ssid, security_type).await?;
38 to_value(result)
39 .map_err(|e| format_err!("error parsing remove network result: {}", e))
40 }
41 "start_client_connections" => {
42 info!(tag = "WlanPolicyFacade"; "attempting to start client connections");
43 let result = self.start_client_connections().await?;
44 to_value(result).map_err(|e| {
45 format_err!("error handling start client connections result: {}", e)
46 })
47 }
48 "stop_client_connections" => {
49 info!(tag = "WlanPolicyFacade"; "attempting to stop client connections");
50 let result = self.stop_client_connections().await?;
51 to_value(result).map_err(|e| {
52 format_err!("error handling stop client connections result: {}", e)
53 })
54 }
55 "save_network" => {
56 let target_ssid = parse_target_ssid(&args)?;
57 let security_type = parse_security_type(&args)?;
58 let target_pwd = parse_target_pwd(&args)?;
59
60 info!(tag = "WlanPolicyFacade"; "saving network with SSID: {:?}", target_ssid);
61 let result = self.save_network(target_ssid, security_type, target_pwd).await?;
62 to_value(result)
63 .map_err(|e| format_err!("error parsing save network result: {}", e))
64 }
65 "get_saved_networks" => {
66 info!(tag = "WlanPolicyFacade"; "attempting to get saved networks");
67 let result = self.get_saved_networks_json().await?;
68 to_value(result)
69 .map_err(|e| format_err!("error handling get saved networks result: {}", e))
70 }
71 "create_client_controller" => {
72 info!(tag = "WlanPolicyFacade"; "initializing client controller");
73 let result = self.create_client_controller().await?;
74 to_value(result)
75 .map_err(|e| format_err!("error initializing client controller: {}", e))
76 }
77 "drop_client_controller" => {
78 info!(tag = "WlanPolicyFacade"; "dropping client controller");
79 let result = self.drop_client_controller();
80 to_value(result).map_err(|e| format_err!("error dropping client controller: {}", e))
81 }
82 "remove_all_networks" => {
83 info!(tag = "WlanPolicyFacade"; "Removing all saved client network configs");
84 let result = self.remove_all_networks().await?;
85 to_value(result)
86 .map_err(|e| format_err!("error removing all saved networks: {}", e))
87 }
88 "get_update" => {
89 info!(tag = "WlanPolicyFacade"; "getting client update");
90 let result = self.get_update().await?;
91 to_value(result).map_err(|e| format_err!("error handling listener update: {}", e))
92 }
93 "set_new_update_listener" => {
94 info!(tag = "WlanPolicyFacade"; "initializing new update listener");
95 let result = self.set_new_listener()?;
96 to_value(result)
97 .map_err(|e| format_err!("error initializing new update listener: {}", e))
98 }
99 _ => return Err(format_err!("unsupported command!")),
100 }
101 }
102}
103
104fn parse_target_ssid(args: &Value) -> Result<Vec<u8>, Error> {
105 args.get("target_ssid")
106 .and_then(|ssid| ssid.as_str().map(|ssid| ssid.as_bytes().to_vec()))
107 .ok_or_else(|| format_err!("Please provide a target ssid"))
108}
109
110fn parse_security_type(args: &Value) -> Result<fidl_policy::SecurityType, Error> {
113 let security_type = match args.get("security_type") {
114 Some(Value::String(security)) => security.as_bytes().to_vec(),
115 Some(value) => {
116 info!(tag = "WlanFacade"; "Please check provided security type, must be String");
117 bail!("provided security type arg is not a string, cannot parse {}", value);
118 }
119 None => {
120 info!(tag = "WlanFacade"; "Please check provided security type, none found");
121 bail!("no security type is provided");
122 }
123 };
124
125 match std::str::from_utf8(&security_type)? {
127 "none" => Ok(fidl_policy::SecurityType::None),
128 "wep" => Ok(fidl_policy::SecurityType::Wep),
129 "wpa" => Ok(fidl_policy::SecurityType::Wpa),
130 "wpa2" => Ok(fidl_policy::SecurityType::Wpa2),
131 "wpa3" => Ok(fidl_policy::SecurityType::Wpa3),
132 _ => Err(format_err!("failed to parse security type (None, WEP, WPA, WPA2, or WPA3")),
133 }
134}
135
136fn parse_target_pwd(args: &Value) -> Result<fidl_policy::Credential, Error> {
143 let target_pwd = match args.get("target_pwd") {
144 Some(Value::String(pwd)) => pwd.as_bytes().to_vec(),
145 Some(value) => {
146 info!(tag = "WlanFacade"; "Please check provided credential, must be String");
147 bail!("provided credential is not a string, cannot parse {}", value);
148 }
149 None => {
150 info!(tag = "WlanFacade"; "Please check provided credential, none provided");
151 bail!("no credential argument provided");
152 }
153 };
154
155 const PSK_LEN: usize = 64;
156 let credential = match target_pwd.len() {
157 0 => fidl_policy::Credential::None(fidl_policy::Empty),
158 PSK_LEN => {
159 let psk = hex::decode(target_pwd).map_err(|e| {
160 info!(
161 tag = "WlanFacade";
162 "Please check provided credential, PSK must be valid hexadecimal string"
163 );
164 format_err!("provided credential length matches PSK, failed to decode: {:?}", e)
165 })?;
166 fidl_policy::Credential::Psk(psk)
167 }
168 _ => fidl_policy::Credential::Password(target_pwd),
169 };
170 Ok(credential)
171}