usbw 0.0.2

basic USB driver. So far just a wrapper for `rusb`. Planning on wrapping `libusb` later
Documentation
use usbw::libusb::device::Device;
use usbw::libusb::error::Error;

const WIRELESS_CONTROLLER_CLASS: u8 = 0xE0;
const SUBCLASS: u8 = 0x01;
const BLUETOOTH_PROGRAMMING_INTERFACE_PROTOCOL: u8 = 0x01;
pub fn has_bluetooth_interface(device: &Device) -> Result<bool, Error> {
    match device.active_config_descriptor() {
        Ok(config) => Ok(config
            .interfaces()
            .iter()
            .next()
            .and_then(|i| {
                i.descriptors().iter().next().map(|d| {
                    d.class_code() == WIRELESS_CONTROLLER_CLASS
                        && d.sub_class_code() == SUBCLASS
                        && d.protocol_code() == BLUETOOTH_PROGRAMMING_INTERFACE_PROTOCOL
                })
            })
            .unwrap_or(false)),
        Err(usbw::libusb::error::Error::NotFound) => Ok(false),
        Err(e) => Err(e),
    }
}

pub fn bluetooth_adapters<'a>(
    i: impl Iterator<Item = Device> + 'a,
) -> impl Iterator<Item = Result<Device, Error>> + 'a {
    i.filter_map(|d| match has_bluetooth_interface(&d) {
        Ok(true) => Some(Ok(d)),
        Ok(false) => None,
        Err(e) => Some(Err(e)),
    })
}

pub fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("can't make async runtime");
    runtime.block_on(main_async())?;
    Ok(())
}
pub const HCI_EVENT_ENDPOINT: u8 = 0x81;
async fn main_async() -> Result<(), Box<dyn std::error::Error>> {
    println!("starting");
    let context = usbw::libusb::context::Context::default()?;
    println!("context made");
    let device_list = context.device_list();
    for d in bluetooth_adapters(device_list.iter()) {
        println!("{:?}", d?.device_descriptor()?);
    }
    println!("opening first device...");
    let mut devices = bluetooth_adapters(device_list.iter());
    let handle = loop {
        let device = devices
            .next()
            .ok_or_else(|| String::from("Device Not Found"))??;
        println!("using {:?}", device);
        match device.open() {
            Ok(adapter) => break adapter,
            Err(usbw::libusb::error::Error::NotSupported) => (),
            Err(e) => Err(e)?,
        }
    };
    let context = context.start_async();
    let handle = context.make_async_device(handle);
    let mut adapter = handle;
    println!("reset");
    adapter.handle_ref().reset()?;
    println!(
        "active configuration {:?}",
        adapter.handle_ref().active_configuration()
    );
    println!("claim");
    adapter.handle_mut().claim_interface(0)?;
    println!("write!");
    let _n = adapter
        .control_write(
            0x20,
            0,
            0,
            0,
            &[0x03, 0x0C, 0x00],
            core::time::Duration::from_secs(1),
        )
        .await?;
    println!("reading a byte");
    let mut out = [0; 7];
    adapter
        .interrupt_read(
            HCI_EVENT_ENDPOINT,
            &mut out,
            core::time::Duration::from_secs(1),
        )
        .await?;
    println!("out {:?}", out);
    Ok(())
}