使用Libusb和hidapi测试HID设备
一.测试中断或者Bulk传输:
首先要使用Libusb打印出HID设备的Endpoint查看是否支持中断或者Bulk传输模式;如果支持的话才可以进一步测试;
因为HID设备在插入的时候无需安装,并且一般会被OS直接占用,所以如果直接使用Interrupt传输(通常只有一个断点)会发生超时
所以建议使用zadig给对应的HID设备安装WinUSB来防止直接被占用,然后就可以收到数据了:
对于收到的数据该如何解析(以及如果想要修改Device来发送不同的字母)可以查看:HID键盘对照表 和 字母的ASCII码表;
这是我的一部分解析数据的代码(传入参数就是接收缓冲区的首地址指针)
1 void parse_mouse_data(char* data)
2 {
3 char c1 = *data;
4 char c2 = *(data + 1);
5 char c3 = *(data + 2);
6 char c4 = *(data + 3);
7 if (c1 & LEFT_PRESS)
8 printf("Left key press\n");
9 if (c1 & RIGHT_PRESS)
10 printf("Right Key Press\n");
11 if (c1 & MIDLE_PRESS)
12 printf("Middle Key Press\n");
13 if (c2 & LEFT_SIDE)
14 printf("Go Left : %d\n", (c2 & 0x7f));
15 else
16 printf("Go Right : %d\n", (c2 & 0x7f));
17 if (c3 & DOWN_SIDE)
18 printf("Go Down : %d\n", (c3 & 0x7f));
19 else
20 printf("Go Up : %d\n", (c3 & 0x7f));
21 }
22 void parse_keyboard_data(char* data)
23 {
24 char temp1 = *data;
25 if (temp1 & (0x1 << 0))
26 printf("Left Control Presed");
27 if (temp1 & (0x1 << 1))
28 printf("Left Shift Pressed\n");
29 if (temp1 & (0x1 << 2))
30 printf("Left Alt Pressed\n");
31 if (temp1 & (0x1 << 4))
32 printf("Right Control Pressed\n");
33 if (temp1 & (0x1 << 5))
34 printf("Right Shift Pressed\n");
35 if (temp1 & (0x1 << 6))
36 printf("Right Alt Pressed\n");
37 char alpha = data + 3;
38 printf("input: %c\n", (char)((int)alpha + ASCII_LOWERCASE_SUB));
39 }
二.如果失败了之后之后测试就会一直失败的问题:
查找资料:如果不是EP0端点传输时,Device收到了不支持或者无效的请求,对应的EP将会在data或者status阶段返回STALL故障 —— 需要Host的EP0发送clear Halt指令才能重新启用这个EP( 也就是需要使用Libusb提供的clear_halt函数)
三. HID report
这是标志一个设备是HID的重要方式:report数组:
注意要区分:报告和报告描述符:前者是用来传输数据(在get report和set report命令,控制EP中传输)后者是对数据用途的说明,是一个数组;
可以根据 HID设备描述符的官方文档 来写自己的HID report array;当然更方便的是结合使用官方提供的 Dt工具 生成更保险;
是我对device,interface,endpoint的修改:
1 /*
2 * for maxPakcetSize0 for device descriptor
3 * it means the mas packet size for endpoint 0
4 * for low: 8; for full: 8 or 16, 32, 65; for high : only can be 64
5 */
6 device_descriptor{
7 .bcdUSB = 0x0210, //表示这个是HID设备
8 .bDeviceClass = 0x00,
9 .bDeviceSubClass = 0x00,
10 .bDeviceProtocol = 0x00,
11 }
12
13 /*
14 * bConfiguration Value must >= 0x01
15 * if == 0x00, after set configuration, enter not configured state
16 * bmAttributes in Config desc
17 * for usb2.0 bit7 reserved must 1
18 * bit6 = 1:means self-powered
19 * bit5 = 1:means Remote Wakeup
20 * rest must be 0
21 */
22 config_descriptor{
23 .bmAttributes = 0xA0,
24 .bMaxPower = 0x32,
25 }
26
27 /*
28 * interfaceClass: class code : delivered by USB-IF; == bDeviceClass
29 * 0x03 means HID
30 * iInterface == 0 means there is no string descriptor
31 */
32 interface_descriptor{
33 .bInterfaceClass = 0x03,
34 .bInterfaceSubClass = 0x00,
35 .bInterfaceProtocol = 0x00,
36 .iInterface = 0x00,
37 }
38
39 /*
40 * for hid descriptor type == 0x21
41 * bDesccriptorType: 0x21 means HID;
42 * bDescriptorType0 : Lower level desciptor : 0x22 means report
43 */
44 hid_descriptor{
45 .bDescriptorType = 0x21,
46 .bDescriptorType0 = 0x22,
47 .wDescriptorLength0 = REPORT_DESC_SIZE,
48 }
49
50 // 下面是使用的HID report结构:
51 0x05, 0x0c, // USAGE PAGE 使用 Consumer Devices 这样就不会被OS直接占用,可以进行bulk等传输
52 0x09, 0x01, // USAGE 使用 Consumer Control
53 0xa1, 0x01, // Collection 选择 Application;
54 0x09, 0x00, // USAGE 使用 Unassigned定义自己的report;
55 0xc0 // End of Collection
四. Get. Set report 指令的使用:
这一部分才是使用的精髓:之前使用多个都是中断传输;但是HID设备更常用或者说更应该使用控制节点传输的report命令:
因为前者中断传输算是异步:需要另外开辟一个线程来等待监听;但是控制节点的类似于同步,对于Host来说更方便:
参考:


所以两者分别是 0xa1 0x01 和 0x21 0x09
然后通过控制节点传输的方法就可以传输了
并且注意:如果是对于HID设备传输时候(在Windows中)一定要将buffer的第一个Byte写为在report 数组中龟腚的ReportID(默认是0x00)才能被传输;
使用libusb中的interrupt_transfer如果判断device是hid设备将会转给hid_transfer函数,所以将ReportID设置为第一个字符非常重要。
五. hidapi踩坑:
相比起Libusb:Hidapi并没有caim interface;以及判断是否被占用和clear_halt等命令;对于mouse之类的无能为力;
并且提供的set report函数功能也很有限;不建议使用;但是比较简单。
使用Libusb和hidapi测试HID设备的更多相关文章
- android usb Host模式下与usb Hid 设备的通信
做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...
- 使用LIBUSB实现和自定义通讯设备通讯--MFC代码在末尾
LIBUSB是一款简单好用的USB通讯开发库,一般HID设备用该库通讯能大大降低开发周期,使用如下,首先需要为设备安装驱动 在libusb的bin目录下有一个inf_wirzed.exe的文件,该文件 ...
- C# 访问USB(HID)设备
原文:C# 访问USB(HID)设备 二话不说,直接给代码,如果您真想做这方面的东西,还是稍微研究下,没有现成的好类用,就需要自己了解其原理 //引用空间 using System; using Sy ...
- HIDKomponente使用读写Hid设备一瞥
HIDKomponente 是delphi中使用的第三方Hid控件库,可以检测.控制连接到电脑的Hid设备.一般情况下多为usb设备.HIDKomponente的使用实际上很简单,只是因为第一次使用, ...
- 第五章 HID设备
5.1 HID介绍 为简化USB设备的开发过程,USB提出了设备类的概念.所有设备类都必须支持标准USB描述符和标准USB设备请求.如果有必要,设备类还可以自行定义其专用的描述符和设备请求,这分别被称 ...
- Android USB Host 与 Hid 设备通信bulkTransfer()返回-1问题的原因
近期一直在做Android USB Host 与USB Hid设备(STM32FXXX)的通信,遇到了很多问题.项目源码以及所遇到的其他问题可以见本博客其他相关文章,这里重点讲一下bulkTransf ...
- [Android] hid设备按键流程简述
hexdump /dev/hidraw0就能看到usbhid设备传输过来的裸流 如:按下Input键 003ae60 0000 0096 8000 006b 0000 0000 0000 0000 * ...
- Windows与自定义USB HID设备通信说明.
1 . 所使用的典型 Windows API CreateFile ReadFile WriteFile 以下函数是 DDK 的内容: HidD_SetFeature HidD_GetFeatur ...
- USB自定义HID设备实现-LPC1768
首先在之前鼠标的基础上修改设备描述符 #include "usbdesc.h" //usb标准设备描述符 const U8 USB_DeviceDescriptor[] = { U ...
- USB自定义HID设备实现-STM32
该文档使用USB固件库,在其基础上进行了自己的定制,完成了一个USB-HID设备,首先是usb_desc.c文件,里面存放了usb各种描述符的存在 #include "usb_desc.h& ...
随机推荐
- MRS_开发编译与设置相关问题汇总
解决问题如下: MRS开发编译时,如何修改工程优化等级 MRS进行工程编译时,如何配置FLASH.RAM显示占比 打印浮点类型 配置LD文件在工程中显示 使用sprintf打印 当重复多次调用相同函数 ...
- countdownlatch应用场景
场景1 让多个线程等待:模拟并发,让并发线程一起执行 为了模拟高并发,让一组线程在指定时刻(秒杀时间)执行抢购,这些线程在准备就绪后,进行等待(CountDownLatch.await()),直到秒杀 ...
- git分支的一些处理情况记录
一.开发分支(dev)上的代码更新后,要合并到 master 分支 git checkout dev #切换到dev分支 git pull #将远程更新的代码同步到本地 git checkout ma ...
- Redis避坑指南:为什么要有分布式锁?
作者:京东保险 张江涛 1.为什么要有分布式锁? JUC提供的锁机制,可以保证在同一个JVM进程中同一时刻只有一个线程执行操作逻辑: 多服务多节点的情况下,就意味着有多个JVM进程,要做到这样,就需要 ...
- P28_全局配置 - 常用的全局配置项以及小程序窗口的组成部分
全局配置文件及常用的配置项 pages 记录当前小程序所有页面的存放路径 window 全局设置小程序窗口的外观 tabBar 设置小程序底部的 tabBar 效果 style 是否启用新版的组件样式 ...
- 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介
️Reference: IoT 边缘计算系列文章 什么是边缘容器? 边缘容器的概念 边缘容器是分散的计算资源,尽可能靠近最终用户或设备,以减少延迟.节省带宽并增强整体数字体验. 可以访问互联网的设备数 ...
- BUUCTF-[强网杯2019]随便注
强网杯2019随便注 它说随便注,它可不是随便注入的哈 首先测试闭合环境,因为有回显,所以很快即知道了是一个单引号闭合 接下来常规操作,得到列数大概为2 1';select 2; 返回了过滤信息 于是 ...
- 【KAWAKO】在windows上用CMake和MinGW编译c++工程
目录 安装CMake 安装MinGW 编写CMakeLists.txt 编译一条龙 安装CMake 在网上随便找个教程照着安装就行了,不再赘述. 安装MinGW 参考这篇博客.从MinGW官网下载的安 ...
- Lucky Tree
题目:http://codeforces.com/problemset/problem/109/C 题意:一棵树n个节点,组成一个图,每条边都有权值,对于i.j.k三个数,计算所有的 i 到 j 和 ...
- JSP 页面引入静态资源 404 未找到
jsp 页面引入了 css 文件,部署项目时发现 css 不生效,打开 f12 查看网络,发现请求状态码是 404.导致这个问题的情况大概有以下两种情况: 如果你通过浏览器 f12 查看 link 或 ...