目錄
- 1. 核心配置
- 2. 裝置配置
- 附 wireshark USB抓包配置
linux下模擬USB HID裝置的簡單記錄,其他USB裝置類似。
1. 核心配置
核心啟用USB Gadget,使用fs配置usb device資訊。
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support --->
<*> USB Gadget functions configurable through configfs
[*] HID function
<*> USB Gadget precomposed configurations (Function Filesystem) --->
2. 裝置配置
HID裝置配置如下,需要將該shell函式新增到啟動指令碼中,其中的相關描述符配置自行根據USB 協議配置,然後呼叫該指令碼。
usb_hid_device_config()
{
if [ -d /sys/kernel/config/usb_gadget/ ] ; then
######USB HID Device config######
cd /sys/kernel/config/usb_gadget/
mkdir -p isticktoit
cd isticktoit
echo 0x0483 > idVendor
echo 0x5710 > idProduct # STM32
echo 0x0215 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "xxxxxx" > strings/0x409/serialnumber
echo "xxxxxx" > strings/0x409/manufacturer
echo "xxxxxx" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "HID_CONFIGUE" > configs/c.1/strings/0x409/configuration
echo 2 > configs/c.1/MaxPower
# Add functions here
mkdir -p functions/hid.usb0
echo 0 > functions/hid.usb0/protocol
echo 0 > functions/hid.usb0/subclass
echo 64 > functions/hid.usb0/report_length
# Set HID in/out desc
echo -ne \\x05\\x81\\x09\\x82\\xa1\\x01\\x09\\x83\\x09\\x84\\x15\\x00\\x26\\xff\\x00\\x75\\x08\\x95\\x40\\x81\\x02\\x09\\x84\\x15\\x00\\x26\\xff\\x00\\x75\\x08\\x95\\x40\\x91\\x02\\xc0 > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
# End functions
ls /sys/class/udc > UDC
######USB HID Device end######
else
errlog "usb_gadget not found!"
return 1
fi
}
- 示例demo
usb裝置節點為/dev/hidg0,以下為應用層USB收發示例;
/* hid_gadget_test */
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_LEN 512
struct options {
const char *opt;
unsigned char val;
};
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
#define HEXDUMP_WIDTH 16
void debug_hexdump(unsigned char *data, unsigned long size, unsigned char *headinfo)
{
unsigned long i, j;
unsigned long addr;
printf("%s 0x%08X, size is %ld. The data is:\n", headinfo, addr,
size);
printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
for (i = 0; i < size; i += HEXDUMP_WIDTH)
{
printf("[%08X] ", addr + i);
/* dump hex */
for (j = 0; j < HEXDUMP_WIDTH; j++)
{
if (i + j < size)
{
printf("%02X ", data[i + j]);
}
else
{
printf(" ");
}
}
/* dump char for hex */
for (j = 0; j < HEXDUMP_WIDTH; j++)
{
if (i + j < size)
{
printf("%c", __is_print(data[i + j]) ? data[i + j] : '.');
}
}
printf("\n");
}
printf("\n");
}
int main(int argc, const char *argv[])
{
const char *filename = NULL;
int fd = 0;
char buf[BUF_LEN];
int cmd_len;
char report[64] = {0};
int to_send = 8;
int hold = 0;
fd_set rfds;
int retval, i;
if (argc < 2) {
fprintf(stderr, "Usage: %s devname\n",
argv[0]);
return 1;
}
filename = argv[1];
if ((fd = open(filename, O_RDWR|O_DSYNC, 0666)) == -1) {
perror(filename);
return 3;
}
while (1) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(fd + 1, &rfds, NULL, NULL, NULL);
if (retval == -1 && errno == EINTR)
continue;
if (retval < 0) {
perror("select()");
return 4;
}
if (FD_ISSET(fd, &rfds)) {
cmd_len = read(fd, buf, BUF_LEN - 1);
#ifdef HEX_DEBUG
debug_hexdump(buf, cmd_len, "recv report");
#endif
}
}
close(fd);
return 0;
}
附 wireshark USB抓包配置
安裝wireshark 時同時安裝USB抓包工具usbpcap後,開啟wireshark有兩個USB捕獲介面
我們可以設定其中一個只抓取新接入的裝置
- USBPcap1 作用可指定抓取未接入的USB裝置
- USBPcap2 作用是抓取所有已接入的USB裝置及新裝置
配置後開啟即可抓取新接入USB裝置的所有USB包並解析。