问题点 7: 关于BLE HIDS data 写入到Android 节点"/dev/uhid"的flow;
关于BLE中的HIDS,首先我们需要理解好角色的定义:
GATT Server 作为HID Service 提供者,对应HID Device角色;
GATT Client 作为BLE的主动连接发起方,对应HID Host角色;
Android BT中的BlueDroid 部分,关于HID Host Le的处理和BR/EDR 的HID Host 同一个文件夹下,为bta_hh_le.cc:
需注意的是:HIDS 中的Report Descriptor是通过BLE 的”Read Request”指令获取到;
如游戏手柄的按键信息,是通过Notification 形式发送到GATT Client端(手机端)
当收到Notification时,最终通过bta_hh_co_write写report到Android;
-->当收到Notification时,触发API bta_hh_le_input_rpt_notify,内部直接调用
bta_hh_co_data,最终通过bta_hh_co_write写report到Android 节点"/dev/uhid";
比较特别的是:其在收到的Report Len中,自行附上了一个Report ID值;
附上Report ID值后,基本和BR/EDR HID一样的数据格式“Report ID + Data”
最后总结:
BLE的HID操作Android 节点"/dev/uhid"实现,相比BR/EDR 的HID:其没有GET_REPORT等指令操作,只需Open后,通过API bta_hh_co_send_hid_info 把Report Map 写入到Android 节点,然后再把 UUID 为0x2A4D 所对应的Value Handle 接收到的Notification 通过 API bta_hh_co_data写入,但这里写Report Data和BR/EDR 的HID的最大差异是:Notification中的Report Data 是不带Report ID的,需要我们在收到HID Report 的Notification后,自行组合为“Report ID + Report Data”形式再调用API bta_hh_co_data;
而Report ID的识别是在Report Map中解析得到,我们目前使用“Report ID +Data长度”形式进行识别,例如:加入当前我们识别到两个Report ID 分别对应不同的长度,那么在收到Notification时通过匹配Data长度来决定使用哪一个Report ID(如果Report Map中不同Report ID 所对应的Data 长度一致,将无法识别,但这里没有其他办法进行识别);
Note:如果Report MAP 中没有Report ID,此时需默认Report ID 为0;