c - 如何通过 gatt 从 esp32 的 hid ble 键盘发送扫描代码 >255?

标签 c embedded hid esp32 esp-idf

我正在使用 esp-32 esp-idf HID 库 ( https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/ble_hid_device_demo ) 制作一个自定义键盘,将扫描代码发送到 Android 设备。我需要发送扫描码 = 310,其中包含两个字节的数据。

我有一个设备需要 ble hid 键盘按钮的扫描码 = 310[dec]。当我尝试将此代码作为 uint8_t key_vaule[] 发送时,因为它在 ble_hid_device_demo 项目的 ble_hid_demo_main.c 中使用,设备收到另一个扫描代码,它从 000 0001 0011 0110 [310dec] 截断为 0011 0110 [155dec]。我想这是因为传输变量的大小是 8 位而不是 16 位。将库从 uint8_t 大小修改为 uint16_t 没有任何结果,结果仍然被截断。有没有办法发送两字节代码而不是 1 字节?

最佳答案

HID scan codes始终是 8 位。在这种情况下,诸如 left-CTRL+<, 之类的组合键是一系列“键修饰符”(0x01 表示 left-CTRL )和 key 代码(<, 为 0x36)。

虽然 0x0136 恰好是 31010,但出于多种原因,将多字节扫描码序列视为单个整数而不是字节序列是错误的:

  • 机器架构的整数字节可能与为 HID 代码序列定义的整数字节不匹配,
  • 在 HID 键盘报告中,有一个键修饰符字节和最多六个键代码 - 用于最多 6 个常规键的组合和用于同时按下的 Shift、Alt、Ctrl 等组合的八个修饰位,
  • 在 HID 键盘报告中,无论如何,修饰符和第一个键代码之间都有一个“保留”字节,因此无论机器字节顺序如何,0x01 和 0x36 在任何情况下都不连续。

HID scan codes为例,你的 31010 实际上是两个字节 0x01 和 0x36 (十六进制)。当谈论字节序列时,使用十六进制表示法更自然 - 特别是在修饰符是多个 Shift/Ctrl 等键的位掩码的情况下。 0x36 代表键<,,0x01 是左CTRL 的键修饰符。

如果您将值 310 分配给 16 位整数时被截断,那么您很可能将其作为单个值传递给需要 uint8_t 的接口(interface)。 。但如上所述,发送 16 位整数在任何情况下都是不正确的。

您需要发送一个字节序列来形成有效的键盘报告,而不是发送 0x0136 或 31010,如设备的键盘报告描述符所述。在HID键盘报告中,第一个字节是“修饰符掩码”(0x01/left-CTRL),第二个字节被保留,然后最多有6个键码(允许多键组合)支持的键的实际数量,因此报告的长度由报告描述符定义。

查看您链接的 HID 演示中的 API,但很明显,所有这些都被抽象掉了,而且您实际需要做的似乎是这样的:

uint8_t key = HID_KEY_COMMA ;
esp_hidd_send_keyboard_value( hid_conn_id, LEFT_CONTROL_KEY_MASK, &key, 1 ) ;

请注意,修饰符是一个位掩码,允许任意组合修饰键,例如 LEFT_CONTROL_KEY_MASK|RIGHT_CONTROL_KEY_MASK 。 HID 将使用它来指示多个类次,但接收器可能会使用它来允许左键或右键,而没有区别。

关于c - 如何通过 gatt 从 esp32 的 hid ble 键盘发送扫描代码 >255?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56297503/

相关文章:

c - '!!' 是 C 中的现有运算符吗?

c - MISRA 相当于医疗行业?

embedded - 有没有人成功地将 Prex 移植到 Stellaris 芯片?

character - 一组清晰的字母和数字供用户输入

hid - 在 VC++ 中使用 PID 和 VID 函数检测 USB 设备的问题

c - 在 C 语言中,为什么多重声明对全局变量有效但对局部变量无效?

关于函数内外的结构值赋值的混淆

Lua 共存于裸机嵌入式 c 应用程序中

c++ - HAL 中的硬件特定库

macos - DriverKit 是否适用于自定义 USB 设备来控制麦克风音量(无流)?