蓝牙HID协议基础:HID报告描述符、协议栈分层与HOGP简介

蓝牙HID(Human Interface Device)驱动开发的核心在于理解HID协议如何通过蓝牙无线链路传输。本章从HID报告描述符的语法结构出发,逐层剖析蓝牙HID协议栈的分工,并重点介绍面向低功耗蓝牙的HID Over GATT Profile(HOGP)。掌握这些基础,才能正确配置设备树并完成数据收发测试。

2.1 HID报告描述符

HID报告描述符(Report Descriptor)是一段二进制数据,用于描述设备发送/接收的数据格式、用途和物理范围。主机通过解析描述符,无需预知设备类型即可正确解释输入/输出报告。

2.1.1 描述符结构

描述符由一系列Item(项)组成,每个Item包含一个字节的头部和若干字节的数据。Item分为短项和长项,常用的是短项,格式如下:

位域 宽度(bit) 说明
bSize 2 数据长度:0=0字节,1=1字节,2=2字节,3=4字节
bType 2 项类型:0=Main,1=Global,2=Local,3=Reserved
bTag 4 功能标签,如Input/Output/Collection/Usage Page等

典型的HID键盘描述符片段如下:

0x05, 0x01,        // Usage Page (Generic Desktop)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Key Codes)
0x19, 0xE0,        //   Usage Minimum (224)
0x29, 0xE7,        //   Usage Maximum (231)
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)
0xC0               // End Collection

2.1.2 报告描述符解析流程

关键概念:主机通过Usage Page和Usage确定设备类型(键盘/鼠标/游戏杆),通过Report ID区分多份报告,通过Logical Minimum/Maximum和Report Size/Count计算数据位宽。

下图展示了HID报告描述符的解析与报告生成流程:

HID报告描述符解析与报告生成流程 原始描述符字节流 Item解析器 全局/局部状态表 报告格式描述 HID数据收发 说明:描述符解析完成后,主机获得报告ID、数据位宽、用途映射表,后续收发直接按格式打包/解包。

2.2 蓝牙HID协议栈分层

蓝牙HID协议栈采用分层架构,每一层封装特定的功能,上层依赖下层提供的服务。理解分层有助于定位驱动开发中的问题。

2.2.1 分层模型

层编号 协议层名称 主要职责 典型数据单元
4 HID Service / Profile 报告描述符管理、报告收发、协议控制 HID报告、控制命令
3 GATT / ATT 属性操作(读/写/通知)、服务发现 Attribute PDU
2 L2CAP 数据分段重组、多路复用、MTU协商 L2CAP帧
1 HCI + Link Layer 蓝牙物理传输、ACL数据包、事件上报 HCI命令/事件、ACL数据

2.2.2 各层交互关系

下图展示了蓝牙HID协议栈的层次结构及数据流向:

蓝牙HID协议栈分层架构 HID Profile / Service 报告描述符 · 报告映射 · 控制点 · 中断通道 GATT / ATT 属性表 · 服务发现 · 读/写/通知 · MTU L2CAP 分段重组 · 多路复用 · 流控 · MTU协商 HCI + Link Layer ACL数据包 · 事件上报 · 物理信道管理 数据流向 主机 → HID Profile → GATT → L2CAP → HCI → 蓝牙芯片 设备 → HCI → L2CAP → GATT → HID Profile → 主机
开发要点:在嵌入式Linux中,HID Profile层通常由BlueZ的bluetoothd或btgatt实现;GATT层通过ioctl或dbus接口与用户态交互;L2CAP和HCI由内核蓝牙子系统(bluetooth.ko)提供。设备树配置主要影响HCI底层(UART/USB绑定)和中断引脚。

2.3 蓝牙HID Profile (HOGP)

HOGP(HID Over GATT Profile)是蓝牙低功耗(BLE)上的HID实现标准,定义在Bluetooth Core Specification的HID Service和HID Profile中。它取代了传统BR/EDR的HID Profile,成为BLE HID设备的唯一规范。

2.3.1 HOGP核心特征

特征(Characteristic) UUID 属性 说明
Report Map 0x2A4B Read 存放HID报告描述符
Report 0x2A4D Read/Write/Notify 输入/输出/特征报告数据
Boot Keyboard Input Report 0x2A22 Read/Notify 兼容BIOS的键盘输入
Boot Mouse Input Report 0x2A33 Read/Notify 兼容BIOS的鼠标输入
HID Information 0x2A4A Read HID版本、国家代码等
Protocol Mode 0x2A4E Read/Write 切换报告模式/启动模式
HID Control Point 0x2A4C Write 发送控制命令(如挂起/恢复)

2.3.2 HOGP设备角色与数据流

HOGP定义了两种角色:

  • HID Host(GATT Client):通常是手机、平板、PC,负责读取报告描述符、接收输入报告、发送输出报告。
  • HID Device(GATT Server):键盘、鼠标、游戏手柄,负责提供HID Service,通过Notify发送输入报告,通过Write接收输出报告。

下图展示了HOGP设备与主机之间的典型交互流程:

HOGP设备与主机交互流程 HID Host (GATT Client) HID Device (GATT Server) 服务发现 读Report Map 配置CCCD Notify报告 CCCD:Client Characteristic Configuration Descriptor,使能通知的开关。

2.3.3 HOGP与传统蓝牙HID对比

对比项 传统蓝牙HID (BR/EDR) HOGP (BLE)
传输层 L2CAP + RFCOMM GATT + ATT
功耗 较高(持续连接) 极低(广播+连接事件)
报告传输 中断通道(独立L2CAP信道) GATT Notify/Indicate
描述符获取 HID控制通道 Read Report Map特征
多报告支持 通过Report ID 多个Report特征实例
兼容性 需配对+认证 支持Just Works配对
常见误区:HOGP设备必须实现Report Map特征,且描述符内容必须与Report特征的数据格式严格一致。如果描述符声明了8字节键盘输入报告,但Notify只发送6字节,主机将解析错误或丢弃数据。开发时建议使用hidrd工具验证描述符合法性。

2.4 本章小结

  • HID报告描述符是设备与主机之间的数据契约,通过Item序列定义报告格式和用途。
  • 蓝牙HID协议栈分为HID Profile、GATT/ATT、L2CAP、HCI四层,每层职责清晰,驱动开发需关注HCI和GATT接口。
  • HOGP是BLE HID的唯一标准,基于GATT特征实现报告映射、输入通知和输出写入,功耗低且兼容性好。
  • 设备树配置主要影响HCI底层(UART/USB引脚、中断、时钟),而HID报告描述符和GATT服务由固件或用户态协议栈管理。