/configfs_test.sh
| #!/bin/bash | |
| sleep 15 | |
| # Create gadget | |
| mkdir /sys/kernel/config/usb_gadget/mykeyboard | |
| cd /sys/kernel/config/usb_gadget/mykeyboard | |
| # Add basic information | |
| echo 0x0100 > bcdDevice # Version 1.0.0 | |
| echo 0x0200 > bcdUSB # USB 2.0 | |
| echo 0x00 > bDeviceClass | |
| echo 0x00 > bDeviceProtocol | |
| echo 0x00 > bDeviceSubClass | |
| echo 0x08 > bMaxPacketSize0 | |
| echo 0x0104 > idProduct # Multifunction Composite Gadget | |
| echo 0x1d6b > idVendor # Linux Foundation | |
| # Create English locale | |
| mkdir strings/0x409 | |
| echo "My manufacturer" > strings/0x409/manufacturer | |
| echo "My virtual keyboard" > strings/0x409/product | |
| echo "0123456789" > strings/0x409/serialnumber | |
| # Create HID function | |
| mkdir functions/hid.usb0 | |
| echo 1 > functions/hid.usb0/protocol | |
| echo 8 > functions/hid.usb0/report_length # 8-byte reports | |
| echo 1 > functions/hid.usb0/subclass | |
| # Write report descriptor | |
| echo "05010906a101050719e029e71500250175019508810275089501810175019503050819012903910275019505910175089506150026ff00050719002aff008100c0" | xxd -r -ps > functions/hid.usb0/report_desc | |
| # Create configuration | |
| mkdir configs/c.1 | |
| mkdir configs/c.1/strings/0x409 | |
| echo 0x80 > configs/c.1/bmAttributes | |
| echo 200 > configs/c.1/MaxPower # 200 mA | |
| echo "Example configuration" > configs/c.1/strings/0x409/configuration | |
| # Link HID function to configuration | |
| ln -s functions/hid.usb0 configs/c.1 | |
| # Enable gadget | |
| ls /sys/class/udc > UDC | |
| sleep 15 | |
| /usr/local/bin/tester.sh & | |
| # /usr/local/bin/tester.py & |
| #!/usr/bin/env python3 | |
| # | |
| # Python file to test the gadget by writing "Hello World!" | |
| # If used with the configfs_test.sh, place this file under /usr/local/bin/tester.py | |
| # and uncomment the appropriate line | |
| NULL_CHAR = chr(0) | |
| def write_report(report): | |
| with open('/dev/hidg0', 'rb+') as fd: | |
| fd.write(report.encode()) | |
| # H (press shift and H) | |
| write_report(chr(32)+NULL_CHAR+chr(11)+NULL_CHAR*5) | |
| # e | |
| write_report(NULL_CHAR*2+chr(8)+NULL_CHAR*5) | |
| # ll | |
| write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
| write_report(NULL_CHAR*8) | |
| write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
| # o | |
| write_report(NULL_CHAR*2+chr(18)+NULL_CHAR*5) | |
| # SPACE | |
| write_report(NULL_CHAR*2+chr(44)+NULL_CHAR*5) | |
| # W (press shift and W) | |
| write_report(chr(32)+NULL_CHAR+chr(26)+NULL_CHAR*5) | |
| # o | |
| write_report(NULL_CHAR*2+chr(18)+NULL_CHAR*5) | |
| # r | |
| write_report(NULL_CHAR*2+chr(21)+NULL_CHAR*5) | |
| # l | |
| write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
| # d | |
| write_report(NULL_CHAR*2+chr(7)+NULL_CHAR*5) | |
| # ! (press shift and 1) | |
| write_report(chr(32)+NULL_CHAR+chr(30)+NULL_CHAR*5) | |
| # Release all keys | |
| write_report(NULL_CHAR*8) |
| #!/bin/bash | |
| # | |
| # Bash file to test the gadget by writing "Hello World!" | |
| # If used with the configfs_test.sh, place this file under /usr/local/bin/tester.sh | |
| # and uncomment the appropriate line | |
| function write_report { | |
| echo -ne $1 > /dev/hidg0 | |
| } | |
| # H (press shift and H) | |
| write_report "\x20\0\xb\0\0\0\0\0" | |
| # e | |
| write_report "\0\0\x8\0\0\0\0\0" | |
| # ll | |
| write_report "\0\0\xf\0\0\0\0\0" | |
| write_report "\0\0\0\0\0\0\0\0" | |
| write_report "\0\0\xf\0\0\0\0\0" | |
| # o | |
| write_report "\0\0\x12\0\0\0\0\0" | |
| # SPACE | |
| write_report "\0\0\x2c\0\0\0\0\0" | |
| # W (press shift and W) | |
| write_report "\x20\0\x1a\0\0\0\0\0" | |
| # o | |
| write_report "\0\0\x12\0\0\0\0\0" | |
| # r | |
| write_report "\0\0\x21\0\0\0\0\0" | |
| # l | |
| write_report "\0\0\xf\0\0\0\0\0" | |
| # d | |
| write_report "\0\0\x7\0\0\0\0\0" | |
| # ! (press shift and 1) | |
| write_report "\x20\0\x1e\0\0\0\0\0" | |
| # Release al keys | |
| write_report "\0\0\0\0\0\0\0\0" |
This comment has been minimized.
This comment has been minimized.
zbeekman
commented
Aug 1, 2018
|
@rmed: Great blog post! (https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-setup-and-device-definition) Where is tester.sh or tester.py? I would like to get more information on setting up sending keystrokes via USB. I'm making a little password vault/manager gadget and it would be great to be able to send the password input over USB. |
This comment has been minimized.
This comment has been minimized.
|
@zbeekman: I updated the gist with the Python and Bash scripts I used to test the gadget config, they simply write |
This comment has been minimized.
This comment has been minimized.
flash76
commented
Dec 5, 2018
•
|
@rmed: Thanks for the tutorial, but I am having some problems. When I run |
This comment has been minimized.
This comment has been minimized.
|
@flash76 Seems like the device already exists when you try to execute the script. Is there any gadget preconfigured in the RPi (e.g. ethernet over USB)? |
This comment has been minimized.
This comment has been minimized.
Shamber
commented
Mar 19, 2019
|
Hi. |
This comment has been minimized.
This comment has been minimized.
seffyroff
commented
May 26, 2019
|
I'm not having any luck getting this going. I have Stretch Lite 2018-06-27 flashed on my Pi0W. The configfs_test.sh and tester.sh scripts in the right place, and it seems like the initialization works, looking at dmesg. tester.sh hangs forever however :/ |
This comment has been minimized.
This comment has been minimized.
shehrozeee
commented
Nov 10, 2019
|
tested and working on pi0w |
This comment has been minimized.
This comment has been minimized.
nsauzede
commented
Feb 27, 2020
•
|
|
This comment has been minimized.
This comment has been minimized.
n1nj4888
commented
Mar 11, 2020
•
|
Anyone have an idea of how to send the combination of "CTRL"+"SHIFT"+"1" keys? |
This comment has been minimized.
This comment has been minimized.
Try the following (using the Python example): write_report(chr(48)+NULL_CHAR+chr(30)+NULL_CHAR*5) |
This comment has been minimized.
rmed commentedJul 8, 2018
Tested on Raspbian Stretch (lite) 2018-06-27.