blob: 7757ac47b29d7655bf37bb2093d5f63145f04761 [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.
#![recursion_limit = "256"]
mod client;
mod config;
mod config_manager;
mod device;
mod fuse_pending;
mod known_ess_store;
mod network_config;
mod policy;
mod shim;
mod stash;
mod state_machine;
use {
crate::{config::Config, config_manager::SavedNetworksManager, known_ess_store::KnownEssStore},
anyhow::{format_err, Context as _, Error},
fidl_fuchsia_wlan_device_service::DeviceServiceMarker,
fuchsia_async as fasync,
fuchsia_component::server::ServiceFs,
futures::{channel::mpsc, future::try_join, prelude::*, select},
parking_lot::Mutex,
pin_utils::pin_mut,
std::sync::Arc,
void::Void,
};
async fn serve_fidl(
_client_ref: shim::ClientRef,
ess_store: Arc<KnownEssStore>,
saved_networks: Arc<SavedNetworksManager>,
) -> Result<Void, Error> {
let mut fs = ServiceFs::new();
let (listener_msg_sender, listener_msgs) = mpsc::unbounded();
let listener_msg_sender1 = listener_msg_sender.clone();
let listener_msg_sender2 = listener_msg_sender.clone();
let saved_networks_clone = Arc::clone(&saved_networks);
fs.dir("svc")
.add_fidl_service(|stream| {
let fut = shim::serve_legacy(
stream,
_client_ref.clone(),
Arc::clone(&ess_store),
Arc::clone(&saved_networks),
)
.unwrap_or_else(|e| eprintln!("error serving legacy wlan API: {}", e));
fasync::spawn(fut)
})
.add_fidl_service(move |reqs| {
policy::client::spawn_provider_server(
Arc::new(Mutex::new(policy::client::Client::new_empty())),
listener_msg_sender1.clone(),
Arc::clone(&saved_networks_clone),
reqs,
)
})
.add_fidl_service(move |reqs| {
policy::client::spawn_listener_server(listener_msg_sender2.clone(), reqs)
});
fs.take_and_serve_directory_handle()?;
let service_fut = fs.collect::<()>().fuse();
pin_mut!(service_fut);
let serve_policy_listeners = policy::client::listener::serve(listener_msgs).fuse();
pin_mut!(serve_policy_listeners);
loop {
select! {
_ = service_fut => (),
_ = serve_policy_listeners => (),
}
}
}
fn main() -> Result<(), Error> {
let cfg = Config::load_from_file()?;
let mut executor = fasync::Executor::new().context("error create event loop")?;
let wlan_svc = fuchsia_component::client::connect_to_service::<DeviceServiceMarker>()
.context("failed to connect to device service")?;
let ess_store = Arc::new(KnownEssStore::new()?);
let saved_networks = Arc::new(SavedNetworksManager::new()?);
let legacy_client = shim::ClientRef::new();
let fidl_fut =
serve_fidl(legacy_client.clone(), Arc::clone(&ess_store), Arc::clone(&saved_networks));
let (watcher_proxy, watcher_server_end) = fidl::endpoints::create_proxy()?;
wlan_svc.watch_devices(watcher_server_end)?;
let listener = device::Listener::new(wlan_svc, cfg, legacy_client);
let fut = watcher_proxy
.take_event_stream()
.try_for_each(|evt| {
device::handle_event(
&listener,
evt,
Arc::clone(&ess_store),
Arc::clone(&saved_networks),
)
.map(Ok)
})
.err_into()
.and_then(|_| future::ready(Err(format_err!("Device watcher future exited unexpectedly"))));
executor.run_singlethreaded(try_join(fidl_fut, fut)).map(|_: (Void, Void)| ())
}