Main Site Documentation

USB Raw


#1

How do I communicate with a raw device? I get an error that says “Invalid length received for a USB descriptor”

using System;
using Microsoft.SPOT;
using System.Threading;
using GHI.Usb.Host;

namespace CerbFirmwareTest {
    public class Program {
        static RawDevice threeDMouse = null;
        static RawDevice.Pipe threeDMousePipe = null;
        static byte[] buffer = new byte[1024];
        public static void Main() {
            Controller.DeviceConnectFailed += Controller_DeviceConnectFailed;
            Controller.UnknownDeviceConnected += Controller_UnknownDeviceConnected;
            Controller.Start();
            Thread.Sleep(Timeout.Infinite);
        }

        static void Controller_UnknownDeviceConnected(object sender, GHI.Usb.Host.Controller.UnknownDeviceConnectedEventArgs e) {
            threeDMouse = new RawDevice(e.Id, e.InterfaceIndex, e.VendorId, e.ProductId, e.PortNumber, GHI.Usb.Host.BaseDevice.DeviceType.Unknown);
            threeDMouse.Disconnected += threeDMouse_Disconnected;
            threeDMousePipe = threeDMouse.OpenPipe(new GHI.Usb.Descriptors.Endpoint(buffer));
            Debug.Print("Unknown Device assumed to be 3d Mouse. VendorID : " + e.VendorId.ToString() + ", Product ID: " + e.ProductId.ToString() + ". Starting up...");
        }

        static void threeDMouse_Disconnected(BaseDevice sender, EventArgs e) {
            threeDMousePipe.Dispose();
            threeDMouse = null;
            Debug.Print("ThreeD Mouse Disconnected");
        }

        static void Controller_DeviceConnectFailed(object sender, EventArgs e) {
            throw new NotImplementedException();
        }

    }
}


#2

@ Mr. John Smith - Have you seen today’s codeshare from GHI:

https://www.ghielectronics.com/community/codeshare/entry/939

May be you can find some hints there on how to deal with Raw USB device.


#3

Nope, I hadn’t. Inspecting it now.


#4

I’m not getting any endpoints to show up.


#5

@ Mr. John Smith - I can get you a more complete program tomorrow when I get in, but can you run the below code and send me the contents of bytes1 and bytes2? Something like {0x00, 0x01, 0x04, …} is fine.


byte[] bytes1 = new byte[Descriptors.Configuration.LENGTH];
threeDMouse.SendSetupPacket(0x80, 0x06, (ushort)0x0200, 0, bytes1, 0, bytes1.Length);

var descriptor = new Descriptors.Configuration(bytes1);

byte[] bytes2 = new byte[descriptor.TotalLength];
threeDMouse.SendSetupPacket(0x80, 0x06, (ushort)0x0200, 0, bytes2, 0, bytes2.Length);


#6

@ Mr. John Smith: Maybe this helps a bit, all done in VS2013 with the beta from codeplex and plain NETMF, but maybe it’ll just work for other versions as well. Was done on a cerberus with 4.3.4.0 (but the raw device I use is not recognized by the raptor though)


        static void Controller_UnknownDeviceConnected(object sender, Controller.UnknownDeviceConnectedEventArgs unknowndevice)
        {
            Debug.Print("");
            Debug.Print("Unknown Device connected.");
            Debug.Print("   ID   = " + unknowndevice.Id.ToString("X4"));
            Debug.Print("   Port = " + unknowndevice.PortNumber);
            Debug.Print("   VID  = " + unknowndevice.VendorId.ToString("X4"));
            Debug.Print("   PID  = " + unknowndevice.ProductId.ToString("X4"));
            Debug.Print("   Type = " + (BaseDevice.DeviceType)unknowndevice.Type);

            raw = new RawDevice(unknowndevice.Id, 
                                    unknowndevice.InterfaceIndex,
                                    unknowndevice.VendorId,
                                    unknowndevice.ProductId, 
                                    unknowndevice.PortNumber, 
                                    BaseDevice.DeviceType.HID);

            raw.Disconnected += raw_Disconnected;

            GHI.Usb.Descriptors.Device devdesc = raw.GetDeviceDescriptor();
            Debug.Print("Number of configurations . . . " + devdesc.NumberOfConfigurations);
            Debug.Print("Max Packet size  . . . . . . . " + devdesc.MaximumPacketSize);
            Debug.Print("Protocol code  . . . . . . . . " + devdesc.ProtocalCode.ToString("X2"));
            Debug.Print("Release number . . . . . . . . " + devdesc.ReleaseNumber.ToString("X2"));
            Debug.Print("Serial number index  . . . . . " + devdesc.SerialNumberIndex.ToString("X2"));
            Debug.Print("Subclass code  . . . . . . . . " + devdesc.SubclassCode.ToString("X2"));
            Debug.Print("USB sepecification number  . . " + devdesc.UsbSpecificationNumber.ToString("X2"));

            // On this device there is only one configuration descriptor
            GHI.Usb.Descriptors.Configuration cfgdesc = raw.GetConfigurationDescriptor(0);

            // look for the HID device
            for (int i = 0; i < cfgdesc.Interfaces.Length; i++)
            {
                Debug.Print("  === Interface ===");
                Debug.Print("  Class: " + ClassToString(cfgdesc.Interfaces[i].ClassCode));
                Debug.Print("  SubClass: " + cfgdesc.Interfaces[i].SubclassCode);
                Debug.Print("  Number: " + cfgdesc.Interfaces[i].Number);
                Debug.Print("  Protocol: " + cfgdesc.Interfaces[i].ProtocolCode);
                Debug.Print("  Type: " + cfgdesc.Interfaces[i].Type);

                for (int ep = 0; ep < cfgdesc.Interfaces[i].Endpoints.Length; ep++)
                {
                    Debug.Print("   -- Endpoint --");
                    Debug.Print("    Attributes: " + cfgdesc.Interfaces[i].Endpoints[ep].Attributes);
                    Debug.Print("    Address: " + cfgdesc.Interfaces[i].Endpoints[ep].Address);
                    Debug.Print("    Type: " + cfgdesc.Interfaces[i].Endpoints[ep].Type);
                    Debug.Print("    Interval: " + cfgdesc.Interfaces[i].Endpoints[ep].Interval);
                    Debug.Print(" ");
                }

                Debug.Print(" ");
                Debug.Print(" ");
            }

            Debug.Print("So far, so good ...");

        }


#7

@ John -
You’re lucky numbers are:

bytes1 {9,2,18,0,1,0,1,128,50}
bytes2 {9,2,0,18,1,1,0,128,50,9,4,0,0,0,0}


#8

@ PiWi - Do you have the body of the “ClassToString” method?


#9

@ Mr. John Smith - you can pull ClassToString form the following codeshare
https://www.ghielectronics.com/community/codeshare/entry/115


#10

@ taylorza, Got it.


#11

@ PiWi - Well the output was:

Unknown Device connected.
ID = 20011358
Port = 0
VID = 03EB
PID = 2FF3
Type = 0
Number of configurations . . . 1
Max Packet size . . . . . . . 32
Protocol code . . . . . . . . 00
Release number . . . . . . . . 00
Serial number index . . . . . 03
Subclass code . . . . . . . . 01
USB sepecification number . . 200
=== Interface ===
Class: Base Class
SubClass: 0
Number: 0
Protocol: 0
Type: 4


#12

Oh, oh, I just got caught making a rookie mistake :-[

Unknown Device connected.
ID = 20011358
Port = 0
VID = 046D
PID = C626
Type = 2
Number of configurations . . . 1
Max Packet size . . . . . . . 8
Protocol code . . . . . . . . 00
Release number . . . . . . . . 431
Serial number index . . . . . 00
Subclass code . . . . . . . . 00
USB specification number . . 200
=== Interface ===
Class: HID
SubClass: 0
Number: 0
Protocol: 0
Type: 4
– Endpoint –
Attributes: 3
Address: 129
Type: 5
Interval: 10

– Endpoint –
Attributes: 3
Address: 2
Type: 5
Interval: 10

It was the USB cable that I was using to connect Cerb to the PC! I did not know this was possible. I changed the cable and now I get endpoints!


#13

Well that was fun. After 2 years I finally get to use this device on the .netmf! Yahoo.

Codeshare Entry: https://www.ghielectronics.com/community/codeshare/entry/940


#14

The framework throws a first chance exception every time I read from the device and there is no data to read (I’m assuming). It Controller.GetLastError says 2.


#15

@ Mr. John Smith - If you got a working scenario with a normal PC you could use a USB sniffer to record the raw data and do some RE ?

For me I have to initiate my used USB Raw device first before it starts spitting data, it is a kind of sensor hub.

Thanks for the codeshare, I’ll try it out with my device (with a couple of modifications of course).


#16

@ PiWi - Nah, I don’t have a USB sniffer. It seems that when that startup packet is sent the lights on the mouse turn on. Weird.


#17

this might help: usbview.exe

https://code.msdn.microsoft.com/USBView-sample-application-e3241039

or get the binnary from here:

the source code compiles pretty easy btw :slight_smile:

Jay


#18

@ Jay Jay - Thanks for the links, worked fine for me …


[Port2]  :  USB Input Device


Is Port User Connectable:         yes
Is Port Debug Capable:            no
Companion Port Number:            0
Companion Hub Symbolic Link Name: 
Protocols Supported:
 USB 1.1:                         yes
 USB 2.0:                         yes
 USB 3.0:                         no

Device Power State:               PowerDeviceD3

       ---===>Device Information<===---
English product name: "Universal Bridge"

ConnectionStatus:                  
Current Config Value:              0x01  -> Device Bus Speed: Low
Device Address:                    0x02
Open Pipes:                           1

          ===>Device Descriptor<===
bLength:                           0x12
bDescriptorType:                   0x01
bcdUSB:                          0x0110
bDeviceClass:                      0x00  -> This is an Interface Class Defined Device
bDeviceSubClass:                   0x00
bDeviceProtocol:                   0x00
bMaxPacketSize0:                   0x08 = (8) Bytes
idVendor:                        0x0FDE = IDT DATA SYSTEM LIMITED
idProduct:                       0xCA01
bcdDevice:                       0x0302
iManufacturer:                     0x00
iProduct:                          0x01
     English (United States)  "Universal Bridge"
iSerialNumber:                     0x00
bNumConfigurations:                0x01

          ---===>Open Pipes<===---

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0008
bInterval:                         0x01

       ---===>Full Configuration Descriptor<===---

          ===>Configuration Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x02
wTotalLength:                    0x0022  -> Validated
bNumInterfaces:                    0x01
bConfigurationValue:               0x01
iConfiguration:                    0x00
bmAttributes:                      0x80  -> Bus Powered
MaxPower:                          0x32 = 100 mA

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x00
bAlternateSetting:                 0x00
bNumEndpoints:                     0x01
bInterfaceClass:                   0x03  -> HID Interface Class
bInterfaceSubClass:                0x00
bInterfaceProtocol:                0x00
iInterface:                        0x00

          ===>HID Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x21
bcdHID:                          0x0110
bCountryCode:                      0x00
bNumDescriptors:                   0x01
bDescriptorType:                   0x22 (Report Descriptor)
wDescriptorLength:               0x0022

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0008
bInterval:                         0x01

@ Mr. John Smith - There is a nice USB Sniffer written in C# where you can input some data and monitor what’s going. Try to search for UsbLibrary on the internet or if you are send me a PM with an email address I’ll send you the VS project with documentation.


#19

Can I have one, please? :smiley:


#20

@ Dat - It’s in the mail !!