use crate::error::*;
use std::sync::{Arc};
use crate::adaptor::{CtxManager};
use crate::device::Device;
use crate::platform::*;
#[cfg(unix)]
use std::os::unix::io::RawFd;
#[derive(Clone)]
pub struct UsbManager{
ctx: Arc<Manager>
}
pub struct UsbManagerBuilder{
no_device_discovery: bool,
}
impl UsbManagerBuilder {
pub fn default()->Self{
Self{
no_device_discovery:false
}
}
#[cfg(libusb)]
#[cfg(all(not(target_os = "android"), unix))]
pub fn no_device_discovery(&mut self)-> &mut Self{
self.no_device_discovery=true;
self
}
#[cfg(libusb)]
pub fn build(&mut self)->Result<UsbManager>{
use libusb_src::*;
use ptr::Context;
let ctx = Context::new();
#[cfg(target_os = "android")]
{
self.no_device_discovery=true;
}
if self.no_device_discovery {
unsafe {
let r = libusb_set_option(ctx.0, LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
check_err(r)?;
}
}
let ctx = Manager::new(ctx)?;
let ctx = Arc::new(ctx);
Ok(UsbManager{
ctx
})
}
}
impl UsbManager {
pub fn builder()->UsbManagerBuilder{
UsbManagerBuilder::default()
}
pub fn init_default() ->Result<Self>{
Self::builder().build()
}
#[cfg(not(target_os = "android"))]
pub async fn device_list(&self)->Result<Vec<Device>>{
let ctx = self.ctx.clone();
let mut l = ctx.clone().device_list().await?;
let mut out = vec![];
while let Some(one) = l.pop() {
#[cfg(libusb)]
let dev = Device::new(one, ctx.clone());
out.push(dev);
}
Ok(out)
}
#[cfg(not(target_os = "android"))]
pub async fn open_device_with_vid_pid(&self, vendor_id: usize, product_id: usize)->Result<Device>{
let list = self.device_list().await?;
for device in list {
if device.vid() == vendor_id as u16 && device.pid() == product_id as u16 {
return Ok(device);
}
}
Err(Error::NotFound)
}
#[cfg(unix)]
pub fn open_device_with_fd(&self, fd: RawFd)->Result<Device>{
let d= self.ctx.open_device_with_fd(fd)?;
Ok(Device::new(d, self.ctx.clone()))
}
}