Libusb_open_device_with_vid_pid falló al intentar acceder al dispositivo USB

Estoy tratando de obtener un dispositivo USB para conectarse a un dispositivo Android 5.1.1. Anteriormente había estado usando libusb regular para KitKat, pero Lollipop ha aumentado la seguridad y esto ya no funciona.

Esto está bien documentado, requiriendo que root establezca el nivel de SELinux. No quiero tener que enraizar el dispositivo para que el dispositivo USB se conecte a él.

Después de mirar a mi alrededor, me encontré con esta respuesta y he intentado esta bifurcación libusb , sin embargo ahora estoy recibiendo un nuevo error

libusb_open_device_with_vid_pid (29c2) failed. Failed to setup USB usb_setup: -1 

No he cambiado nada del código, sólo la biblioteca.

¿Es esto todavía un problema de permiso, o hay algo que me falta que hará que esto funcione?

    Los siguientes pasos se pueden utilizar para resolver los problemas que mencionó.

    El proceso de montaje del dispositivo como almacenamiento masivo USB es inconsistente entre los dispositivos y el fabricante. Algunos dispositivos como el Nexus S ofrecen "Activar el almacenamiento USB" al conectar el dispositivo al escritorio mediante un cable USB. Otros dispositivos como el Galaxy S3 requieren una aplicación para lanzar el dispositivo como almacenamiento masivo. De cualquier manera, los dispositivos Android suelen ofrecer tal característica, y tendrás que crear un archivo que coincida con la especificación del fabricante de tu dispositivo.

    Es necesario agregar al archivo de manifiesto de la aplicación antes de trabajar con las API de host USB:

    • Debido a que no todos los dispositivos con Android están garantizados para admitir las API de host USB, incluya un elemento que declare que su aplicación utiliza la función android.hardware.usb.host.
    • Si desea que su aplicación sea notificada de un dispositivo USB conectado, especifique un par de elementos y para la intención de android.hardware.usb.action.USB_DEVICE_ATTACHED en su actividad principal.

    Agregue USB_DEVICE_ATTACHED a su archivo manisfest:

     <manifest ...> <uses-feature android:name="android.hardware.usb.host" /> <uses-sdk android:minSdkVersion="12" /> ... <application> <activity ...> ... <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity> </application> </manifest> 

    Para ayudar a su APP a descubrir un dispositivo USB en particular, puede utilizar filtro de intenciones:

     <activity ...> ... <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity> 

    También tiene que especificar su dispositivo y su proveedor:

     <?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="1234" product-id="5678" /> </resources> 

    Esto debería ser suficiente para hacer frente a su conexión de host USB . Ahora llame al USB:

     int LIBUSB_CALL libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd); 

    Utilice el descriptor para abrir la conexión al dispositivo usb , por ejemplo:

     UsbManager myUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); UsbAccessory myUsbAccessory = (myUsbManager.getAccessoryList())[0]; ParcelFileDescriptor pfd = myUsbManager.openAccessory(myUsbAccessory); FileDescriptor fileDescriptor = pfd.getFileDescriptor(); FileInputStream myFileInputStream = new FileInputStream(fileDescriptor); FileOutputStream myFileOutputStream = new FileOutputStream(fileDescriptor); 

    Si todavía tienes problemas con el nivel de SELinux, aquí tienes algunas ediciones que puedes usar para hacer que tu programa funcione sin problemas:

     // default.prop ro.secure=1 -----------------> ro.secure=0 ro.adb.secure=1 -----------------> ro.adb.secure=0 //init.rc setsebool debugfs 1 --------> setsebool debugfs 0 setenforce 0 setprop selinux.reload_policy 1 -------> setprop selinux.reload_policy 0 // init.target.rc setprop selinux.reload_policy 1 -----> setprop selinux.reload_policy 0 

    Como SELinux se establece de forma predeterminada para reforzar la seguridad más alta y desea conceder a un cliente acceso a su dispositivo Android a través de USB.

    Introduzca aquí la descripción de la imagen

    Dependiendo de su marca y modelo de Android, pruebe a desenchufar el cable USB que conecta su dispositivo y el escritorio y vuelva a conectarlo. Se le pedirá que encienda el almacenamiento USB. Si este es el caso, continúa e intenta acceder a Configuración → Más … en Android y busca una opción de almacenamiento masivo USB.

    http://www.pocketables.com/images/old/6a00d83451c9ec69e201675f40c44a970b-500wi.png

    También puede buscar el proceso de almacenamiento masivo USB recomendado por el fabricante de su dispositivo. Cuando activa el almacenamiento USB, el dispositivo le permite saber que algunas aplicaciones se detendrán, adelante y Aceptar. Ahora vaya a su computadora de escritorio y busque su medio de almacenamiento masivo USB, a menudo llamado NO NAME si no lo ha cambiado de nombre. Haga clic en su dispositivo de almacenamiento masivo, y justo allí en la carpeta pie, busque un archivo llamado data.tsv.

    Introduzca aquí la descripción de la imagen

    También puede comprobar data.tsv abriéndolo en su editor de texto favorito. Encontrará dos columnas cuidadosamente separadas por una pestaña; En cada fila, encontrará un par de valores enteros. Esto es perfectamente suficiente para nuestro proyecto. Los proyectos de datos más complejos normalmente requieren un identificador único para cada fila, una fila en una tabla para apuntar a un registro específico en otro.

    Introduzca aquí la descripción de la imagen

    De acuerdo con su entorno de desarrollo , también tiene que ajustar sus ajustes en consecuencia. Si se está desarrollando en Windows, siga las instrucciones de instalación del controlador USB disponibles . Si está desarrollando Linux, siga las instrucciones para configurar su dispositivo para el desarrollo.

    Introduzca aquí la descripción de la imagen

    Además, también vale la pena mencionar que muchos dispositivos lanzados anteriormente con Android sólo son capaces de actuar como un dispositivo USB y no puede iniciar las conexiones con dispositivos USB externos. La compatibilidad con accesorio abierto de Android (AOA) supera esta limitación y le permite crear accesorios que pueden interactuar con un surtido de dispositivos con tecnología Android permitiendo que el accesorio inicie la conexión . Un ejemplo de uso común de Android Open Accessory se puede encontrar en el proyecto: grabar y reproducir audio utilizando el modo de host USB – que por supuesto requiere el modo USB para estar en funcionamiento.

    Introduzca aquí la descripción de la imagen

    Poner a Android para comunicarse a través de USB con microcontroladores Arduino es también un tipo de implementación que mostró ser muy exitosa recientemente, ya que le permite ampliar sus capacidades de Android integrando características adicionales a través de un enfoque de solución multi-dispositivo. Un típico Arduino Sketch para permitir la comunicación del dispositivo con tu dispositivo USB Android sería así:

     // the USB Host libraries #include <Max3421e.h> #include <Usb.h> // the AOA library #include <AndroidAccessory.h> void setup(); void loop(); void setup() { // start serial debugging Serial.begin(115200); Serial.print("\r\nADK has run setup()."); Serial.println("Ready to start USB communication..."); } void loop() { // example - read the voltage from a sensor uint16_t val; val = analogRead(TEMP_SENSOR); // or any sort of input Serial.println(val,HEX); Serial.write(val); // Delay for 100 milliseconds. delay(100); } 

    Todos los proyectos de Arduino deben tener un método setup () y un método loop () declarado de lo contrario su Android no se comunicará correctamente.

    También recuerde que una lista de requisitos mínimos necesarios para usar AOA:

    • Un dispositivo Android compatible con AOA. Para probar la compatibilidad antes de probar este ejemplo, consulte la sección "Dispositivos Android compatibles" para obtener enlaces a las aplicaciones de demostración de AOA de Microchip disponibles en Google Play.
    • Una tarjeta microcontroladora compatible. El Arduino Mega ADK sería una opción fácil si no está seguro.

    Introduzca aquí la descripción de la imagen

    Las posibilidades de los dispositivos Android que utilizan USB son increíbles, y la demanda de APPs innovadoras que son capaces de aprovechar al máximo estas características se establece para crecer notablemente.

    Su error no está relacionado con los permisos está relacionado con la E / S, el error -1 equivale a

     LIBUSB_ERROR_IO - Input/output error. 

    Usted puede modificar la interfaz JNI para poner libusb en el modo de depuración que llama libusb_set_debug() , creo que es la única y única manera de saber lo que realmente está sucediendo.

    De todos modos, compruebe primero VID / PID para asegurarse de que está en la lista de dispositivos conectados.

    En Android, no puedes usar libusb_open_device_with_vid_pid sin root. Para acceder a un dispositivo USB, debe usar la API de Android de UsbDeviceManager.

    El único ejemplo que sé del código fuente público que conecta libusb a Android sin root es: https://github.com/martinmarinov/rtl_tcp_andro-/

    No obtendrá nunca acceso de lectura / escritura a / dev / bus / usb / xxx / yyy. Android forma de hacerlo, es un sistema de servicios le envía, a través de carpeta, un descriptor de archivo ya abierto en el dispositivo específico / dev / bus / usb / xxx / yyy que usted pidió.

    Ya hay un montón de documentaciones sobre cómo manejar UsbHost de java en Android, así que voy a señalar lo que queda después de eso.

    • Necesita un libusb parcheado (el que está en rtl_tcp_andro- hará), que puede tomar un descriptor de archivo en lugar de un nombre de dispositivo / pid / vid
    • Necesitas llamar a libusb_open2 (así es como esta nueva función con fd se llama en libusb de rtl_tcp_andro) con el fd que recuperarás con UsbDeviceConnection.getFileDescriptor ()

    Edit: Estoy viendo rtl_tcp_andro- también agregó un libusb_init2, no entiendo por qué ATM, pero el commit dice que es para el apoyo L, así que supongo que también es necesario.

    Ese parche usb mencionado en cuestión funciona de la siguiente manera:

    1. DEBE abrir el dispositivo por UsbManager
    2. Abierto por libusb
    3. Cerca de libusb
    4. Cerca de UsbManager

    Exactamente ese orden funcionará.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.