sl4f_lib/wlan/
commands.rs1use crate::server::Facade;
6use anyhow::{format_err, Error};
7use async_trait::async_trait;
8use fidl_fuchsia_wlan_common as fidl_common;
9use ieee80211::{MacAddr, Ssid, NULL_ADDR};
10use log::*;
11use serde_json::{from_value, to_value, Value};
12
13use crate::wlan::facade::WlanFacade;
15use crate::wlan::types;
16
17use crate::common_utils::common::parse_u64_identifier;
18
19#[async_trait(?Send)]
20impl Facade for WlanFacade {
21 async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
22 match method.as_ref() {
23 "scan" => {
24 info!(tag = "WlanFacade"; "performing wlan scan");
25 let results = self.scan().await?;
26 info!(tag = "WlanFacade"; "received {:?} scan results", results.len());
27 to_value(results).map_err(|e| format_err!("error handling scan results: {}", e))
28 }
29 "scan_for_bss_info" => {
30 info!(tag = "WlanFacade"; "performing wlan scan");
31 let results = self.scan_for_bss_info().await?;
32 info!(tag = "WlanFacade"; "received {:?} scan results", results.len());
33 to_value(results).map_err(|e| format_err!("error handling scan results: {}", e))
34 }
35 "connect" => {
36 let target_ssid = match args.get("target_ssid") {
37 Some(ssid_value) => {
38 let ssid = match ssid_value.as_str() {
39 Some(ssid_value) => Ssid::try_from(ssid_value)?,
40 None => {
41 return Err(format_err!("Please provide a target ssid"));
42 }
43 };
44 ssid
45 }
46 None => return Err(format_err!("Please provide a target ssid")),
47 };
48
49 let target_pwd = match args.get("target_pwd") {
50 Some(pwd) => match pwd.clone().as_str() {
51 Some(pwd) => pwd.as_bytes().to_vec(),
52 None => {
53 info!(tag = "WlanFacade"; "Please check provided password");
54 vec![0; 0]
55 }
56 },
57 _ => vec![0; 0],
58 };
59
60 let target_bss_desc: types::BssDescriptionDef = match args.get("target_bss_desc") {
61 Some(target_bss_desc) => from_value(target_bss_desc.clone())?,
62 None => return Err(format_err!("Please provide a target BSS description")),
63 };
64
65 info!(tag = "WlanFacade"; "performing wlan connect to SSID: {:?}", target_ssid);
66 let results = self.connect(target_ssid, target_pwd, target_bss_desc.into()).await?;
67 to_value(results)
68 .map_err(|e| format_err!("error handling connection result: {}", e))
69 }
70 "get_iface_id_list" => {
71 info!(tag = "WlanFacade"; "Getting the interface id list.");
72 let result = self.get_iface_id_list().await?;
73 to_value(result).map_err(|e| format_err!("error handling get_iface_id_list: {}", e))
74 }
75 "get_phy_id_list" => {
76 info!(tag = "WlanFacade"; "Getting the phy id list.");
77 let result = self.get_phy_id_list().await?;
78 to_value(result).map_err(|e| format_err!("error handling get_phy_id_list: {}", e))
79 }
80 "create_iface" => {
81 info!(tag = "WlanFacade"; "Performing wlan create_iface");
82 let phy_id = match args.get("phy_id") {
83 Some(phy_id) => match phy_id.as_u64() {
84 Some(phy_id) => phy_id as u16,
85 None => return Err(format_err!("Could not parse phy id")),
86 },
87 None => return Err(format_err!("Please provide target phy id")),
88 };
89
90 let role = if let Some(role) = args.get("role") {
91 match role.as_str() {
92 Some("Ap") => fidl_common::WlanMacRole::Ap,
93 Some("Client") => fidl_common::WlanMacRole::Client,
94 None => return Err(format_err!("Could not parse role")),
95 other => return Err(format_err!("Invalid iface role: {:?}", other)),
96 }
97 } else {
98 return Err(format_err!("Please provide a role for the new iface"));
99 };
100
101 let sta_addr: MacAddr = if let Some(mac) = args.get("sta_addr") {
102 match mac.as_str() {
103 Some(mac) => match serde_json::from_str::<[u8; 6]>(mac) {
104 Ok(mac) => mac.into(),
105 Err(e) => {
106 println!(
107 "Could not parse mac: {:?}, using null addr {}",
108 e, NULL_ADDR
109 );
110 NULL_ADDR
111 }
112 },
113 None => {
114 println!(
115 "Could not convert sta_addr to string, using null addr {}",
116 NULL_ADDR
117 );
118 NULL_ADDR
119 }
120 }
121 } else {
122 println!("No MAC provided in args, using null addr {}", NULL_ADDR);
123 NULL_ADDR
124 };
125
126 let result = self.create_iface(phy_id, role, sta_addr).await?;
127 to_value(result).map_err(|e| format_err!("error handling create_iface: {}", e))
128 }
129 "destroy_iface" => {
130 info!(tag = "WlanFacade"; "Performing wlan destroy_iface");
131 let iface_id = parse_u64_identifier(args.clone())?;
132 self.destroy_iface(iface_id as u16).await?;
133 to_value(true).map_err(|e| format_err!("error handling destroy_iface: {}", e))
134 }
135 "disconnect" => {
136 info!(tag = "WlanFacade"; "performing wlan disconnect");
137 self.disconnect().await?;
138 to_value(true).map_err(|e| format_err!("error handling disconnect: {}", e))
139 }
140 "query_iface" => {
141 let iface_id = match args.get("iface_id") {
142 Some(iface_id) => match iface_id.as_u64() {
143 Some(iface_id) => iface_id as u16,
144 None => return Err(format_err!("Could not parse iface id")),
145 },
146 None => return Err(format_err!("Please provide target iface id")),
147 };
148
149 info!(tag = "WlanFacade"; "performing wlan query iface");
150 let result = self.query_iface(iface_id).await?;
151 to_value(result).map_err(|e| format_err!("error handling query iface: {}", e))
152 }
153 "status" => {
154 info!(tag = "WlanFacade"; "fetching connection status");
155 let result = self.status().await?;
156 to_value(result).map_err(|e| format_err!("error handling connection status: {}", e))
157 }
158 _ => return Err(format_err!("unsupported command!")),
159 }
160 }
161}