Using Android to Communicate with a USB HID Device

前端 未结 3 841
长情又很酷
长情又很酷 2020-12-08 08:19

I am new to USB and to Android so please forgive me if I don\'t explain myself clearly.

I have a USB HID device that I can communicate with in Windows. I am trying

相关标签:
3条回答
  • 2020-12-08 09:17

    You can get a full list of the details of interfaces and endpoint by using the following:

    UsbManager mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    HashMap<String, UsbDevice> deviceList = mManager.getDeviceList();
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    
    while (deviceIterator.hasNext())
        {
            UsbDevice device = deviceIterator.next();
            Log.i(TAG,"Model: " + device.getDeviceName());
            Log.i(TAG,"ID: " + device.getDeviceId());
            Log.i(TAG,"Class: " + device.getDeviceClass());
            Log.i(TAG,"Protocol: " + device.getDeviceProtocol());
            Log.i(TAG,"Vendor ID " + device.getVendorId());
            Log.i(TAG,"Product ID: " + device.getProductId());
            Log.i(TAG,"Interface count: " + device.getInterfaceCount());
            Log.i(TAG,"---------------------------------------");
       // Get interface details
            for (int index = 0; index < device.getInterfaceCount(); index++)
            {
            UsbInterface mUsbInterface = device.getInterface(index);
            Log.i(TAG,"  *****     *****");
            Log.i(TAG,"  Interface index: " + index);
            Log.i(TAG,"  Interface ID: " + mUsbInterface.getId());
            Log.i(TAG,"  Inteface class: " + mUsbInterface.getInterfaceClass());
            Log.i(TAG,"  Interface protocol: " + mUsbInterface.getInterfaceProtocol());
            Log.i(TAG,"  Endpoint count: " + mUsbInterface.getEndpointCount());
        // Get endpoint details 
                for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
            {
                UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
                Log.i(TAG,"    ++++   ++++   ++++");
                Log.i(TAG,"    Endpoint index: " + epi);
                Log.i(TAG,"    Attributes: " + mEndpoint.getAttributes());
                Log.i(TAG,"    Direction: " + mEndpoint.getDirection());
                Log.i(TAG,"    Number: " + mEndpoint.getEndpointNumber());
                Log.i(TAG,"    Interval: " + mEndpoint.getInterval());
                Log.i(TAG,"    Packet size: " + mEndpoint.getMaxPacketSize());
                Log.i(TAG,"    Type: " + mEndpoint.getType());
            }
            }
        }
        Log.i(TAG," No more devices connected.");
    }
    
    0 讨论(0)
  • 2020-12-08 09:26

    So, I have been researching similar things. I cannot confirm, but what I believe is happening is:

    1. Android does not list the control endpoint when it enumerates it's endpoints. It only lists other endpoints.
    2. A connection to any endpoint can send control transfers to endpoint 0, through the controlTransfer method, which (quoting from the api) "Performs a control transaction on endpoint zero for this device."
    3. So, in your above code, I would use the 0th endpoint as an interrupt input endpoint, but it will still allow for control transfers.
    4. An example of someone using a HID device is the Missle Launcher demo, the device it uses is a HID device with an interrupt endpoint.
    0 讨论(0)
  • 2020-12-08 09:26

    Control transfer doesn't show any interface descriptor and its endpoint number is 0 by default, for both in and out transfer.

    if you have other interfaces the index of those interfaces should start from 0 i.e. default control transfer interface does not count.

    So your interface 0 holds the endpoint 1 descriptor. use the UsbEndpoint methods to find the attributes of the endpoint whether it is interrupt type or not. if it is then endpoint type by UsbEndpoint.getType() should return 0x03 and endpoint number by UsbEndpoint.getEndpointNumber() should return 0x81 which is usual value for endpoint 1.

    below your code is wrong:

    //first field ox21 is bin 00100001 which splits into 0 01 00001 for direction(1bit)/type(2b)/recipient(5b)
         //To set direction as 'host to Device' we need 0, **To set type to HID we need 11 (3)**, and for recipient we want 00001
         //second field 0x09 is class specific request code, **0x09 is listed as 'reserved for future use'**
         //**third field 0x200 is value**
         //int transfer = mConnectionRead.controlTransfer(0x21, 0x9, 0x200, 0, message, message.length, 0);
         //try with type set to HID
         int transfer = mConnectionRead.controlTransfer(0xC1, 0x9, 0x200, 0, message, message.length, 0);
    

    Type 2 bits is used to indicate class specific request, i.e. its value is 01, 0x09 is Hid class specific request SET_REPORT, not reserved. value is the wValue which is used as Report ID for Hid class, for your case it is probably 0, if you have only one report at you HID descriptor. and the 4 th parameter is wIndex which should be used to indicate the recipient, for your case it should be 0x01 for interface as recipient.

    So your code for control transfer for Read or receive data form device should be:

    int transfer = mConnectionRead.controlTransfer(0xA1, 0x01, 0x00, 0x01, message, message.length, 0);
    

    where 0x01 in second parameter is GET_REPORT is Hid calls specific request.

    And your code for control transfer for Write or send data to device should be:

    int transfer = mConnectionWrite.controlTransfer(0x21, 0x09, 0x00, 0x01, message, message.length, 0);
    

    Since you only have Interrupt IN endpoint 1, Bulk or Interrupt transfer should be like:

    int transfer = bulkTransfer (ep1, message, message.length, 0);
    

    to have the interrupt Out endpoint there should be a endpoint descriptor for that at the interface descriptor of firmware of your device.

    0 讨论(0)
提交回复
热议问题