libusb открыть устройство с vid PID не удалось при попытке доступа к USB-устройству

Я пытаюсь получить USB-устройство для подключения к устройству Android 5.1.1. Раньше я использовал обычный libusb для KitKat, но Lollipop повысил безопасность, и это больше не работает.

это хорошо документировано, требуя, чтобы root установил уровень SELinux. Я не хочу Рута получить USB-устройство для подключения к нему.

осмотревшись, я наткнулся ответ и эта вилка libusb, однако теперь я получаю новую ошибку

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

Я не изменил ни одного кода, только библиотеку.

это все еще проблема с разрешением, или есть что-то, чего мне не хватает, что заставит это работать?

4 ответов


следующие шаги могут быть использованы для решения упомянутых вами проблем.

процесс установки устройства в качестве USB-накопителя непоследователен между устройствами и производителем. Некоторые устройства, такие как Nexus S, предлагают "включить USB-накопитель" при подключении устройства к рабочему столу через USB-кабель. Другие устройства, такие как Galaxy S3, требуют приложения для запуска устройства в качестве массового хранилища. В любом случае, устройства Android обычно предлагают такую функцию, и вам придется создайте файл, соответствующий спецификации производителя вашего устройства.

перед работой с API хоста USB необходимо добавить в файл манифеста приложения:

  • поскольку не все Android-устройства гарантированно поддерживают API хоста USB, включите элемент, который объявляет, что ваше приложение использует android.аппаратура.USB.функция хоста.
  • если вы хотите, чтобы ваше приложение было уведомлено о подключенном USB-устройстве, укажите и пара элементов для android.аппаратура.USB.действие.USB_DEVICE_ATTACHED намерение в вашей основной деятельности.

добавить USB_DEVICE_ATTACHED в файл 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>

чтобы помочь вашему приложению обнаружить конкретное USB-устройство, вы можете использовать фильтр намерений:

<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>

вы также должны указать свое устройство и идентификатор поставщика:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="1234" product-id="5678" />
</resources>

этого должно быть достаточно, чтобы справиться с вашей USB-хост подключение. Теперь звоните USB:

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

используйте дескриптор, чтобы открыть соединение с usb-устройство, например:

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);

если у вас все еще есть проблемы с уровнем SELinux, здесь у вас есть некоторые изменения, которые вы можете использовать, чтобы ваша программа работала гладко:

// 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

As настройки SELinux по умолчанию установлен для обеспечения наивысшей безопасности, и вы хотите предоставить клиентский доступ к вашему Android-устройству через USB.

enter image description here

в зависимости от вашего Android make and model, попробуйте отключить USB-кабель, соединяющий ваше устройство и рабочий стол, и подключите его обратно. Вам будет предложено" включить USB-накопитель". Если это так, попробуйте перейти к → Настройки... на Android и найдите опцию USB-накопителя.

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

альтернативно ищите процесс хранения данных USB рекомендуется производителем устройства. Когда вы включаете USB-накопитель, устройство позволяет вам знать, что некоторые приложения остановятся, идите вперед и ОК. Теперь перейдите к настольному компьютеру и перейдите на USB-накопитель, который часто не называется именем, если вы его не переименовали. Нажмите на свое запоминающее устройство и прямо там, в папке foot, найдите файл с именем data.tsv .

enter image description here

вы также можете проверить данные.tsv, открыв его в своем любимом текстовом редакторе. Вы найдете там два столбца, аккуратно разделенных вкладкой; в каждой строке вы найдете пару целочисленных значений. Этого вполне достаточно для нашего проекта. Более сложные проекты данных обычно требуют уникального идентификатора для каждой строки, строки в одной таблице для указания на конкретную запись в другой.

enter image description here

в соответствии с вашей!--61-->среда разработки, вы также должны настроить соответствующим образом параметры. Если вы разрабатываете на Windows, следуйте USB установка драйвера доступные инструкции. Если вы разрабатываете Linux, следуйте инструкциям для настройка устройство для разработки.

enter image description here

кроме того, также стоит упомянуть, что многие ранее выпущенные Android-устройства способны действовать только как USB-устройство и не могут инициировать соединения с внешними USB-устройствами. Поддержка Android Open Accessory (AOA) преодолевает это ограничение и позволяет создайте аксессуары, которые могут взаимодействовать с ассортиментом устройств на базе Android, позволяя аксессуару инициировать подключение. Пример общего использования Android Open Accessory можно найти в проекте: запись и воспроизведение аудио с помощью режим хоста USB - что, конечно, требует, чтобы режим USB был включен и запущен.

enter image description here

положить Android для связи через USB с Arduino microcontrolers является также тип реализации, который показал, чтобы стать очень успешным в последнее время, так как это позволяет расширить возможности Android интеграции дополнительных функций с помощью подхода решения нескольких устройств. Типичный эскиз Arduino для обеспечения связи устройства с вашим Android USB будет выглядеть следующим образом:

// 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);
}

все проекты Arduino должны иметь метод setup() и loop (), объявленный в противном случае ваш Android не будет общаться должным образом.

тоже помню что список минимальных требований, необходимых для использования AOA:

  • AOA-совместимое устройство Android. Чтобы проверить совместимость перед попыткой этого примера, обратитесь к разделу "поддерживаемые устройства Android" для ссылок на демонстрационные приложения Microchip AOA, доступные в Google Play.
  • совместимая плата микроконтроллера. Arduino Mega ADK будет простым вариантом, если вы не уверены.

enter image description here

возможности Android-устройства, использующие USB, удивительны, и спрос на инновационные приложения, которые способны в полной мере использовать такие функции, будет заметно расти.


ваша ошибка не связана с разрешениями, связанными с вводом / выводом,-1 ошибка эквивалентна

LIBUSB_ERROR_IO - Input/output error. 

вы можете modifiy в интерфейс JNI поставить libusb в режим отладки вызова libusb_set_debug(), Я думаю, что это единственный способ узнать, что происходит на самом деле.

В любом случае, сначала проверьте VID/PID, чтобы убедиться, что он находится в списке подключенных устройств.


на Android вы не можете использовать libusb_open_device_with_vid_pid без root. Чтобы получить доступ к USB-устройству, необходимо использовать UsbDeviceManager Android API.

единственный пример, который я знаю о общедоступном исходном коде, соединяющем libusb с Android без root:https://github.com/martinmarinov/rtl_tcp_andro-/

вы никогда не получите доступ для чтения / записи в /dev/bus/usb/xxx / yyy. Способ Android сделать это, это системные службы отправляет вам, через binder, уже открыт файловый дескриптор на конкретном/dev/bus/usb/xxx / yyy устройстве, которое вы просили.

уже есть много документов о том, как обрабатывать UsbHost с java в Android, поэтому я укажу на то, что осталось после этого.

  • вам нужен исправленный libusb (тот, который в rtl_tcp_andro - будет делать), который может принимать filedescriptor вместо имени устройства/pid/vid
  • вам нужно вызвать libusb_open2 (вот как эта новая функция с fd вызывается в rtl_tcp_andro libusb) с fd, который вы получите с помощью UsbDeviceConnection.getFileDescriptor ()

Edit: я вижу rtl_tcp_andro - также добавлен libusb_init2, я не понимаю, почему ATM, но фиксация говорит, что это для поддержки L, поэтому я думаю, что это также необходимо.


этот USB-патч, упомянутый в вопросе, работает следующим образом:

  1. вы должны открыть устройство UsbManager
  2. открыть libusb
  3. рядом с libusb
  4. закрыть UsbManager

именно этот заказ будет работать.