summary refs log tree commit diff
path: root/usb_util/src/libusb_context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'usb_util/src/libusb_context.rs')
-rw-r--r--usb_util/src/libusb_context.rs268
1 files changed, 0 insertions, 268 deletions
diff --git a/usb_util/src/libusb_context.rs b/usb_util/src/libusb_context.rs
deleted file mode 100644
index 17a77f0..0000000
--- a/usb_util/src/libusb_context.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2018 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std;
-#[allow(unused_imports)]
-use std::os::raw::{c_long, c_short, c_void};
-use std::os::unix::io::RawFd;
-use std::sync::Arc;
-
-use crate::bindings;
-#[cfg(feature = "sandboxed-libusb")]
-use crate::device_handle::DeviceHandle;
-use crate::error::{Error, Result};
-use crate::hotplug::{hotplug_cb, UsbHotplugHandler, UsbHotplugHandlerHolder};
-use crate::libusb_device::LibUsbDevice;
-
-use sync::Mutex;
-
-pub struct LibUsbContextInner {
-    context: *mut bindings::libusb_context,
-    pollfd_change_handler: Mutex<Option<Box<PollfdChangeHandlerHolder>>>,
-}
-
-// Safe because libusb_context could be accessed from multiple threads safely.
-unsafe impl Send for LibUsbContextInner {}
-unsafe impl Sync for LibUsbContextInner {}
-
-impl LibUsbContextInner {
-    /// Remove the previous registered notifiers.
-    pub fn remove_pollfd_notifiers(&self) {
-        // Safe because 'self.context' is valid.
-        unsafe {
-            bindings::libusb_set_pollfd_notifiers(self.context, None, None, std::ptr::null_mut());
-        }
-    }
-}
-
-impl Drop for LibUsbContextInner {
-    fn drop(&mut self) {
-        // Avoid pollfd change handler call when libusb_exit is called.
-        self.remove_pollfd_notifiers();
-        // Safe beacuse 'self.context' points to a valid context allocated by libusb_init.
-        unsafe {
-            bindings::libusb_exit(self.context);
-        }
-    }
-}
-
-/// Wrapper for libusb_context. The libusb libary initialization/deinitialization
-/// is managed by this context.
-/// See: http://libusb.sourceforge.net/api-1.0/group__libusb__lib.html
-#[derive(Clone)]
-pub struct LibUsbContext {
-    inner: Arc<LibUsbContextInner>,
-}
-
-impl LibUsbContext {
-    /// Create a new LibUsbContext.
-    pub fn new() -> Result<LibUsbContext> {
-        let mut ctx: *mut bindings::libusb_context = std::ptr::null_mut();
-        // Safe because '&mut ctx' points to a valid memory (on stack).
-        try_libusb!(unsafe { bindings::libusb_init(&mut ctx) });
-        Ok(LibUsbContext {
-            inner: Arc::new(LibUsbContextInner {
-                context: ctx,
-                pollfd_change_handler: Mutex::new(None),
-            }),
-        })
-    }
-
-    #[cfg(feature = "sandboxed-libusb")]
-    pub fn handle_from_file(&self, f: std::fs::File) -> Result<DeviceHandle> {
-        use std::os::unix::io::IntoRawFd;
-
-        let fd = f.into_raw_fd();
-        let mut handle: *mut bindings::libusb_device_handle = std::ptr::null_mut();
-        // Safe because fd is valid and owned, and '&mut handle' points to valid memory.
-        try_libusb!(unsafe {
-            bindings::libusb_wrap_sys_device(self.inner.context, fd as c_long, &mut handle)
-        });
-        unsafe { Ok(DeviceHandle::new(self.inner.clone(), handle)) }
-    }
-
-    /// Returns a list of USB devices currently attached to the system.
-    pub fn get_device_iter(&self) -> Result<DeviceIter> {
-        let mut list: *mut *mut bindings::libusb_device = std::ptr::null_mut();
-        // Safe because 'inner.context' points to a valid context and '&mut list' points to a valid
-        // memory.
-        try_libusb!(unsafe { bindings::libusb_get_device_list(self.inner.context, &mut list) });
-
-        Ok(DeviceIter {
-            context: self.inner.clone(),
-            list,
-            index: 0,
-        })
-    }
-
-    /// Check at runtime if the loaded library has a given capability.
-    pub fn has_capability(&self, cap: u32) -> bool {
-        // Safe because libusb_init is called before this call happens.
-        unsafe { bindings::libusb_has_capability(cap) != 0 }
-    }
-
-    /// Return an iter of poll fds. Those fds that should be polled to handle libusb events.
-    pub fn get_pollfd_iter(&self) -> PollFdIter {
-        // Safe because 'inner.context' is inited.
-        let list: *mut *const bindings::libusb_pollfd =
-            unsafe { bindings::libusb_get_pollfds(self.inner.context) };
-        PollFdIter { list, index: 0 }
-    }
-
-    /// Handle libusb events in a non block way.
-    pub fn handle_events_nonblock(&self) {
-        static mut zero_time: bindings::timeval = bindings::timeval {
-            tv_sec: 0,
-            tv_usec: 0,
-        };
-        // Safe because 'inner.context' points to valid context.
-        unsafe {
-            bindings::libusb_handle_events_timeout_completed(
-                self.inner.context,
-                &mut zero_time as *mut bindings::timeval,
-                std::ptr::null_mut(),
-            );
-        }
-    }
-
-    /// Set a handler that could handle pollfd change events.
-    pub fn set_pollfd_notifiers(&self, handler: Box<dyn LibUsbPollfdChangeHandler>) {
-        // LibUsbContext is alive when any libusb related function is called. It owns the handler,
-        // thus the handler memory is always valid when callback is invoked.
-        let holder = Box::new(PollfdChangeHandlerHolder { handler });
-        let raw_holder = Box::into_raw(holder);
-        unsafe {
-            bindings::libusb_set_pollfd_notifiers(
-                self.inner.context,
-                Some(pollfd_added_cb),
-                Some(pollfd_removed_cb),
-                raw_holder as *mut c_void,
-            );
-        }
-        // Safe because raw_holder is from Boxed pointer.
-        let holder = unsafe { Box::from_raw(raw_holder) };
-        *self.inner.pollfd_change_handler.lock() = Some(holder);
-    }
-
-    /// Remove the previous registered notifiers.
-    pub fn remove_pollfd_notifiers(&self) {
-        self.inner.remove_pollfd_notifiers();
-    }
-
-    /// Set a callback that could handle hotplug events. Currently, this function listen to hotplug
-    /// event of all devices.
-    pub fn set_hotplug_cb<H: UsbHotplugHandler + Sized>(&self, handler: H) -> Result<()> {
-        let event = bindings::LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
-            | bindings::LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
-        let holder = UsbHotplugHandlerHolder::new(self.inner.clone(), handler);
-        let raw_holder = Box::into_raw(holder);
-        // Safe becuase hotpulg cb is a vaild c function and raw_holder points to memory for that
-        // function argument.
-        try_libusb!(unsafe {
-            bindings::libusb_hotplug_register_callback(
-                self.inner.context,
-                event,
-                bindings::LIBUSB_HOTPLUG_NO_FLAGS,
-                bindings::LIBUSB_HOTPLUG_MATCH_ANY,
-                bindings::LIBUSB_HOTPLUG_MATCH_ANY,
-                bindings::LIBUSB_HOTPLUG_MATCH_ANY,
-                Some(hotplug_cb),
-                raw_holder as *mut c_void,
-                std::ptr::null_mut(),
-            )
-        });
-        Ok(())
-    }
-}
-
-/// Iterator for device list.
-pub struct DeviceIter {
-    context: Arc<LibUsbContextInner>,
-    list: *mut *mut bindings::libusb_device,
-    index: isize,
-}
-
-impl Drop for DeviceIter {
-    fn drop(&mut self) {
-        // Safe because 'self.list' is inited by a valid pointer from libusb_get_device_list.
-        unsafe {
-            bindings::libusb_free_device_list(self.list, 1);
-        }
-    }
-}
-
-impl Iterator for DeviceIter {
-    type Item = LibUsbDevice;
-
-    fn next(&mut self) -> Option<LibUsbDevice> {
-        // Safe becuase 'self.list' is valid, the list is null terminated.
-        unsafe {
-            let current_ptr = self.list.offset(self.index);
-            if (*current_ptr).is_null() {
-                return None;
-            }
-            self.index += 1;
-            Some(LibUsbDevice::new(self.context.clone(), *current_ptr))
-        }
-    }
-}
-
-/// Iterator for pollfds.
-pub struct PollFdIter {
-    list: *mut *const bindings::libusb_pollfd,
-    index: isize,
-}
-
-impl Drop for PollFdIter {
-    fn drop(&mut self) {
-        // Safe because 'self.list' points to valid memory of pollfd list.
-        unsafe {
-            bindings::libusb_free_pollfds(self.list);
-        }
-    }
-}
-
-impl Iterator for PollFdIter {
-    type Item = bindings::libusb_pollfd;
-
-    fn next(&mut self) -> Option<bindings::libusb_pollfd> {
-        // Safe because 'self.index' never grow out of the null pointer index.
-        unsafe {
-            let current_ptr = self.list.offset(self.index);
-            if (*current_ptr).is_null() {
-                return None;
-            }
-
-            self.index += 1;
-            // Safe because '*current_ptr' is not null.
-            Some(**current_ptr)
-        }
-    }
-}
-
-/// Trait for handler that handles Pollfd Change events.
-pub trait LibUsbPollfdChangeHandler: Send + Sync + 'static {
-    fn add_poll_fd(&self, fd: RawFd, events: c_short);
-    fn remove_poll_fd(&self, fd: RawFd);
-}
-
-// This struct owns LibUsbPollfdChangeHandler. We need it because it's not possible to cast void
-// pointer to trait pointer.
-struct PollfdChangeHandlerHolder {
-    handler: Box<dyn LibUsbPollfdChangeHandler>,
-}
-
-// This function is safe when user_data points to valid PollfdChangeHandlerHolder.
-unsafe extern "C" fn pollfd_added_cb(fd: RawFd, events: c_short, user_data: *mut c_void) {
-    // Safe because user_data was casted from holder.
-    let keeper = &*(user_data as *mut PollfdChangeHandlerHolder);
-    keeper.handler.add_poll_fd(fd, events);
-}
-
-// This function is safe when user_data points to valid PollfdChangeHandlerHolder.
-unsafe extern "C" fn pollfd_removed_cb(fd: RawFd, user_data: *mut c_void) {
-    // Safe because user_data was casted from holder.
-    let keeper = &*(user_data as *mut PollfdChangeHandlerHolder);
-    keeper.handler.remove_poll_fd(fd);
-}