use core::future::Future;
use crate::ember::constants::COUNTER_TYPE_COUNT;
use crate::ember::entropy::Source;
use crate::ember::{Eui64, NodeId, event, library};
use crate::error::Error;
use crate::ezsp::mfg_token::Id;
use crate::frame::Callback;
use crate::frame::parameters::utilities::{
callback, custom_frame, debug_write, delay_test, echo, get_eui64, get_library_status,
get_mfg_token, get_node_id, get_phy_interface_count, get_random_number, get_timer, get_token,
get_true_random_entropy_source, get_xncp_info, nop, read_and_clear_counters, read_counters,
set_mfg_token, set_timer, set_token,
};
use crate::parameters::utilities;
use crate::transport::Transport;
use crate::types::ByteSizedVec;
use crate::{Parameters, Response};
pub trait Utilities {
fn callback(&mut self) -> impl Future<Output = Result<Option<Callback>, Error>> + Send;
fn custom_frame(
&mut self,
payload: ByteSizedVec<u8>,
) -> impl Future<Output = Result<ByteSizedVec<u8>, Error>> + Send;
fn debug_write(
&mut self,
binary_message: bool,
message: ByteSizedVec<u8>,
) -> impl Future<Output = Result<(), Error>> + Send;
fn delay_test(&mut self, delay_millis: u16) -> impl Future<Output = Result<(), Error>> + Send;
fn echo(
&mut self,
data: ByteSizedVec<u8>,
) -> impl Future<Output = Result<ByteSizedVec<u8>, Error>> + Send;
fn get_eui64(&mut self) -> impl Future<Output = Result<Eui64, Error>> + Send;
fn get_library_status(
&mut self,
library_id: library::Id,
) -> impl Future<Output = Result<library::Status, Error>> + Send;
fn get_mfg_token(
&mut self,
token_id: Id,
) -> impl Future<Output = Result<ByteSizedVec<u8>, Error>> + Send;
fn get_node_id(&mut self) -> impl Future<Output = Result<NodeId, Error>> + Send;
fn get_phy_interface_count(&mut self) -> impl Future<Output = Result<u8, Error>> + Send;
fn get_random_number(&mut self) -> impl Future<Output = Result<u16, Error>> + Send;
fn get_timer(
&mut self,
timer_id: u8,
) -> impl Future<Output = Result<get_timer::Response, Error>> + Send;
fn get_token(&mut self, token_id: u8) -> impl Future<Output = Result<[u8; 8], Error>> + Send;
fn get_true_random_entropy_source(
&mut self,
) -> impl Future<Output = Result<Source, Error>> + Send;
fn get_xncp_info(
&mut self,
) -> impl Future<Output = Result<get_xncp_info::Payload, Error>> + Send;
fn nop(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
fn read_and_clear_counters(
&mut self,
) -> impl Future<Output = Result<[u16; COUNTER_TYPE_COUNT], Error>> + Send;
fn read_counters(
&mut self,
) -> impl Future<Output = Result<[u16; COUNTER_TYPE_COUNT], Error>> + Send;
fn set_mfg_token(
&mut self,
token_id: Id,
token: ByteSizedVec<u8>,
) -> impl Future<Output = Result<(), Error>> + Send;
fn set_timer(
&mut self,
timer_id: u8,
duration: event::Duration,
repeat: bool,
) -> impl Future<Output = Result<(), Error>> + Send;
fn set_token(
&mut self,
token_id: u8,
token: [u8; 8],
) -> impl Future<Output = Result<(), Error>> + Send;
}
impl<T> Utilities for T
where
T: Transport,
{
async fn callback(&mut self) -> Result<Option<Callback>, Error> {
match self.communicate(callback::Command).await? {
Parameters::Callback(callback) => Ok(Some(callback)),
Parameters::Response(Response::Utilities(utilities::Response::NoCallbacks(_))) => {
Ok(None)
}
Parameters::Response(response) => Err(Parameters::Response(response).into()),
}
}
async fn custom_frame(&mut self, payload: ByteSizedVec<u8>) -> Result<ByteSizedVec<u8>, Error> {
self.communicate(custom_frame::Command::new(payload))
.await?
.try_into()
}
async fn debug_write(
&mut self,
binary_message: bool,
message: ByteSizedVec<u8>,
) -> Result<(), Error> {
self.communicate(debug_write::Command::new(binary_message, message))
.await?
.try_into()
}
async fn delay_test(&mut self, delay_millis: u16) -> Result<(), Error> {
self.communicate(delay_test::Command::new(delay_millis))
.await
.map(drop)
}
async fn echo(&mut self, data: ByteSizedVec<u8>) -> Result<ByteSizedVec<u8>, Error> {
self.communicate(echo::Command::new(data))
.await
.map(echo::Response::echo)
}
async fn get_eui64(&mut self) -> Result<Eui64, Error> {
self.communicate(get_eui64::Command).await.map(Into::into)
}
async fn get_library_status(
&mut self,
library_id: library::Id,
) -> Result<library::Status, Error> {
self.communicate(get_library_status::Command::new(library_id))
.await
.map(Into::into)
}
async fn get_mfg_token(&mut self, token_id: Id) -> Result<ByteSizedVec<u8>, Error> {
self.communicate(get_mfg_token::Command::new(token_id))
.await
.map(Into::into)
}
async fn get_node_id(&mut self) -> Result<NodeId, Error> {
self.communicate(get_node_id::Command).await.map(Into::into)
}
async fn get_phy_interface_count(&mut self) -> Result<u8, Error> {
self.communicate(get_phy_interface_count::Command)
.await
.map(Into::into)
}
async fn get_random_number(&mut self) -> Result<u16, Error> {
self.communicate(get_random_number::Command)
.await?
.try_into()
}
async fn get_timer(&mut self, timer_id: u8) -> Result<get_timer::Response, Error> {
self.communicate(get_timer::Command::new(timer_id)).await
}
async fn get_token(&mut self, token_id: u8) -> Result<[u8; 8], Error> {
self.communicate(get_token::Command::new(token_id))
.await?
.try_into()
}
async fn get_true_random_entropy_source(&mut self) -> Result<Source, Error> {
self.communicate(get_true_random_entropy_source::Command)
.await?
.try_into()
}
async fn get_xncp_info(&mut self) -> Result<get_xncp_info::Payload, Error> {
self.communicate(get_xncp_info::Command).await?.try_into()
}
async fn nop(&mut self) -> Result<(), Error> {
self.communicate(nop::Command).await.map(drop)
}
async fn read_and_clear_counters(&mut self) -> Result<[u16; COUNTER_TYPE_COUNT], Error> {
self.communicate(read_and_clear_counters::Command)
.await
.map(Into::into)
}
async fn read_counters(&mut self) -> Result<[u16; COUNTER_TYPE_COUNT], Error> {
self.communicate(read_counters::Command)
.await
.map(Into::into)
}
async fn set_mfg_token(&mut self, token_id: Id, token: ByteSizedVec<u8>) -> Result<(), Error> {
self.communicate(set_mfg_token::Command::new(token_id, token))
.await?
.try_into()
}
async fn set_timer(
&mut self,
timer_id: u8,
duration: event::Duration,
repeat: bool,
) -> Result<(), Error> {
self.communicate(set_timer::Command::new(
timer_id,
duration.time(),
duration.units(),
repeat,
))
.await?
.try_into()
}
async fn set_token(&mut self, token_id: u8, token: [u8; 8]) -> Result<(), Error> {
self.communicate(set_token::Command::new(token_id, token))
.await?
.try_into()
}
}