Raw hid gadget

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

 



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...|
00000450 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
00000460 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
00000470 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
00000480 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
00000490 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
000004a0 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
000004b0 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
000004c0 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
000004d0 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
000004e0 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
000004f0 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
00000500 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
00000510 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
00000520 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
00000530 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
00000540 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
00000550 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
00000560 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
00000570 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
00000580 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
00000590 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
000005a0 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|
000005b0 02 00 00 ff 35 00 00 00 02 00 00 ff 36 00 00 00 |....5.......6...|
000005c0 02 00 00 ff 37 00 00 00 02 00 00 ff 38 00 00 00 |....7.......8...|
000005d0 02 00 00 ff 39 00 00 00 02 00 00 ff 30 00 00 00 |....9.......0...|
000005e0 02 00 00 ff 31 00 00 00 02 00 00 ff 32 00 00 00 |....1.......2...|
000005f0 02 00 00 ff 33 00 00 00 02 00 00 ff 34 00 00 00 |....3.......4...|

Which is somewhat surprising!

Can anyone tell me what I am doing wrong?

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
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
--
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