How to catch signals from a unknown USB OTG device?

Viewed 544

I have a USB OTG device which acts like a mouse, bought in china with not much more information about the used controller. When I connect it to my android there is a mouse cursor and the device has 5 hard buttons (left, right, up, down, enter). I want to programm the buttons for my app to performe specific tasks. So I need to read the input signals and overwrite them.

How can I catch the signals?

I found out the vendor (0x04D9) and product id (0x2519) and the controller name Lenovo Calliope USB Keyboard. But no idea about the used chip, it's covert.

It doesn't work with the methods onKeyDown or dispatchKeyEvent. Also not with USB serial Lib because the device is not found/ recognized with the provided VID und PID (see discussion with Fatih Şennik below, other devices are recognized with it).

My current assumption is that it is a Hardware/ Chip issue that I cannot get the signals. But the strange thing is that the device otherwise does what it is supposed to do.

2 Answers

You can use a USB serial Lib such as https://github.com/mik3y/usb-serial-for-android and give vendor and product ID of your USB OTG device to control it. So you can catch left, right, up, down and hex codes in any monitor and based on the raw byte, you can do a switch like operation.

UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { 
     //Defining a Callback which triggers whenever data is read.
        @Override
        public void onReceivedData(byte[] arg0) {
            String data = null;
            try {
                data = new String(arg0, "UTF-8");
                data.concat("/n");
                switch() // etc
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    };

Lets first try this to connect our android phone to the USB otg device. As for the product and vendor ids, you can find it when you plug it to your pc. if the connection is established then the rest will come. it would be helpful if you can share the USB Otg device data sheets here.

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        ProbeTable customTable = new ProbeTable();
        customTable.addProduct(0x0403, 0x6001, CdcAcmSerialDriver.class);

        List<UsbSerialDriver> availableDrivers = new UsbSerialProber(customTable).findAllDrivers(manager);
        ArrayAdapter<String> deviceList = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_2);
        ListView listDevices = (ListView) findViewById(R.id.listView);
        if(!availableDrivers.isEmpty()) {
            for(UsbSerialDriver driver: availableDrivers) {
                deviceList.add(driver.getDevice().getDeviceName());
            }
            listDevices.setAdapter(deviceList);
        } else {
            Toast.makeText(getApplicationContext(), "No devices found", Toast.LENGTH_LONG).show();
        }
    }
}

if it is USB hid device, Trying this code might help;

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.");
}

The solution if nothings works: I got an arduino controller and solder it to the buttons. It's not that complicated.

Important is that the controller supports hid e.g. the leonardo pro micro with the atmega32u4 chip. The code for the controller can be found easily with google.

Then it works with override onKeyDown or onKeyUp etc.

Related