Android Question USB Interface HID Report Descriptor

aeropic

Active Member
Licensed User
Longtime User
Hi All,,

Thanks to the USB library and example found here I have successfully been able to connect and read raw data of my HID gamepads (thank you for all that).

Here is the code, rather simple but works well !

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: USB
    #VersionCode: 2
    #VersionName: 1.01
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

Sub Process_Globals
  Dim manager As UsbManager
  Dim HIDstreams As UsbDeviceConnection
  Dim outEndpoint, inEndpoint As UsbEndpoint
  Dim device As UsbDevice
  Dim interface As UsbInterface
  Dim VID As Int : VID = 1118
  Dim PID As Int : PID = 27
  Dim RxPlcBuffer(64) As Byte
  Dim TxPlcBuffer(64) As Byte
  Dim Timer1 As Timer
End Sub
Sub Globals
    Dim EdLog As EditText
    Dim btnConnect As Button
    Dim btnDisconnect As Button
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Timer1.Initialize("Timer1", 50) ' 1000 = 1 second
  Timer1.Enabled = True
    If FirstTime Then
        manager.Initialize
 

    End If
    Activity.LoadLayout("1")
End Sub
Sub Activity_Pause(UserClosed As Boolean)
End Sub

Sub btnDisconnect_Click
  If HIDstreams.IsInitialized Then
    Log("Stopped")
  End If
End Sub
Sub btnConnect_Click
    Dim usbdevices() As UsbDevice
  usbdevices = manager.GetDevices
  'Iterate over devices and find the correct one
  For i = 0 To usbdevices.Length - 1
      Dim ud As UsbDevice
      ud = usbdevices(i)
      Log(ud)
    'Log(Bit.ToHexString(ud.VendorId))
    Log(ud.InterfaceCount)
      'Iterate over interfaces
      For a = 0 To ud.InterfaceCount - 1
        Dim inter As UsbInterface
        inter = ud.GetInterface(a)
        If inter.InterfaceClass = 3 AND inter.InterfaceSubclass = 0 Then 'HID interface
        'found our device and interface
   
   
      ' If ud.VendorId = VID AND ud.ProductId = PID Then
        'Log(Bit.ToHexString(ud.VendorId))
        'Log(Bit.ToHexString(ud.ProductId))
            'found our device and interface
            device = ud
            interface = inter
         
            'Find correct endpoints
            For b = 0 To interface.EndpointCount - 1
              Dim endpoint As UsbEndpoint
            Log (interface.EndpointCount)
              endpoint = interface.GetEndpoint(b)
 
              ' And claim it
              If endpoint.Type = manager.USB_ENDPOINT_XFER_INT Then
                  If endpoint.Direction = manager.USB_DIR_IN Then
                    inEndpoint = endpoint
                    Log(inEndpoint.MaxPacketSize)
                  Else If endpoint.Direction = manager.USB_DIR_OUT Then
                    outEndpoint = endpoint
                    Log(outEndpoint.MaxPacketSize)
                  End If
              End If
            Next
        End If
      Next
    Next
    manager.RequestPermission(device)
    If manager.HasPermission(device) Then
 
        HIDstreams = manager.OpenDevice(device, interface, True)
    Log("Connected")
    End If

End Sub
Sub Timer1_Tick
Dim NbRead As Int
Dim i As Int
Dim j As Int
Dim MyStr As String = ""

     
    If ( HIDstreams.IsInitialized = True ) Then
 
        NbRead = HIDstreams.BulkTransfer(inEndpoint,RxPlcBuffer,inEndpoint.MaxPacketSize,500)
        For i = 0 To NbRead -1
            j = ConvertSignedByteToUnsigned(RxPlcBuffer(i))
            MyStr = MyStr & NumberFormat(j,0, 0) & " "
            EdLog.Text = MyStr
        Next

    End If
End Sub
Sub ConvertSignedByteToUnsigned(b As Byte) As Int
  Return Bit.AND(b, 0xFF)
End Sub

This code simply dumps the raw values into integers.
It runs fine on a Nexus5 with kitkat and is able to recognize all my gamepads (Logitech, Thrustfire, Microsoft force feedback joystick, ...)
Now to decommutate the raw values I need to have access to the report descriptor (see picture)

HID_descriptor.jpg

Of course this descriptor is quite simple for a basic joystick and I could be able to parse the raw values without difficulty. However as soon as I connect another gamepad I get a new descriptor... with the joystick axis coded on 10 bits, the buttons before the axis ... etc ...
It would then be better to access the report descriptor into the program and to try to make a more generic "joystick handler".
My question is : Is there a way to get the report descriptor with B4A ?

I know how to get the Rawreportsdescriptors,

B4X:
test =HIDstreams.GetRawDescriptors    'gets the raw descriptors

But I don't know how to get the Interface 0 HID Report Descriptor (Joystick)


Thanks in advance
Alain
 
Last edited:
Top