use std::fs::File;
use std::os::raw::c_int;
use base::handle_eintr_errno;
use base::ioctl_ior_nr;
use crate::usb::backend::fido_backend::constants;
use crate::usb::backend::fido_backend::error::Error;
use crate::usb::backend::fido_backend::error::Result;
#[repr(C)]
#[derive(Clone)]
pub struct HidrawReportDescriptor {
pub size: u32,
pub value: [u8; constants::HID_MAX_DESCRIPTOR_SIZE],
}
pub const HID_IO_TYPE: u32 = 'H' as u32;
ioctl_ior_nr!(HIDIOCGRDESCSIZE, HID_IO_TYPE, 0x01, c_int);
ioctl_ior_nr!(HIDIOCGRDESC, HID_IO_TYPE, 0x02, HidrawReportDescriptor);
pub fn verify_is_fido_device(hidraw: &File) -> Result<()> {
let mut desc_size: c_int = 0;
unsafe {
let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(
hidraw,
HIDIOCGRDESCSIZE,
&mut desc_size
));
if ret < 0 || (desc_size as usize) < constants::HID_REPORT_DESC_HEADER.len() {
return Err(Error::InvalidHidrawDevice);
}
}
let mut descriptor = HidrawReportDescriptor {
size: desc_size as u32,
value: [0; constants::HID_MAX_DESCRIPTOR_SIZE],
};
unsafe {
let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(
hidraw,
HIDIOCGRDESC,
&mut descriptor
));
if ret < 0 {
return Err(Error::InvalidHidrawDevice);
}
}
if descriptor.value[..constants::HID_REPORT_DESC_HEADER.len()]
!= *constants::HID_REPORT_DESC_HEADER
{
return Err(Error::InvalidHidrawDevice);
}
Ok(())
}