Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for android no-rusb-open workaround #48

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

brandonros
Copy link

Let me know your thoughts.

use std::ffi::c_int;

use rusb::{GlobalContext, DeviceHandle, UsbContext};

pub fn libusb_init_from_fd(fd: i32) -> Option<DeviceHandle<GlobalContext>> {
    log::info!("libusb_init_from_fd fd = {fd}");
    // android workaround
    #[cfg(target_os = "android")]
    let _ = rusb::disable_device_discovery();
    // fd -> device_handle
    let global_context = GlobalContext::default();
    let libusb_context = global_context.as_raw();
    let mut fd_handle = std::ptr::null_mut();
    let ret_val = unsafe { libusb1_sys::libusb_wrap_sys_device(libusb_context, fd as *mut c_int, &mut fd_handle) };
    if ret_val != 0 {
        log::error!("libusb_wrap_sys_device failed ret_val = {ret_val}");
        return None;
    }
    let handle_ptr = std::ptr::NonNull::new(fd_handle).unwrap();
    let device_handle = unsafe { DeviceHandle::from_libusb(global_context, handle_ptr) };
    // return
    Some(device_handle)
}

#[no_mangle]
unsafe extern "C" fn libusb_init_from_fd_wrapper(fd: i32) {
    log::info!("libusb_init_from_fd_wrapper fd = {fd}");
    // do custom android libusb init
    let device_handle = usb::libusb_init_from_fd(fd).unwrap();
    // create tokio runtime
    let runtime = tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();
    // spawn usbip server on thread
    let _handle = std::thread::spawn(move || {
        let server = Arc::new(usbip::UsbIpServer::new_from_device_handle(device_handle));
        let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 3240);
        let _ = runtime.block_on(usbip::server(addr, server));
    });
}

Rust library that provides JNI for Java to call:

#[no_mangle]
pub extern "C" fn Java_com_redacted_redacted_RemoterWrapperLib_StartUsbIpHost(_env: JNIEnv, _obj: JObject) {
    // load library which has extra libusb_init_from_fd_wrapper export added to it
    let driver_filename = DRIVER_FILENAME.get().unwrap();
    let library = Library::load(&driver_filename).unwrap();
    // call libusb_init_from_fd_wrapper
    let fd = USB_DEVICE_FD.get().unwrap();
    let libusb_init_from_fd_wrapper: LibusbInitFromFdWrapperFn = unsafe { library.sym("libusb_init_from_fd_wrapper\0").unwrap() };
    unsafe {
        libusb_init_from_fd_wrapper(*fd);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant