blob: 9b93d8cef30232fbcacda1a74a3429c1c638850b [file] [log] [blame]
// Copyright 2020 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 anyhow::{format_err, Context as _, Error};
use fidl::endpoints::create_endpoints;
use fidl_fuchsia_factory_lowpan::{FactoryDeviceMarker, FactoryDeviceProxy, FactoryLookupMarker};
use fidl_fuchsia_lowpan_device::{
DeviceExtraMarker, DeviceExtraProxy, DeviceMarker, DeviceProxy, LookupMarker, LookupProxy,
Protocols,
};
use fidl_fuchsia_lowpan_test::{DeviceTestMarker, DeviceTestProxy};
use fuchsia_component::client::connect_to_service;
use futures::FutureExt;
/// This struct contains all of the transient state that can
/// be kept between invocations of commands when `lowpanctl` is
/// invoked in interactive mode. For single command execution
/// it is set up once and then discarded.
pub struct LowpanContext {
pub lookup: LookupProxy,
pub device_name: String,
}
impl LowpanContext {
const DEFAULT_DEVICE_NAME: &'static str = "lowpan0";
pub fn new(device_name: Option<String>) -> Result<LowpanContext, Error> {
let lookup = connect_to_service::<LookupMarker>()
.context("Failed to connect to Lowpan Lookup service")?;
Ok(LowpanContext {
lookup,
device_name: device_name
.clone()
.unwrap_or(LowpanContext::DEFAULT_DEVICE_NAME.to_string()),
})
}
/// Returns the default DeviceProxy.
pub async fn get_default_device(&self) -> Result<DeviceProxy, Error> {
let lookup = &self.lookup;
let (client, server) = create_endpoints::<DeviceMarker>()?;
lookup
.lookup_device(
&self.device_name,
Protocols {
device: Some(server),
device_extra: None,
device_test: None,
..Protocols::EMPTY
},
)
.map(|x| match x {
Ok(Ok(())) => Ok(()),
Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
Err(x) => Err(x.into()),
})
.await?;
client.into_proxy().context("into_proxy() failed")
}
/// Returns the default FactoryDeviceProxy.
pub async fn get_default_device_factory(&self) -> Result<FactoryDeviceProxy, Error> {
let lookup = connect_to_service::<FactoryLookupMarker>()
.context("Failed to connect to Lowpan FactoryLookup service")?;
let (client, server) = create_endpoints::<FactoryDeviceMarker>()?;
lookup
.lookup(&self.device_name, server)
.map(|x| match x {
Ok(Ok(())) => Ok(()),
Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
Err(x) => Err(x.into()),
})
.await
.context(format!("Unable to find {:?}", &self.device_name))?;
client.into_proxy().context("into_proxy() failed")
}
/// Returns the default DeviceProxy, DeviceExtraProxy and DeviceTestProxy.
pub async fn get_default_device_proxies(
&self,
) -> Result<(DeviceProxy, DeviceExtraProxy, DeviceTestProxy), Error> {
let lookup = &self.lookup;
let (client, server) = create_endpoints::<DeviceMarker>()?;
let (client_extra, server_extra) = create_endpoints::<DeviceExtraMarker>()?;
let (client_test, server_test) = create_endpoints::<DeviceTestMarker>()?;
lookup
.lookup_device(
&self.device_name,
Protocols {
device: Some(server),
device_extra: Some(server_extra),
device_test: Some(server_test),
..Protocols::EMPTY
},
)
.map(|x| match x {
Ok(Ok(())) => Ok(()),
Ok(Err(x)) => Err(format_err!("Service Error: {:?}", x)),
Err(x) => Err(x.into()),
})
.await?;
//.context(format!("Unable to find {:?}", &self.device_name))?;
Ok((
client.into_proxy().context("into_proxy() failed")?,
client_extra.into_proxy().context("into_proxy() failed")?,
client_test.into_proxy().context("into_proxy() failed")?,
))
}
}