use num_derive::FromPrimitive;
#[derive(Copy, Clone, Default, Debug)]
#[repr(C, packed)]
pub struct Device {
pub len: u8,
pub descriptor_type: u8,
pub cd_usb: u16,
pub class: u8,
pub subclass: u8,
pub protocol: u8,
pub max_packet_size0: u8,
pub vendor: u16,
pub product_id: u16,
pub device: u16,
pub manufacture: u8,
pub product: u8,
pub serial_number: u8,
pub num_configurations: u8,
}
impl Device {
pub fn max_packet_size(&self) -> u16 {
if let (3, _) = self.version() {
2_u16.pow(self.max_packet_size0.into())
} else {
self.max_packet_size0.into()
}
}
fn version(&self) -> (u8, u8) {
let cd_usb = self.cd_usb;
(
(cd_usb >> 8).try_into().unwrap(),
(cd_usb & 0xff).try_into().unwrap(),
)
}
pub fn is_refer_interface(&self) -> bool {
self.class == StandardUSBDeviceClassCode::ReferInterfaceDescriptor as u8
&& self.subclass == StandardUSBDeviceClassCode::ReferInterfaceDescriptor as u8
&& self.protocol == 0
}
}
#[derive(FromPrimitive, Copy, Clone, Debug)]
#[repr(u8)]
pub enum StandardUSBDeviceClassCode {
ReferInterfaceDescriptor = 0x00,
Audio = 0x01,
CommunicationsAndCDCControl = 0x02,
HID = 0x03,
Physical = 0x05,
Image = 0x06,
Printer = 0x07,
MassStorage = 0x08,
Hub = 0x09,
CDCData = 0x0A,
SmartCard = 0x0B,
ContentSecurity = 0x0D,
Video = 0x0E,
PersonalHealthcare = 0x0F,
AudioVideoDevices = 0x10,
BillboardDeviceClass = 0x11,
USBTypeCBridge = 0x12,
DiagnosticDevice = 0xDC,
WirelessController = 0xE0,
Miscellaneous = 0xEF,
ApplicationSpecific = 0xFE,
VendorSpecific = 0xFF,
}