Re: Issues with simulating a keyboard device with gadgetfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thank you for the explanation, Alan.

Please find my questions below:

On Fri, Apr 10, 2009 at 10:19 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> On Thu, 9 Apr 2009, Aniruddha Marathe wrote:
>
>> Hi All,
>>
>> I am trying to understand how usb.c, the only working user mode driver
>> example that I found on the net that uses gadgetfs. Using that code as
>> the base I am trying to write a HID keyboard driver (user mode) with
>> Net2280 peripheral device controller to simulate working of a
>> keyboard. I referred to the following discussion that happened almost
>> half a decade ago but didn't lead to any useful conclusions (but did
>> help me find answers to some of my questions):
>>
>> http://www.mail-archive.com/linux-usb-devel@xxxxxxxxxxxxxxxxxxxxx/msg20380.html
>>
>> I am running Wireshark with USB support on the host to see what's
>> going on. I've attached the traces of real keyboard and my simulation
>> keyboard with this email.
>
> My copy of Wireshark doesn't display the contents of the URBs
> correctly.  Can you provide output from usbmon instead?

Please find attached usbmon output for real keyboard (kbd2.dump) and
my keyboard (mykbd2.dump).

>
>> Based on that I have the following (newbie)
>> questions:
>>
>> 1. After the response to 'GET DEVICE DESCRIPTOR' request, the trace of
>> simulation driver shows that the host sends a 'GET DESCRIPTOR DEVICE
>> QUALIFIER' request. I do not see such request in the trace for the
>> real keyboard.
>
> Get-Device-Qualifier is sent only to USB-2.0 devices.  No doubt your
> real keyboard is USB-1.1.
>

Thanks for clearing that out. I am specifying the device type as USB
1.1. However, I see USB 2.0 type of device when I list the device on
the host. Here are the device and hid descriptors I use for the
device:

static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      1,
        .bcdUSB =               __constant_cpu_to_le16(0x0110),
        .bDeviceClass =         0,
        .bDeviceSubClass =      0,
        .bDeviceProtocol =      0,
        .idVendor =             __constant_cpu_to_le16(KEYBOARD_VENDOR_NUM),
        .idProduct =            __constant_cpu_to_le16(KEYBOARD_PRODUCT_NUM),
        .bcdDevice =            0x0100,
        .iManufacturer =        STRING_MANUFACTURER,
        .iProduct =             STRING_PRODUCT,
        .iSerialNumber =        STRING_SERIALNUM,
        .bNumConfigurations =   1
};

static struct hid_descriptor hid_config_desc = {

        .bLength = sizeof(hid_config_desc),
        .bDescriptorType = 0x21,
        .bcdHID = 0x0110,
        .bCountryCode = 0,
        .bNumDescriptors = 1,
        .desc[0].wDescriptorLength = sizeof(ReportDescriptor),
        .desc[0].bDescriptorType = 0x22
};

[aniruddha@localhost ~]$ cat /proc/bus/usb/devices

T:  Bus=04 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  7 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=4242 ProdID=0110 Rev= 1.00
S:  Manufacturer=Microsoft Corporation
S:  Product=Microsoft Natural Keyboard Pro
C:  #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=3ms

I am not sure why it shows Ver= 2.00, even though I specify 1.1.

>>  What is the meaning of this request?
>
> It is documented in the USB 2.0 specification (which you should be
> familiar with if you are going to write a USB driver).  It asks for a
> device descriptor appropriate to the "other" speed: If the connection
> is running at full speed then it asks the device to send its high-speed
> device descriptor, and vice versa.
>

Thanks for the explanation.

>> Was the response
>> to the earlier 'GET DEVICE DESCRIPTOR' request malformed (the sniffer
>> doesn't indicate that, however)?
>
> I can't tell since Wireshark doesn't display the response data
> properly.
>
>> Simulation keyboard trace:
>>
>> --------------------------------------------------------------------------------------------------
>> Source     Destination    Protocol   Info
>> --------------------------------------------------------------------------------------------------
>> host         23.0              USB        GET DESCRIPTOR Request
>> DEVICE QUALIFIER
>>
>>
>> 2. My simulation keyboard driver stops responding after the following request:
>>
>> -------------------------------------------------------------------------------
>> Source    Destination   Protocol     Info
>> -------------------------------------------------------------------------------
>> host        3.0               USB          SET CONFIGURATION Request
>>
>> What should my driver send as a response back to the host?
>
> Set-Configuration doesn't have a response, only an acknowledgement.
> You really should read through the descriptions of the standard
> requests in Chapter 9 of the USB 2.0 specification; if you don't
> understand them then you can't possibly write a USB driver.
>
>> I saw that
>> the real keyboard just sends a response with 0's filled in it.
>
> No it doesn't.  You're probably seeing an artifact introduced by
> Wireshark.  There's no response, only an acknowledgement.
>
>>  Is this
>> what it is supposed to send? Keyboard simulator creates a new thread
>> for 'ep-a' management and writes the endpoint descriptor into ep-a's
>> file  descriptor.  But the host doesn't seem to get it (can't see it
>> on Wireshark). What I see is a (probable) timeout after 5 sec and 0's
>> filled in 'SET CONFIGURATION' response. Also after this, the host
>> doesn't send a request for reports, like it does in case of the real
>> keyboard. Why does this happen?
>
> Probably because your program isn't sending the acknowledgement.  You
> should do more or less the same thing as the usb.c demo program.
>
>> 3. The real keyboard has an IN endpoint of type interrupt. As far as I
>> understand, this is the endpoint that should be sending the report
>> descriptors to the host.
>
> No.  The interrupt-IN endpoint is used for sending the reports
> themselves; the report _descriptor_ is sent via endpoint 0.
>

Ahh.. Two different things..

>>  However, in Wireshark I see that when the
>> host sends a 'GET DESCRIPTOR RPIPE' request the ep0 of the real
>> keyboard sends the report instead of ep1. Here is the trace (I assume
>> '3.0' means ep0):
>>
>> -------------------------------------------------------------------------------------
>> Source    Destination   Protocol     Info
>> -------------------------------------------------------------------------------------
>> host         3.0              USB           GET DESCRIPTOR Request RPIPE
>
> What do you think "RPIPE" means?  Some sort of shorthand for "Report"?
> Wireshark is weird...
>

I confused report descriptor with the report itself. Here, I
correlated USB_DT_RPIPE which is 0x22 with RPIPE request seen in
Wireshark.

>> Since ep1 is interrupt type, shouldn't it send the report when the
>> host sends an 'IN' token packet to ep0 instead of ep0 sending it when
>> the host sends 'GET DESCRIPTOR RPIPE' to ep0?
>
> Endpoints don't respond to packets sent to other endpoints.  So if the
> host sends a token packet to ep0, there won't be a response from ep1.
> If the host had sent a token packet to _ep1_ then you would expect to
> see a report sent back from ep1.
>
> Furthermore, "GET DESCRIPTOR RPIPE" (whatever else it is) clearly is a
> control transfer, not an interrupt transaction.  As such it has to use
> ep0, not ep1.
>
>> 4. Is there any other documentation available on gadgetfs and usb.c
>> apart from the source code itself?
>
> No, not really.
>
> Alan Stern
>
>

Thanks,
Aniruddha

Attachment: mykbd2.dump
Description: Binary data

Attachment: kbd2.dump
Description: Binary data


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux