blob: d17e008a18a85d39cc4e8ff8bb59a08e3b94c7fe [file] [log] [blame]
// Copyright 2019 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.
//! LoWPAN Service for Fuchsia
mod inspect;
mod service;
use anyhow::{format_err, Context as _, Error};
use fidl_fuchsia_factory_lowpan;
use fidl_fuchsia_lowpan_driver::RegisterRequestStream;
use fuchsia_async as fasync;
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect::Inspector;
use futures::prelude::*;
use futures::task::{FutureObj, Spawn, SpawnError};
use lowpan_driver_common::lowpan_fidl::*;
use lowpan_driver_common::ServeTo;
use service::*;
use std::default::Default;
use std::sync::Arc;
#[allow(unused_imports)]
use tracing::{debug, error, info, trace, warn};
enum IncomingService {
DeviceWatcher(DeviceWatcherRequestStream),
Register(RegisterRequestStream),
FactoryLookup(FactoryLookupRequestStream),
FactoryRegister(FactoryRegisterRequestStream),
DeviceConnector(DeviceConnectorRequestStream),
DeviceExtraConnector(DeviceExtraConnectorRequestStream),
DeviceRouteConnector(DeviceRouteConnectorRequestStream),
DeviceRouteExtraConnector(DeviceRouteExtraConnectorRequestStream),
CountersConnector(CountersConnectorRequestStream),
DeviceTestConnector(DeviceTestConnectorRequestStream),
LegacyJoiningConnector(LegacyJoiningConnectorRequestStream),
DatasetConnector(DatasetConnectorRequestStream),
MeshcopConnector(MeshcopConnectorRequestStream),
EnergyScanConnector(EnergyScanConnectorRequestStream),
ExperimentalDeviceConnector(ExperimentalDeviceConnectorRequestStream),
ExperimentalDeviceExtraConnector(ExperimentalDeviceExtraConnectorRequestStream),
TelemetryProviderConnector(TelemetryProviderConnectorRequestStream),
FeatureConnector(FeatureConnectorRequestStream),
CapabilitiesConnector(CapabilitiesConnectorRequestStream),
}
const MAX_CONCURRENT: usize = 100;
/// Type that implements futures::task::Spawn and uses
/// Fuchsia's port-based global executor.
pub struct FuchsiaGlobalExecutor;
impl Spawn for FuchsiaGlobalExecutor {
fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
fasync::Task::spawn(future).detach();
Ok(())
}
}
#[fuchsia::main()]
async fn main() -> Result<(), Error> {
info!("LoWPAN Service starting up");
let service = LowpanService::with_spawner(FuchsiaGlobalExecutor);
let mut fs = ServiceFs::new_local();
// Creates a new inspector object. This will create the "root" node in the
// inspect tree to which further children objects can be added.
let inspector = fuchsia_inspect::Inspector::default();
let _inspect_server_task =
inspect_runtime::publish(&inspector, inspect_runtime::PublishOptions::default());
let inspect_tree = Arc::new(inspect::LowpanServiceTree::new(inspector));
let inspect_fut = inspect::start_inspect_process(inspect_tree).map(|ret| {
error!("Inspect process terminated: {:?}", ret);
});
fs.dir("svc")
.add_fidl_service(IncomingService::DeviceWatcher)
.add_fidl_service(IncomingService::Register)
.add_fidl_service(IncomingService::FactoryLookup)
.add_fidl_service(IncomingService::FactoryRegister)
.add_fidl_service(IncomingService::DeviceConnector)
.add_fidl_service(IncomingService::DeviceExtraConnector)
.add_fidl_service(IncomingService::DeviceRouteConnector)
.add_fidl_service(IncomingService::DeviceRouteExtraConnector)
.add_fidl_service(IncomingService::CountersConnector)
.add_fidl_service(IncomingService::DeviceTestConnector)
.add_fidl_service(IncomingService::LegacyJoiningConnector)
.add_fidl_service(IncomingService::DatasetConnector)
.add_fidl_service(IncomingService::ExperimentalDeviceConnector)
.add_fidl_service(IncomingService::ExperimentalDeviceExtraConnector)
.add_fidl_service(IncomingService::TelemetryProviderConnector)
.add_fidl_service(IncomingService::MeshcopConnector)
.add_fidl_service(IncomingService::FeatureConnector)
.add_fidl_service(IncomingService::EnergyScanConnector)
.add_fidl_service(IncomingService::CapabilitiesConnector);
fs.take_and_serve_directory_handle()?;
let fut = fs.for_each_concurrent(MAX_CONCURRENT, |request| async {
if let Err(err) = match request {
IncomingService::DeviceWatcher(stream) => service.serve_to(stream).await,
IncomingService::Register(stream) => service.serve_to(stream).await,
IncomingService::FactoryLookup(stream) => service.serve_to(stream).await,
IncomingService::FactoryRegister(stream) => service.serve_to(stream).await,
IncomingService::DeviceConnector(stream) => service.serve_to(stream).await,
IncomingService::DeviceExtraConnector(stream) => service.serve_to(stream).await,
IncomingService::DeviceRouteConnector(stream) => service.serve_to(stream).await,
IncomingService::DeviceRouteExtraConnector(stream) => service.serve_to(stream).await,
IncomingService::CountersConnector(stream) => service.serve_to(stream).await,
IncomingService::DeviceTestConnector(stream) => service.serve_to(stream).await,
IncomingService::LegacyJoiningConnector(stream) => service.serve_to(stream).await,
IncomingService::DatasetConnector(stream) => service.serve_to(stream).await,
IncomingService::MeshcopConnector(stream) => service.serve_to(stream).await,
IncomingService::EnergyScanConnector(stream) => service.serve_to(stream).await,
IncomingService::ExperimentalDeviceConnector(stream) => service.serve_to(stream).await,
IncomingService::ExperimentalDeviceExtraConnector(stream) => {
service.serve_to(stream).await
}
IncomingService::TelemetryProviderConnector(stream) => service.serve_to(stream).await,
IncomingService::FeatureConnector(stream) => service.serve_to(stream).await,
IncomingService::CapabilitiesConnector(stream) => service.serve_to(stream).await,
} {
error!("{:?}", err);
}
});
futures::future::select(fut.boxed_local(), inspect_fut.boxed_local()).await;
info!("LoWPAN Service shut down");
Ok(())
}