blob: 6727392cd0efef36e9919c188955f2114c04ea3e [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.
#![feature(async_await, await_macro, futures_api, arbitrary_self_types)]
#![deny(warnings)]
#![recursion_limit = "256"]
mod client;
mod config;
mod device;
mod known_ess_store;
mod shim;
mod state_machine;
use crate::{config::Config, known_ess_store::KnownEssStore};
use failure::{format_err, Error, ResultExt};
use fidl::endpoints::{RequestStream, ServiceMarker};
use fidl_fuchsia_wlan_device_service::DeviceServiceMarker;
use fidl_fuchsia_wlan_service as legacy;
use fuchsia_app::server::ServicesServer;
use fuchsia_async as fasync;
use futures::prelude::*;
use std::sync::Arc;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Never {}
impl Never {
pub fn into_any<T>(self) -> T {
match self {}
}
}
fn serve_fidl(
_client_ref: shim::ClientRef,
ess_store: Arc<KnownEssStore>,
) -> impl Future<Output = Result<Never, Error>> {
future::ready(
ServicesServer::new()
.add_service((legacy::WlanMarker::NAME, move |channel| {
let stream = legacy::WlanRequestStream::from_channel(channel);
let fut = shim::serve_legacy(stream, _client_ref.clone(), Arc::clone(&ess_store))
.unwrap_or_else(|e| eprintln!("error serving legacy wlan API: {}", e));
fasync::spawn(fut)
}))
.start(),
)
.and_then(|fut| fut)
.and_then(|()| future::ready(Err(format_err!("FIDL server future exited unexpectedly"))))
}
fn main() -> Result<(), Error> {
let cfg = Config::load_from_file()?;
let mut executor = fasync::Executor::new().context("error creating event loop")?;
let wlan_svc = fuchsia_app::client::connect_to_service::<DeviceServiceMarker>()
.context("failed to connect to device service")?;
let ess_store = Arc::new(KnownEssStore::new()?);
let legacy_client = shim::ClientRef::new();
let fidl_fut = serve_fidl(legacy_client.clone(), Arc::clone(&ess_store));
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)).map(Ok))
.err_into()
.and_then(|_| future::ready(Err(format_err!("Device watcher future exited unexpectedly"))));
executor.run_singlethreaded(fidl_fut.try_join(fut)).map(|_: (Never, Never)| ())
}