hidpp/feature/wireless_device_status/
mod.rs1use std::sync::Arc;
5
6use num_enum::{IntoPrimitive, TryFromPrimitive};
7
8use crate::{
9 channel::HidppChannel,
10 event::EventEmitter,
11 feature::{CreatableFeature, EmittingFeature, Feature, event_payload},
12};
13
14pub struct WirelessDeviceStatusFeature {
16 chan: Arc<HidppChannel>,
18
19 emitter: Arc<EventEmitter<WirelessDeviceStatusEvent>>,
21
22 msg_listener_hdl: u32,
26}
27
28impl CreatableFeature for WirelessDeviceStatusFeature {
29 const ID: u16 = 0x1d4b;
30 const STARTING_VERSION: u8 = 0;
31
32 fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
33 let emitter = Arc::new(EventEmitter::new());
34
35 let hdl = chan.add_msg_listener({
36 let emitter = Arc::clone(&emitter);
37
38 move |raw, matched| {
39 let Some((func, payload)) =
40 event_payload(raw, matched, device_index, feature_index)
41 else {
42 return;
43 };
44 if func.to_lo() != 0 {
46 return;
47 }
48
49 let (Ok(status), Ok(request), Ok(reason)) = (
50 WirelessDeviceStatus::try_from(payload[0]),
51 WirelessDeviceStatusRequest::try_from(payload[1]),
52 WirelessDeviceStatusReason::try_from(payload[2]),
53 ) else {
54 return;
55 };
56
57 emitter.emit(WirelessDeviceStatusEvent::StatusBroadcast(
58 WirelessDeviceStatusBroadcast {
59 status,
60 request,
61 reason,
62 },
63 ));
64 }
65 });
66
67 Self {
68 chan,
69 emitter,
70 msg_listener_hdl: hdl,
71 }
72 }
73}
74
75impl Feature for WirelessDeviceStatusFeature {}
76
77impl EmittingFeature<WirelessDeviceStatusEvent> for WirelessDeviceStatusFeature {
78 fn listen(&self) -> async_channel::Receiver<WirelessDeviceStatusEvent> {
79 self.emitter.create_receiver()
80 }
81}
82
83impl Drop for WirelessDeviceStatusFeature {
84 fn drop(&mut self) {
85 self.chan.remove_msg_listener(self.msg_listener_hdl);
86 }
87}
88
89#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "serde", derive(serde::Serialize))]
93#[non_exhaustive]
94pub enum WirelessDeviceStatusEvent {
95 StatusBroadcast(WirelessDeviceStatusBroadcast),
99}
100
101#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
104#[cfg_attr(feature = "serde", derive(serde::Serialize))]
105#[non_exhaustive]
106pub struct WirelessDeviceStatusBroadcast {
107 pub status: WirelessDeviceStatus,
109
110 pub request: WirelessDeviceStatusRequest,
112
113 pub reason: WirelessDeviceStatusReason,
115}
116
117#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
120#[cfg_attr(feature = "serde", derive(serde::Serialize))]
121#[non_exhaustive]
122#[repr(u8)]
123pub enum WirelessDeviceStatus {
124 Unknown = 0x00,
125 Reconnection = 0x01,
126}
127
128#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize))]
132#[non_exhaustive]
133#[repr(u8)]
134pub enum WirelessDeviceStatusRequest {
135 NoRequest = 0x00,
136 SoftwareReconfigurationNeeded = 0x01,
137}
138
139#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
142#[cfg_attr(feature = "serde", derive(serde::Serialize))]
143#[non_exhaustive]
144#[repr(u8)]
145pub enum WirelessDeviceStatusReason {
146 Unknown = 0x00,
147 PowerSwitchActivated = 0x01,
148}