Android USB host, 3.2, HID Report Get / Set - PullRequest
       7

Android USB host, 3.2, HID Report Get / Set

3 голосов
/ 07 декабря 2011

У меня есть устройство HID, в частности -> Эталонный дизайн Silicon Labs USB-FM Radio. Это устройство отображается как HID.

Используя API хоста 3.2 USB, как мне выполнить HID_REPORT_GET / SET или его эквивалент?

Ура, Earlence

Ответы [ 2 ]

2 голосов
/ 22 мая 2017

Я только что получил USB-ключ Si470x для работы на Android.Я решил часть HID, написав небольшой класс-оболочку для вызовов Android:

private class HidDevice {
    /** GET_REPORT request code */
    public static final int REQUEST_GET_REPORT = 0x01;
    /** SET_REPORT request code */
    public static final int REQUEST_SET_REPORT = 0x09;
    /** INPUT report type */
    public static final int REPORT_TYPE_INPUT = 0x0100;
    /** OUTPUT report type */
    public static final int REPORT_TYPE_OUTPUT = 0x0200;
    /** FEATURE report type */
    public static final int REPORT_TYPE_FEATURE = 0x0300;

    private Context context;
    private UsbManager manager;
    private UsbDevice device;
    private UsbInterface ifHid = null;
    private UsbEndpoint epIn = null;
    private UsbDeviceConnection connection;

    public HidDevice(Context context, UsbDevice device) throws IOException {
        this.context = context;
        this.device = device;

        for (int i = 0; (this.ifHid == null) && (i < device.getInterfaceCount()); i++)
            if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
                this.ifHid = device.getInterface(i);
                for (int j = 0; j < ifHid.getEndpointCount(); j++) {
                    UsbEndpoint ep = ifHid.getEndpoint(j);
                    if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT))
                        epIn = ep;
                }
            }
        if (this.ifHid == null)
            throw new IllegalArgumentException("Device has no HID interface");
        else if (this.epIn == null)
            throw new IllegalArgumentException("Device has no INTERRUPT IN endpoint (type USB_ENDPOINT_XFER_INT, direction USB_DIR_IN");

        this.manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        this.connection = manager.openDevice(device);
        if (!connection.claimInterface(ifHid, true))
            throw new IOException("Failed to claim HID interface");
    }

    public int getFeatureReport(int reportId, byte[] data, int length) {
        if ((reportId & 0xFF) != reportId)
            throw new IllegalArgumentException("reportId may only set the lowest 8 bits");
        return connection.controlTransfer(
                UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT,
                REQUEST_GET_REPORT,
                reportId | REPORT_TYPE_OUTPUT,
                ifHid.getId(), data, length, 0);
    }

    public int read(byte[] data, int length) {
        return connection.bulkTransfer(epIn, data, length, 0);
    }

    public int sendFeatureReport(int reportId, byte[] data, int length) {
        if ((reportId & 0xFF) != reportId)
            throw new IllegalArgumentException("reportId may only set the lowest 8 bits");
        return connection.controlTransfer(
                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT,
                REQUEST_SET_REPORT,
                reportId | REPORT_TYPE_INPUT,
                ifHid.getId(), data, length, 0);
    }
}

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

Что касается высокоуровневых вещей, взгляните на драйвер Linux .hid_open() соответствует конструктору HidDevice, остальное должно быть простым.

Имейте в виду, что отсутствие целочисленных типов без знака в Java может иметь нежелательные побочные эффекты при объединении данных из массива byte[],Обходной путь должен использовать (data[i] & 0xFF) вместо data[i].

Аудио не передается по этому каналу - ключ использует отдельное аудиоустройство для этого, которое кажется стандартным аудиоустройством Linux.Впрочем, опыта в этом нет (для моего проекта мне нужны только данные RDS).

0 голосов
/ 10 декабря 2013

Вам нужно будет отправить контрольный запрос , отформатированный для выдачи GET_REPORT или SET_REPORT вместе с типом отчета и идентификатором отчета. Взгляните раздел 7.2 в спецификации HID .

...