Report 描述符解析与报告处理
1. HID 报告模型
HID descriptor 描述数据的位级布局,而不是固定 C 结构:
1 | Report Type |
类型:
- Input:设备到 host;
- Output:host 到设备;
- Feature:双向配置状态。
2. Item
短/长 item 按 type 分为:
- Main:Input/Output/Feature/Collection/End Collection;
- Global:Usage Page、Logical/Physical Min/Max、Report Size/Count/ID、Unit;
- Local:Usage、Usage Min/Max、Designator、String、Delimiter。
parser 使用 global stack、local usage list 和 collection stack。
3. 解析链
1 | hid_open_report() |
传输在 hid_add_device() 前读取 dev_rdesc;专用驱动可在正式 parse 前修复错误字节。
4. 结构
hid_report 包含 report ID、type、bit size、field array。hid_field 包含:
- report offset/size/count;
- logical/physical min/max;
- unit/exponent;
- flags;
- value array;
- usages。
hid_usage 保存 HID usage code、collection index、input code/type 映射。
5. 收包
1 | hid_input_report(type, data, size, interrupt) |
raw_event 只有负值会中止本次处理;零和正值都会继续进入通用 report 解析。按 usage 调用的 event() 则在返回非零时停止该 usage 的通用 input/hiddev 处理,其中负值还会记录错误。
6. 数组与变量
- Variable:每个 field element 对应一个 usage/value;
- Array:value 是 usage selector,如键盘按键数组;
- Relative:产生相对事件;
- Absolute:产生绝对坐标;
- Null state:允许无有效 selector。
键盘数组需比较前后 report,生成 press/release。
7. Report ID
若 descriptor 声明任一 report ID,传输数据首字节通常是 ID。Core 的 report_enum->numbered 控制偏移。编号和非编号 report 混用或长度错误是常见固件问题。
8. 输出编码
1 | hid_set_field() |
调用者必须遵守 report type、ID、长度和 logical range。
9. 安全边界
报告描述符和输入报告都来自外设,属于不可信输入。Core 限制 descriptor/report 大小、collection 深度、usage 数量并检查位偏移。专用 report_fixup 也必须验证 rsize 后再访问固定 offset。
10. 可观测
1 | cat /sys/bus/hid/devices/*/report_descriptor > rdesc.bin |
debugfs 节点依赖 CONFIG_DEBUG_FS。
正在加载留言…