use std::sync::Arc;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use crate::{
channel::HidppChannel,
receiver::{RECEIVER_DEVICE_INDEX, ReceiverError},
};
pub const VPID_PAIRS: &[(u16, u16)] = &[(0x046d, 0xc52b), (0x046d, 0xc532)];
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum Register {
ReceiverInfo = 0xb5,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum InfoSubRegister {
ReceiverInfo = 0x03,
}
#[derive(Clone)]
pub struct Receiver {
chan: Arc<HidppChannel>,
}
impl Receiver {
pub fn new(chan: Arc<HidppChannel>) -> Result<Self, ReceiverError> {
if !VPID_PAIRS.contains(&(chan.vendor_id, chan.product_id)) {
return Err(ReceiverError::UnknownReceiver);
}
Ok(Receiver { chan })
}
pub async fn get_receiver_info(&self) -> Result<ReceiverInfo, ReceiverError> {
let response = self
.chan
.read_long_register(
RECEIVER_DEVICE_INDEX,
Register::ReceiverInfo.into(),
[InfoSubRegister::ReceiverInfo.into(), 0, 0],
)
.await?;
Ok(ReceiverInfo {
serial_number: hex::encode_upper(&response[1..=4]),
pairing_slots: response[6],
})
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct ReceiverInfo {
pub serial_number: String,
pub pairing_slots: u8,
}