use std::sync::Arc;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use crate::{
channel::HidppChannel,
event::EventEmitter,
feature::{CreatableFeature, EmittingFeature, Feature, event_payload},
};
pub struct WirelessDeviceStatusFeature {
chan: Arc<HidppChannel>,
emitter: Arc<EventEmitter<WirelessDeviceStatusEvent>>,
msg_listener_hdl: u32,
}
impl CreatableFeature for WirelessDeviceStatusFeature {
const ID: u16 = 0x1d4b;
const STARTING_VERSION: u8 = 0;
fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
let emitter = Arc::new(EventEmitter::new());
let hdl = chan.add_msg_listener({
let emitter = Arc::clone(&emitter);
move |raw, matched| {
let Some((func, payload)) =
event_payload(raw, matched, device_index, feature_index)
else {
return;
};
if func.to_lo() != 0 {
return;
}
let (Ok(status), Ok(request), Ok(reason)) = (
WirelessDeviceStatus::try_from(payload[0]),
WirelessDeviceStatusRequest::try_from(payload[1]),
WirelessDeviceStatusReason::try_from(payload[2]),
) else {
return;
};
emitter.emit(WirelessDeviceStatusEvent::StatusBroadcast(
WirelessDeviceStatusBroadcast {
status,
request,
reason,
},
));
}
});
Self {
chan,
emitter,
msg_listener_hdl: hdl,
}
}
}
impl Feature for WirelessDeviceStatusFeature {}
impl EmittingFeature<WirelessDeviceStatusEvent> for WirelessDeviceStatusFeature {
fn listen(&self) -> async_channel::Receiver<WirelessDeviceStatusEvent> {
self.emitter.create_receiver()
}
}
impl Drop for WirelessDeviceStatusFeature {
fn drop(&mut self) {
self.chan.remove_msg_listener(self.msg_listener_hdl);
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum WirelessDeviceStatusEvent {
StatusBroadcast(WirelessDeviceStatusBroadcast),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct WirelessDeviceStatusBroadcast {
pub status: WirelessDeviceStatus,
pub request: WirelessDeviceStatusRequest,
pub reason: WirelessDeviceStatusReason,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum WirelessDeviceStatus {
Unknown = 0x00,
Reconnection = 0x01,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum WirelessDeviceStatusRequest {
NoRequest = 0x00,
SoftwareReconfigurationNeeded = 0x01,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum WirelessDeviceStatusReason {
Unknown = 0x00,
PowerSwitchActivated = 0x01,
}