Main Site Documentation

Could USB host exceptions be better defined?


#1

I have a function that I am using with a USB host raw device:

public static int GetProtocol(USBH_RawDevice openedDevice)
{
    var dataBytes = new byte[2];
    openedDevice.SendSetupTransfer(
        (byte)(UsbRequestType.DeviceToHost | UsbRequestType.Vendor),
        (byte)AndroidAccessoryUsbCommands.GetProtocol,
        0,
        1,
        dataBytes,
        0,
        dataBytes.Length
        );

    return (dataBytes[1] << 8) | dataBytes[0];
}

This is part of the Android Open Accessory handshaking. The gist of it is that if you have a device that speaks the Android Open Accessory protocol, it will respoond to this request with a version number. Which works great for devices that support the protocol.

However, if you plug in a device that does not speak the protocol, I get an exception:

#### Exception System.Exception - 0xffffffff (1) ####
#### Message: 
#### GHIElectronics.NETMF.USBHost.USBH_RawDevice::SendSetupTransfer [IP: 0000] ####
#### Prototype.AndroidOpenAccessory.Fez.AndroidAccessoryUtil::GetProtocol [IP: 0018] ####
#### Prototype.AndroidOpenAccessory.Fez.HelloFez.Program::Main [IP: 008f] ####

A first chance exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.USBHost.dll
An unhandled exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.USBHost.dll

No InnerException. Message is “Exception was thrown: System.Exception”. There looks like there is a non-public m_HResult = 4294967295 but that’s just the 0xffffffff value and not useful (and I can’t access it anyway due to its protection level).

Now, I can appreciate that an Exception is used to signal the fact that the device balked at the command that was sent. But I can’t differentiate between “this device did not respond to the USB command that was sent” and “something has seriously gone wrong”.

Am I missing something? It seems like a specialized UsbException with some more actionable details would be useful.


#2

Just make a call:

USBH_ERROR usbError = USBHostController.GetLastError();

right after you got the exception. Refer to the documentation for the error value and meaning.


#3

Thanks – GetLastError returns DeviceBusy in my failure case. Just to be safe, I’ll rethrow if the error is not NoError and call it a day.


#4

btw you can get it using reflection.Check my extension,that uses this trick to return HRESULT code name from managed code:

http://code.tinyclr.com/project/279/exception-extension-to-get-hresult-name/


#5

The things we do for love :wink:

Thanks – interesting technique. If it had more of a juicy center I think I would have tried harder to pry it out, but it’s good to know that a solution exists.