Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions embedded-service/src/power/policy/action/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ use crate::power::policy::{ConsumerPowerCapability, Error, ProviderPowerCapabili
use crate::{info, trace};

/// Device state machine control
pub struct Device<'a, S: Kind> {
device: &'a device::Device,
pub struct Device<'a, S: Kind, const N: usize> {
device: &'a device::Device<N>,
_state: core::marker::PhantomData<S>,
}

/// Enum to contain any state
pub enum AnyState<'a> {
pub enum AnyState<'a, const N: usize> {
/// Detached
Detached(Device<'a, Detached>),
Detached(Device<'a, Detached, N>),
/// Idle
Idle(Device<'a, Idle>),
Idle(Device<'a, Idle, N>),
/// Connected Consumer
ConnectedConsumer(Device<'a, ConnectedConsumer>),
ConnectedConsumer(Device<'a, ConnectedConsumer, N>),
/// Connected Provider
ConnectedProvider(Device<'a, ConnectedProvider>),
ConnectedProvider(Device<'a, ConnectedProvider, N>),
}

impl AnyState<'_> {
impl<const N: usize> AnyState<'_, N> {
/// Return the kind of the contained state
pub fn kind(&self) -> StateKind {
match self {
Expand All @@ -33,22 +33,24 @@ impl AnyState<'_> {
}
}

impl<'a, S: Kind> Device<'a, S> {
impl<'a, S: Kind, const N: usize> Device<'a, S, N> {
/// Create a new state machine
pub(crate) fn new(device: &'a device::Device) -> Self {
pub(crate) fn new(device: &'a device::Device<N>) -> Self {
Self {
device,
_state: core::marker::PhantomData,
}
}

/// Detach the device
pub async fn detach(self) -> Result<Device<'a, Detached>, Error> {
pub async fn detach(self) -> Result<Device<'a, Detached, N>, Error> {
info!("Received detach from device {}", self.device.id().0);
self.device.set_state(device::State::Detached).await;
self.device.update_consumer_capability(None).await;
self.device.update_requested_provider_capability(None).await;
policy::send_request(self.device.id(), policy::RequestData::NotifyDetached)
self.device
.context_ref
.send_request(self.device.id(), policy::RequestData::NotifyDetached)
.await?
.complete_or_err()?;
Ok(Device::new(self.device))
Expand All @@ -60,7 +62,9 @@ impl<'a, S: Kind> Device<'a, S> {
self.device.update_consumer_capability(None).await;
self.device.update_requested_provider_capability(None).await;
self.device.set_state(device::State::Idle).await;
policy::send_request(self.device.id(), policy::RequestData::NotifyDisconnect)
self.device
.context_ref
.send_request(self.device.id(), policy::RequestData::NotifyDisconnect)
.await?
.complete_or_err()
}
Expand All @@ -76,12 +80,14 @@ impl<'a, S: Kind> Device<'a, S> {
capability
);
self.device.update_consumer_capability(capability).await;
policy::send_request(
self.device.id(),
policy::RequestData::NotifyConsumerCapability(capability),
)
.await?
.complete_or_err()
self.device
.context_ref
.send_request(
self.device.id(),
policy::RequestData::NotifyConsumerCapability(capability),
)
.await?
.complete_or_err()
}

/// Request the given power from the power policy service
Expand All @@ -97,29 +103,33 @@ impl<'a, S: Kind> Device<'a, S> {

info!("Request provide from device {}, {:#?}", self.device.id().0, capability);
self.device.update_requested_provider_capability(Some(capability)).await;
policy::send_request(
self.device.id(),
policy::RequestData::RequestProviderCapability(capability),
)
.await?
.complete_or_err()?;
self.device
.context_ref
.send_request(
self.device.id(),
policy::RequestData::RequestProviderCapability(capability),
)
.await?
.complete_or_err()?;
Ok(())
}
}

impl<'a> Device<'a, Detached> {
impl<'a, const N: usize> Device<'a, Detached, N> {
/// Attach the device
pub async fn attach(self) -> Result<Device<'a, Idle>, Error> {
pub async fn attach(self) -> Result<Device<'a, Idle, N>, Error> {
info!("Received attach from device {}", self.device.id().0);
self.device.set_state(device::State::Idle).await;
policy::send_request(self.device.id(), policy::RequestData::NotifyAttached)
self.device
.context_ref
.send_request(self.device.id(), policy::RequestData::NotifyAttached)
.await?
.complete_or_err()?;
Ok(Device::new(self.device))
}
}

impl Device<'_, Idle> {
impl<const N: usize> Device<'_, Idle, N> {
/// Notify the power policy service of an updated consumer power capability
pub async fn notify_consumer_power_capability(
&self,
Expand All @@ -134,25 +144,26 @@ impl Device<'_, Idle> {
}
}

impl<'a> Device<'a, ConnectedConsumer> {
impl<'a, const N: usize> Device<'a, ConnectedConsumer, N> {
/// Disconnect this device
pub async fn disconnect(self) -> Result<Device<'a, Idle>, Error> {
pub async fn disconnect(self) -> Result<Device<'a, Idle, N>, Error> {
self.disconnect_internal().await?;
Ok(Device::new(self.device))
}

/// Notify the power policy service of an updated consumer power capability
pub async fn notify_consumer_power_capability(
&self,

capability: Option<ConsumerPowerCapability>,
) -> Result<(), Error> {
self.notify_consumer_power_capability_internal(capability).await
}
}

impl<'a> Device<'a, ConnectedProvider> {
impl<'a, const N: usize> Device<'a, ConnectedProvider, N> {
/// Disconnect this device
pub async fn disconnect(self) -> Result<Device<'a, Idle>, Error> {
pub async fn disconnect(self) -> Result<Device<'a, Idle, N>, Error> {
self.disconnect_internal().await?;
Ok(Device::new(self.device))
}
Expand All @@ -165,6 +176,7 @@ impl<'a> Device<'a, ConnectedProvider> {
/// Notify the power policy service of an updated consumer power capability
pub async fn notify_consumer_power_capability(
&self,

capability: Option<ConsumerPowerCapability>,
) -> Result<(), Error> {
self.notify_consumer_power_capability_internal(capability).await
Expand Down
52 changes: 26 additions & 26 deletions embedded-service/src/power/policy/action/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ use crate::{error, info};
const DEFAULT_TIMEOUT: Duration = Duration::from_millis(5000);

/// Policy state machine control
pub struct Policy<'a, S: Kind> {
device: &'a device::Device,
pub struct Policy<'a, S: Kind, const N: usize> {
device: &'a device::Device<N>,
_state: core::marker::PhantomData<S>,
}

/// Enum to contain any state
pub enum AnyState<'a> {
pub enum AnyState<'a, const N: usize> {
/// Detached
Detached(Policy<'a, Detached>),
Detached(Policy<'a, Detached, N>),
/// Idle
Idle(Policy<'a, Idle>),
Idle(Policy<'a, Idle, N>),
/// Connected Consumer
ConnectedConsumer(Policy<'a, ConnectedConsumer>),
ConnectedConsumer(Policy<'a, ConnectedConsumer, N>),
/// Connected Provider
ConnectedProvider(Policy<'a, ConnectedProvider>),
ConnectedProvider(Policy<'a, ConnectedProvider, N>),
}

impl AnyState<'_> {
impl<const N: usize> AnyState<'_, N> {
/// Return the kind of the contained state
pub fn kind(&self) -> StateKind {
match self {
Expand All @@ -38,9 +38,9 @@ impl AnyState<'_> {
}
}

impl<'a, S: Kind> Policy<'a, S> {
impl<'a, S: Kind, const N: usize> Policy<'a, S, N> {
/// Create a new state machine
pub(crate) fn new(device: &'a device::Device) -> Self {
pub(crate) fn new(device: &'a device::Device<N>) -> Self {
Self {
device,
_state: core::marker::PhantomData,
Expand Down Expand Up @@ -97,14 +97,14 @@ impl<'a, S: Kind> Policy<'a, S> {
}

// The policy can do nothing when no device is attached
impl Policy<'_, Detached> {}
impl<const N: usize> Policy<'_, Detached, N> {}

impl<'a> Policy<'a, Idle> {
impl<'a, const N: usize> Policy<'a, Idle, N> {
/// Connect this device as a consumer
pub async fn connect_as_consumer_no_timeout(
self,
capability: ConsumerPowerCapability,
) -> Result<Policy<'a, ConnectedConsumer>, Error> {
) -> Result<Policy<'a, ConnectedConsumer, N>, Error> {
info!("Device {} connecting as consumer", self.device.id().0);

self.device
Expand All @@ -122,7 +122,7 @@ impl<'a> Policy<'a, Idle> {
pub async fn connect_consumer(
self,
capability: ConsumerPowerCapability,
) -> Result<Policy<'a, ConnectedConsumer>, Error> {
) -> Result<Policy<'a, ConnectedConsumer, N>, Error> {
match with_timeout(DEFAULT_TIMEOUT, self.connect_as_consumer_no_timeout(capability)).await {
Ok(r) => r,
Err(TimeoutError) => Err(Error::Timeout),
Expand All @@ -133,7 +133,7 @@ impl<'a> Policy<'a, Idle> {
pub async fn connect_provider_no_timeout(
self,
capability: ProviderPowerCapability,
) -> Result<Policy<'a, ConnectedProvider>, Error> {
) -> Result<Policy<'a, ConnectedProvider, N>, Error> {
self.connect_as_provider_internal_no_timeout(capability)
.await
.map(|_| Policy::new(self.device))
Expand All @@ -143,30 +143,30 @@ impl<'a> Policy<'a, Idle> {
pub async fn connect_provider(
self,
capability: ProviderPowerCapability,
) -> Result<Policy<'a, ConnectedProvider>, Error> {
) -> Result<Policy<'a, ConnectedProvider, N>, Error> {
self.connect_provider_internal(capability)
.await
.map(|_| Policy::new(self.device))
}
}

impl<'a> Policy<'a, ConnectedConsumer> {
impl<'a, const N: usize> Policy<'a, ConnectedConsumer, N> {
/// Disconnect this device
pub async fn disconnect_no_timeout(self) -> Result<Policy<'a, Idle>, Error> {
pub async fn disconnect_no_timeout(self) -> Result<Policy<'a, Idle, N>, Error> {
self.disconnect_internal_no_timeout()
.await
.map(|_| Policy::new(self.device))
}

/// Disconnect this device
pub async fn disconnect(self) -> Result<Policy<'a, Idle>, Error> {
pub async fn disconnect(self) -> Result<Policy<'a, Idle, N>, Error> {
self.disconnect_internal().await.map(|_| Policy::new(self.device))
}
}

impl<'a> Policy<'a, ConnectedProvider> {
impl<'a, const N: usize> Policy<'a, ConnectedProvider, N> {
/// Disconnect this device
pub async fn disconnect_no_timeout(self) -> Result<Policy<'a, Idle>, Error> {
pub async fn disconnect_no_timeout(self) -> Result<Policy<'a, Idle, N>, Error> {
if let Err(e) = self.disconnect_internal_no_timeout().await {
error!("Error disconnecting device {}: {:?}", self.device.id().0, e);
return Err(e);
Expand All @@ -175,7 +175,7 @@ impl<'a> Policy<'a, ConnectedProvider> {
}

/// Disconnect this device
pub async fn disconnect(self) -> Result<Policy<'a, Idle>, Error> {
pub async fn disconnect(self) -> Result<Policy<'a, Idle, N>, Error> {
match with_timeout(DEFAULT_TIMEOUT, self.disconnect_no_timeout()).await {
Ok(r) => r,
Err(TimeoutError) => Err(Error::Timeout),
Expand All @@ -186,7 +186,7 @@ impl<'a> Policy<'a, ConnectedProvider> {
pub async fn connect_as_consumer_no_timeout(
self,
capability: ConsumerPowerCapability,
) -> Result<Policy<'a, ConnectedConsumer>, Error> {
) -> Result<Policy<'a, ConnectedConsumer, N>, Error> {
info!("Device {} connecting as consumer", self.device.id().0);

self.device
Expand All @@ -204,7 +204,7 @@ impl<'a> Policy<'a, ConnectedProvider> {
pub async fn connect_consumer(
self,
capability: ConsumerPowerCapability,
) -> Result<Policy<'a, ConnectedConsumer>, Error> {
) -> Result<Policy<'a, ConnectedConsumer, N>, Error> {
match with_timeout(DEFAULT_TIMEOUT, self.connect_as_consumer_no_timeout(capability)).await {
Ok(r) => r,
Err(TimeoutError) => Err(Error::Timeout),
Expand All @@ -215,7 +215,7 @@ impl<'a> Policy<'a, ConnectedProvider> {
pub async fn connect_provider_no_timeout(
&self,
capability: ProviderPowerCapability,
) -> Result<Policy<'a, ConnectedProvider>, Error> {
) -> Result<Policy<'a, ConnectedProvider, N>, Error> {
self.connect_as_provider_internal_no_timeout(capability)
.await
.map(|_| Policy::new(self.device))
Expand All @@ -225,7 +225,7 @@ impl<'a> Policy<'a, ConnectedProvider> {
pub async fn connect_provider(
&self,
capability: ProviderPowerCapability,
) -> Result<Policy<'a, ConnectedProvider>, Error> {
) -> Result<Policy<'a, ConnectedProvider, N>, Error> {
self.connect_provider_internal(capability)
.await
.map(|_| Policy::new(self.device))
Expand Down
Loading