使用Pi Zero W模拟HID键盘和鼠标 [英] Using Pi Zero W to simulate HID keyboard and mouse
问题描述
我的目的是将PiZeroW用作计算机的HID键盘和鼠标USB输入设备.
My intention is to use a PiZeroW as an HID keyboard and mouse USB input device to computers.
我已经咨询了以下内容
- https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/一个很好的概述,其中包含指向usb.org文档的链接
- https://eleccelerator.com/usbdescreqparser/用于检查报告文件的解析器
- 隐藏式键盘,操纵杆,鼠标的示例代码 https://github.com/msemtd/promicro-joypad/blob/master/HID.cpp
- 还 http://www.isticktoit.net/?p=1383
- https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/ a good overview with links to usb.org's documentation
- https://eleccelerator.com/usbdescreqparser/ a parser to check the report file
- example code for hid keyboard, joystick, mouse https://github.com/msemtd/promicro-joypad/blob/master/HID.cpp
- also, http://www.isticktoit.net/?p=1383
我以为我可以将键盘和鼠标描述符组合到一个文件中,并为每个文件添加REPORT_ID
I thought I could just combine the keyboard and mouse descriptors into one file, adding REPORT_ID to each
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE7, // Usage Maximum (0xE7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maximum (Kana)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x85, 0x02, // Report ID (2)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x03, // Usage Maximum (0x03)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0xC0, // End Collection
// 117 bytes
然后,设置rc.local以自动执行/usr/bin/isticktoit_usb即可,即
And then, it's a matter of setting up rc.local to automatically execute /usr/bin/isticktoit_usb, i.e.
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p isticktoit
cd isticktoit
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
#echo 0x1d6b > idVendor # Linux Foundation
#echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x2341 > idVendor # pretend leonardo
echo 0x8036 > idProduct # pretend leonardo
mkdir -p strings/0x409
echo "fedcba9876543210" > strings/0x409/serialnumber
echo "pi zero w HID" > strings/0x409/manufacturer
echo "iSticktoit.net USB Device" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1: ECM network" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
# Add functions here
# see gadget configurations below
# End functions
# Add functions here
mkdir -p functions/hid.usb0
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 8 > functions/hid.usb0/report_length
echo -ne \\x05\\x01\\x09\\x06\\xA1\\x01\\x85\\x01\\x05\\x07\\x19\\xE0\\x29\\xE7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xC0\\x05\\x01\\x09\\x02\\xA1\\x01\\x09\\x01\\xA1\\x00\\x85\\x02\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7F\\x75\\x08\\x95\\x02\\x81\\x06\\xC0\\xC0 > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
# End functions
echo 0x80 > configs/c.1/bmAttributes
echo 200 > configs/c.1/MaxPower # 200 mA
ls /sys/class/udc > UDC
chown pi /dev/hidg0
sleep 3
绞线只是为了让用户pi通过测试程序(如
The chown line is just to let user pi access the hidg0 port, with a test program such as
#!/usr/bin/python3
import time
time.sleep(3)
NULL_CHAR = chr(0)
def write_report(report):
with open('/dev/hidg0', 'rb+') as fd:
fd.write(report.encode())
# Press a
write_report(chr(2) + NULL_CHAR*2+chr(4)+NULL_CHAR*5)
# Release keys
write_report(chr(2)+ NULL_CHAR*8)
# Press B
write_report(chr(2) + chr(32) + NULL_CHAR + chr(5)+NULL_CHAR*5)
# Release keys
write_report(chr(2) + NULL_CHAR*8)
第一个字符表示该报告用于REPORT_ID 2,即键盘.
The first character says the report is meant for REPORT_ID 2, i.e. the keyboard.
我能够获得PZW来模拟键盘.但是添加REPORT_ID和鼠标描述符似乎使仿真无法识别为USB设备.
I was able to get the PZW to emulate a keyboard. But adding REPORT_ID and the mouse descriptor seems to make the emulation unrecognizable as a USB device.
测试程序返回
Traceback (most recent call last):
File "./composite.py", line 14, in <module>
write_report(chr(2) + NULL_CHAR*2+chr(4)+NULL_CHAR*5)
File "./composite.py", line 11, in write_report
fd.write(report.encode())
BrokenPipeError: [Errno 108] Cannot send after transport endpoint shutdown
我哪里出错了?
推荐答案
这仍然是一个很好的教程 https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-setup-and-device-definition/
This remains a good tutorial https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-setup-and-device-definition/
这是我使用过的文件
(1)/usr/bin/isticktoit_usb
(1) /usr/bin/isticktoit_usb
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p isticktoit
cd isticktoit
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
#echo 0x1d6b > idVendor # Linux Foundation
#echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x2341 > idVendor # pretend leonardo
echo 0x8036 > idProduct # pretend leonardo
mkdir -p strings/0x409
echo "fedcba9876543210" > strings/0x409/serialnumber
echo "pi zero w HID" > strings/0x409/manufacturer
echo "iSticktoit.net USB Device" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1: ECM network" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
# Add functions here
# see gadget configurations below
# End functions
# Add functions here
mkdir -p functions/hid.usb0
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 8 > functions/hid.usb0/report_length
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x85\\x01\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x09\\x38\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x03\\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\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
# End functions
echo 0x80 > configs/c.1/bmAttributes
echo 200 > configs/c.1/MaxPower # 200 mA
sleep 10
ls /sys/class/udc > UDC
sleep 2
chown pi /dev/hidg0
sleep 2
(2)test.py
(2) test.py
#!/usr/bin/python3
import time
time.sleep(3)
NULL_CHAR = chr(0)
def write_report(report):
with open('/dev/hidg0', 'rb+') as fd:
fd.write(report.encode())
# Press a
write_report(chr(2) + NULL_CHAR*2+chr(4)+NULL_CHAR*5)
# Release keys
write_report(chr(2)+ NULL_CHAR*8)
# Press B
write_report(chr(2) + chr(32) + NULL_CHAR + chr(5)+NULL_CHAR*5)
# Release keys
write_report(chr(2) + NULL_CHAR*8)
# testing mouse
write_report(chr(1)+NULL_CHAR+chr(100)+chr(0)+NULL_CHAR)
time.sleep(2)
write_report(chr(1)+NULL_CHAR+chr(100)+chr(100)+NULL_CHAR)
time.sleep(2)
write_report(chr(1)+NULL_CHAR+chr(228)+chr(228)+NULL_CHAR)
这篇关于使用Pi Zero W模拟HID键盘和鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!