blob: abcd62ab8ce0b510b01a45178bf8ed0004217c14 [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 super::*;
use crate::prelude::*;
use crate::spinel::*;
use async_trait::async_trait;
use fasync::Time;
use fidl_fuchsia_lowpan::*;
use fidl_fuchsia_lowpan_device::{
DeviceState, EnergyScanParameters, EnergyScanResult, NetworkScanParameters,
ProvisioningMonitorMarker,
};
use futures::future::ready;
use futures::stream::BoxStream;
use lowpan_driver_common::{Driver as LowpanDriver, FutureExt as _, ZxResult};
/// API-related tasks. Implementation of [`lowpan_driver_common::Driver`].
#[async_trait]
impl<DS: SpinelDeviceClient> LowpanDriver for SpinelDriver<DS> {
async fn provision_network(&self, _params: ProvisioningParams) -> ZxResult<()> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn leave_network(&self) -> ZxResult<()> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn set_active(&self, _enabled: bool) -> ZxResult<()> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_supported_network_types(&self) -> ZxResult<Vec<String>> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_supported_channels(&self) -> ZxResult<Vec<ChannelInfo>> {
use fidl_fuchsia_lowpan::ChannelInfo;
fx_log_info!("Got get_supported_channels command");
// Wait until we are ready.
self.wait_for_state(DriverState::is_initialized).await;
let results = self.get_property_simple::<Vec<u8>, _>(PropPhy::ChanSupported).await?;
// TODO: Actually calculate all of the fields for channel info struct
Ok(results
.into_iter()
.map(|x| ChannelInfo {
id: Some(x.to_string()),
index: Some(u16::from(x)),
masked_by_regulatory_domain: Some(false),
..ChannelInfo::empty()
})
.collect())
}
fn watch_device_state(&self) -> BoxStream<'_, ZxResult<DeviceState>> {
ready(Err(ZxStatus::NOT_SUPPORTED)).into_stream().boxed()
}
fn watch_identity(&self) -> BoxStream<'_, ZxResult<Identity>> {
ready(Err(ZxStatus::NOT_SUPPORTED)).into_stream().boxed()
}
async fn form_network(
&self,
_params: ProvisioningParams,
progress: fidl::endpoints::ServerEnd<ProvisioningMonitorMarker>,
) {
// We don't care about errors here because
// we are simply reporting that this isn't implemented.
let _ = progress.close_with_epitaph(ZxStatus::NOT_SUPPORTED);
}
async fn join_network(
&self,
_params: ProvisioningParams,
progress: fidl::endpoints::ServerEnd<ProvisioningMonitorMarker>,
) {
// We don't care about errors here because
// we are simply reporting that this isn't implemented.
let _ = progress.close_with_epitaph(ZxStatus::NOT_SUPPORTED);
}
async fn get_credential(&self) -> ZxResult<Option<fidl_fuchsia_lowpan::Credential>> {
Err(ZxStatus::NOT_SUPPORTED)
}
fn start_energy_scan(
&self,
_params: &EnergyScanParameters,
) -> BoxStream<'_, ZxResult<Vec<EnergyScanResult>>> {
ready(Err(ZxStatus::NOT_SUPPORTED)).into_stream().boxed()
}
fn start_network_scan(
&self,
_params: &NetworkScanParameters,
) -> BoxStream<'_, ZxResult<Vec<BeaconInfo>>> {
ready(Err(ZxStatus::NOT_SUPPORTED)).into_stream().boxed()
}
async fn reset(&self) -> ZxResult<()> {
fx_log_info!("Got reset command");
// Cancel everyone with an outstanding command.
self.frame_handler.clear();
let task = async {
if self.get_init_state().is_initialized() {
fx_log_info!("reset: Sending reset command");
self.frame_handler
.send_request(CmdReset)
.boxed()
.map(|result| match result {
Ok(()) => Ok(()),
Err(e) if e.downcast_ref::<Canceled>().is_some() => Ok(()),
Err(e) => Err(ZxStatus::from(ErrorAdapter(e))),
})
.cancel_upon(self.ncp_did_reset.wait(), Ok(()))
.await?;
fx_log_info!("reset: Waiting for driver to start initializing");
self.wait_for_state(DriverState::is_initializing).await;
}
fx_log_info!("reset: Waiting for driver to finish initializing");
self.wait_for_state(DriverState::is_initialized).await;
Ok(())
};
task.on_timeout(Time::after(DEFAULT_TIMEOUT), ncp_cmd_timeout!(self)).await?;
Ok(())
}
async fn get_factory_mac_address(&self) -> ZxResult<Vec<u8>> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_current_mac_address(&self) -> ZxResult<Vec<u8>> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_ncp_version(&self) -> ZxResult<String> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_current_channel(&self) -> ZxResult<u16> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_current_rssi(&self) -> ZxResult<i32> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_partition_id(&self) -> ZxResult<u32> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_thread_rloc16(&self) -> ZxResult<u16> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn get_thread_router_id(&self) -> ZxResult<u8> {
Err(ZxStatus::NOT_SUPPORTED)
}
async fn send_mfg_command(&self, command: &str) -> ZxResult<String> {
fx_log_info!("Got send_mfg_command");
// Wait until we are ready.
self.wait_for_state(DriverState::is_initialized).await;
self.apply_standard_combinators(
self.frame_handler
.send_request(
CmdPropValueSet(PropStream::Mfg.into(), command.to_string())
.returning::<String>(),
)
.boxed(),
)
.await
}
}