Re: Raw hid gadget

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

 



On Sat, 7 Jan 2017, Rogan Dawes wrote:

> Hi folks,
> 
> I'm trying to port the USaBUSe project
> (https://github.com/SensePost/USaBUSe) from an AVR microcontroller to
> the Linux USB gadget stack. USaBUSe implements a combined keyboard and
> mouse via a single HID endpoint, as well as a raw HID endpoint, which
> is used as a bi-directional comms channel.
> 
> I have managed to get the combined keyboard and mouse working, by
> extending the report size to 9 instead of 8, and writing the report ID
> as the first byte of the report to /dev/hidg0. And the performance is
> excellent, 300 characters per second with no problems! Thank you!
> 
> However, I'm now trying to figure out how to use the raw hid interface
> as a "pipe". I ran the following on a Linux host, to which my gadget
> was connected:
> 
> rogan:/dev/usb# cat hiddev0 | hexdump -C
> 
> In order to see what the host received when I sent data to /dev/hidg1
> on the gadget host.
> 
> $ echo "foo" > /dev/hidg1
> 00000000 02 00 00 ff 66 00 00 00 02 00 00 ff 6f 00 00 00 |....f.......o...|
> 00000010 02 00 00 ff 6f 00 00 00 02 00 00 ff 0a 00 00 00 |....o...........|
> 00000020 02 00 00 ff 00 00 00 00 02 00 00 ff 00 00 00 00 |................|
> *
> 
> $ echo "bar" > /dev/hidg1
> 00000200 02 00 00 ff 62 00 00 00 02 00 00 ff 61 00 00 00 |....b.......a...|
> 00000210 02 00 00 ff 72 00 00 00 02 00 00 ff 0a 00 00 00 |....r...........|
> 00000220 02 00 00 ff 00 00 00 00 02 00 00 ff 00 00 00 00 |................|
> *
> $ printf "1234567890 < to fill a 64 byte packet" > /dev/hidg1
> 00000400 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
> 00000410 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
> 00000420 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
> 00000430 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
> 00000440 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
...

> Which is somewhat surprising!

Have you read Documentation/hid/hiddev.txt?  This looks basically 
right: Each character gives rise to an 8-byte event, where the first 4 
bytes contain the HID usage page and code, and the second 4 bytes 
contain the updated value.  To get the original data as written to the 
hidg1 file, just extract the fifth byte from each group of 8.

> Can anyone tell me what I am doing wrong?

Probably nothing, other than having wrong expectations.

> Here is the setup script that I am using:
> 
> #!/bin/bash
> 
> # based on hidonly.sh by
> #
> # Collin Mulliner <collin AT mulliner.org>
> #
> 
> # Check if the hardware has USB Device Controller capabilty
> UDC=`ls /sys/class/udc/`
> if [ -z "$UDC" ] ; then
> echo "No USB Device Controller hardware found, cannot continue!"
> exit 1
> fi
> 
> modprobe -r g_ether usb_f_ecm usb_f_rndis u_ether
> modprobe usb_f_hid
> 
> cd /sys/kernel/config/
> # Create a gadget
> mkdir usb_gadget/g1
> cd usb_gadget/g1
> 
> # define basic device properties, and corresponding strings
> echo 0x1209 > idVendor
> echo 0x6667 > idProduct
> echo 0x0100 > bcdDevice # v1.0.0
> echo 0x0200 > bcdUSB # USB2
> 
> # 0x0409 is English (United States)
> mkdir strings/0x409
> # echo "fedcba9876543210" > strings/0x409/serialnumber
> echo "SensePost" > strings/0x409/manufacturer
> echo "USaBUSe" > strings/0x409/product
> 
> # define how many configurations the device has. Most will just have one
> mkdir configs/c.1
> # define Max power consumption for Config 1
> echo 120 > configs/c.1/MaxPower
> 
> # define Strings related to Config 1
> mkdir configs/c.1/strings/0x409
> echo "Default" > configs/c.1/strings/0x409/configuration
> 
> # define the available functions that the device supports
> 
> # Set up the combined keyboard and mouse
> mkdir functions/hid.usb0
> cd functions/hid.usb0
> # Non-boot protocol == 0, Keyboard Boot Protocol == 1, Mouse Boot Protocol == 2
> echo 0 > protocol
> # Non-boot subclass == 0, Boot subclass == 1
> echo 0 > subclass
> 
> # Report length is 9 rather than 8, because we include the report
> identifier before the keyboard report
> # This must correspond closely with the report descriptor that follows
> echo 9 > report_length
> echo -ne "\x05\x01\x09\x02\xA1\x01\x85\x01\x09\x01\xA1\x00\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02\x95\x01\x75\x05\x81\x01\x05\x01\x09\x30\x09\x31\x15\x81\x25\x7F\x35\x81\x45\x7F\x95\x02\x75\x08\x81\x06\xC0\xC0\x05\x01\x09\x06\xA1\x01\x85\x02\x05\x07\x19\xE0\x29\xE7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x05\x08\x19\x01\x29\x05\x95\x05\x75\x01\x91\x02\x95\x01\x75\x03\x91\x01\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x95\x06\x75\x08\x81\x00\xC0"
> > report_desc
> cd ../..
> 
> # Set up the raw HID interface
> mkdir functions/hid.usb1
> cd functions/hid.usb1
> # Non-boot protocol == 0, Keyboard Boot Protocol == 1, Mouse Boot Protocol == 2
> echo 0 > protocol
> # Non-boot subclass == 0, Boot subclass == 1
> echo 0 > subclass
> 
> # Report length is 9 rather than 8, because we include the report
> identifier before the keyboard report
> # This must correspond closely with the report descriptor that follows
> echo 64 > report_length
> echo -ne "\x06\x00\xFF\x09\x01\xA1\x01\x09\x02\x15\x00\x25\xFF\x75\x08\x95\x40\x81\x02\x09\x03\x15\x00\x25\xFF\x75\x08\x95\x40\x91\x02\xC0"
> > report_desc

Would you care to provide an English version of this report descriptor?  
I'm not so good at reading hex and mentally performing the rather
arcane translation into the descriptor language.

> cd ../..
> 
> # make the functions available in the defined configuration
> ln -s functions/hid.usb0 configs/c.1
> ln -s functions/hid.usb1 configs/c.1
> 
> # enable the device
> echo "$UDC" > UDC

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

  Powered by Linux