blob: 4e325882d6bba02265bdab6873cbf0ac297861e4 [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)]
use {
failure::{Error, ResultExt},
fidl::endpoints::ServiceMarker,
fidl_fuchsia_bluetooth_bredr::ProfileMarker,
fidl_fuchsia_bluetooth_control::ControlMarker,
fidl_fuchsia_bluetooth_gatt::Server_Marker,
fidl_fuchsia_bluetooth_le::{CentralMarker, PeripheralMarker},
fidl_fuchsia_bluetooth_snoop::SnoopMarker,
fuchsia_app::{
server::ServicesServer,
client::{connect_to_service, Launcher},
},
fuchsia_async as fasync,
fuchsia_bluetooth::make_clones,
fuchsia_syslog::{self as syslog, fx_log_info, fx_log_warn},
futures::TryFutureExt,
parking_lot::Mutex,
std::sync::Arc,
};
mod config;
fn main() -> Result<(), Error> {
syslog::init_with_tags(&["bt-mgr"]).expect("Can't init logger");
fx_log_info!("Starting bt-mgr...");
let mut executor = fasync::Executor::new().context("Error creating executor")?;
let cfg = config::Config::load()?;
// Start bt-snoop service before anything else.
if cfg.autostart_snoop() {
let res = connect_to_service::<SnoopMarker>();
if let Err(e) = res {
fx_log_warn!("Failed to start snoop service: {}", e);
}
}
let launcher = Launcher::new()
.context("Failed to open launcher service")
.unwrap();
let btgap = Arc::new(Mutex::new(
launcher
.launch(
String::from("fuchsia-pkg://fuchsia.com/bt-gap#meta/bt-gap.cmx"),
None,
)
.context("Failed to launch bt-gap (bluetooth) service")
.unwrap(),
));
make_clones!(btgap => btgap_control, btgap_central, btgap_peripheral, btgap_profile, btgap_gatt_server);
let server = ServicesServer::new()
.add_service((ControlMarker::NAME, move |chan: fasync::Channel| {
fx_log_info!("Passing Control Handle to bt-gap");
let _ = btgap_control
.lock()
.pass_to_service(ControlMarker, chan.into());
}))
.add_service((CentralMarker::NAME, move |chan: fasync::Channel| {
fx_log_info!("Passing LE Central Handle to bt-gap");
let _ = btgap_central
.lock()
.pass_to_service(CentralMarker, chan.into());
}))
.add_service((PeripheralMarker::NAME, move |chan: fasync::Channel| {
fx_log_info!("Passing Peripheral Handle to bt-gap");
let _ = btgap_peripheral
.lock()
.pass_to_service(PeripheralMarker, chan.into());
}))
.add_service((ProfileMarker::NAME, move |chan: fasync::Channel| {
fx_log_info!("Passing Profile Handle to bt-gap");
let _ = btgap_profile
.lock()
.pass_to_service(ProfileMarker, chan.into());
}))
.add_service((Server_Marker::NAME, move |chan: fasync::Channel| {
fx_log_info!("Passing GATT Handle to bt-gap");
let _ = btgap_gatt_server
.lock()
.pass_to_service(Server_Marker, chan.into());
}))
.start()
.map_err(|e| e.context("error starting service server"))?;
let io_config_fut = cfg.set_capabilities();
executor
.run_singlethreaded(server.try_join(io_config_fut))
.context("bt-mgr failed to execute future")
.map_err(|e| e.into())
.map(|_| ())
}