blob: 09dba67be97eb3a8e523c328a4840fc87c406eda [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use connectivity_testing::wlan_service_util;
use failure::{Error, ResultExt};
use fidl_fuchsia_wlan_device_service::{DeviceServiceMarker, DeviceServiceProxy};
use fuchsia_component::client::connect_to_service;
use fuchsia_syslog::fx_log_err;
use parking_lot::RwLock;
// WlanFacade: proxies commands from sl4f test to proper fidl APIs
//
// This object is shared among all threads created by server. The inner object is the facade
// itself. Callers interact with a wrapped version of the facade that enforces read/write
// protection.
//
// Use: Create once per server instantiation.
#[derive(Debug)]
struct InnerWlanFacade {
scan_results: bool,
}
#[derive(Debug)]
pub struct WlanFacade {
wlan_svc: DeviceServiceProxy,
inner: RwLock<InnerWlanFacade>,
}
impl WlanFacade {
pub fn new() -> Result<WlanFacade, Error> {
let wlan_svc = connect_to_service::<DeviceServiceMarker>()?;
Ok(WlanFacade { wlan_svc, inner: RwLock::new(InnerWlanFacade { scan_results: false }) })
}
pub async fn scan(&self) -> Result<Vec<String>, Error> {
// get iface info
let wlan_iface_ids = await!(wlan_service_util::get_iface_list(&self.wlan_svc))
.context("Scan: failed to get wlan iface list")?;
if wlan_iface_ids.len() == 0 {
bail!("no wlan interfaces found");
}
// pick the first one
let sme_proxy =
await!(wlan_service_util::get_iface_sme_proxy(&self.wlan_svc, wlan_iface_ids[0]))
.context("Scan: failed to get iface sme proxy")?;
// start the scan
let results = await!(wlan_service_util::perform_scan(&sme_proxy)).context("Scan failed")?;
// send the ssids back to the test
let mut ssids = Vec::new();
for entry in &results {
let ssid = String::from_utf8_lossy(&entry.best_bss.ssid).into_owned();
ssids.push(ssid);
}
Ok(ssids)
}
pub async fn connect(&self, target_ssid: Vec<u8>, target_pwd: Vec<u8>) -> Result<bool, Error> {
// get iface info
let wlan_iface_ids = await!(wlan_service_util::get_iface_list(&self.wlan_svc))
.context("Connect: failed to get wlan iface list")?;
if wlan_iface_ids.len() == 0 {
bail!("no wlan interfaces found");
}
// pick the first one
let sme_proxy =
await!(wlan_service_util::get_iface_sme_proxy(&self.wlan_svc, wlan_iface_ids[0]))
.context("Connect: failed to get iface sme proxy")?;
await!(wlan_service_util::connect_to_network(&sme_proxy, target_ssid, target_pwd))
}
pub async fn disconnect(&self) -> Result<(), Error> {
// get iface info
let wlan_iface_ids = await!(wlan_service_util::get_iface_list(&self.wlan_svc))
.context("Disconnect: failed to get wlan iface list")?;
if wlan_iface_ids.len() == 0 {
bail!("no wlan interfaces found");
}
let mut disconnect_error = false;
// disconnect all networks
for iface_id in wlan_iface_ids {
let sme_proxy =
await!(wlan_service_util::get_iface_sme_proxy(&self.wlan_svc, iface_id))
.context("Disconnect: failed to get iface sme proxy")?;
match await!(wlan_service_util::disconnect_from_network(&sme_proxy)) {
Err(e) => {
fx_log_err!("Disconnect call failed on iface {}: {:?}", iface_id, e);
disconnect_error = true;
}
_ => {}
}
}
if disconnect_error {
bail!("saw a failure with at least one disconnect call");
}
Ok(())
}
}