android hid自动重连,Android Bluetooth HID
8種機械鍵盤軸體對比
本人程序員,要買一個寫代碼的鍵盤,請問紅軸和茶軸怎么選?
HID (Human Interface Device) 定義了藍牙在人機接口設備中的協議、特征和使用規程。典型的應用包括藍牙鼠標、藍牙鍵盤、藍牙游戲手柄等。
2. 協議略讀
HID 設備主要分為 Host 和 Device , 其基本通信方式如下圖 :
2.1 HID Report
Bluetooth HID devices 支持 3 種 report type : Input , Output 和 Feature . 其中 Input 和 Output report 包含低延遲的信息 , 區別是 Input 為 device 發給 host 而 Output 為 host 發給device . Fearture 為雙向包含一些非用戶產生的信息。
HID 連接包含兩條邏輯連接 :Control channel **和 **Interrupt Channel , 兩個 channel 上都可以傳輸 reports , 但是區別是 Control channel 上必須先發送 SET_REPORT / GET_REPORT request 才會傳輸 reports, 這種又被稱為 “synchronous reports” . 而在 Interrupt Channel 上則無須發送requset 和 acknowledg, 又被稱為 “asynchronous reports” .
補充: HID Report Modes 分為兩種 report protocol mode 和 boot protocol mode , 前者是所有 HID devices 的默認模式, host 端必須可以解析 report 。 而boot protocol mode 是針對一些小型的嵌入式系統設置, host 端并不會包含 report 的解析器 。
2.2 Bluetooth HID Protocol Message
HID 數據傳輸直接基于 L2CAP 之上 , 起數據結構為 :
其中 type 的定義為 :
2.3 Disconnect
連接流程和其他 profile 流程差不多,只是如上所述回建立 control 和 interruput 兩個邏輯連接 。 下面看一下 disconnect 流程 :
本地用藍牙鼠標試驗看到 disconnect 其實并沒有發送 VIRTUAL_CABLE_UNPLUG , 而在鼠標斷開連接之后移動鼠標時,鼠標會自動發起連接重新連起來。 而在解配對過程中是完全按照這個流程來走的, 并會刪除 link key , 一般鼠標不會在發起連接。
3. Android HID
HID service 和其他profile 差不多在 enable BT 時完成啟動和初始化,這里不再分析。 這里只關注 device 連接之后 :
首先已配對鼠標發起 ACL 連接請求,DUT接受請求。省略中間的連接細節,在 HID_Control 和 HID_Interrupt 都連接好之后
下面來看一下連接ok 之后的 log 及 對應的 code :
// LOG
bt-btif : bta_hh_open_act: Device[0] connected
bt-btif : bta_hh_sm_execute: State 0x02 [BTA_HH_W4_CONN_ST], Event [BTA_HH_OPEN_CMPL_EVT]
bt-btif : bta_hh_co_open: Found an existing device with the same handle dev_status = 2
void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
......
/* initialize device driver */
bta_hh_co_open(p_cb->hid_handle, p_cb->sub_class, p_cb->attr_mask, p_cb->app_id);
void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_mask,
UINT8 app_id)
{
......
p_dev = &btif_hh_cb.devices[i]
p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); // 打開/dev/uhid p_dev->hh_keep_polling = 1;
p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev); //創建線程監聽uinput driver 上傳的事件 p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
//LOG
bt-btif : bta_hh_sm_execute: State 0x03 [BTA_HH_CONN_ST], Event [BTA_HH_API_GET_DSCP_EVT]
bt-btif : btif_hh_upstreams_evt: event=BTA_HH_GET_DSCP_EVT
bt-btif : bta_hh_co_send_hid_info: fd = 90, name = [Microsoft Sculpt Comfort Mouse], dscp_len = 352
bt-btif : bta_hh_co_send_hid_info: vendor_id = 0x045e, product_id = 0x07a2, version= 0x0129,ctry_code=0x21
void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 vendor_id,
UINT16 product_id, UINT16 version, UINT8 ctry_code,
int dscp_len, UINT8 *p_dscp)
{
//創建 uinput device ev.type = UHID_CREATE;
strncpy((char*)ev.u.create.name, dev_name, sizeof(ev.u.create.name) - 1);
ev.u.create.bus = BUS_BLUETOOTH;
ev.u.create.vendor = vendor_id;
ev.u.create.product = product_id;
...
result = uhid_write(p_dev->fd, &ev);
bt-btif : UHID_START from uhid-dev
bt-btif : UHID_OPEN from uhid-dev 到這里 uinput 設備就創建好了, 后面在收到 device 的 input report 時只需寫入該 fd 即可 : ```c int bta_hh_co_write(int fd, UINT8* rpt, UINT16 len) {
APPL_TRACE_VERBOSE("bta_hh_co_data: UHID write");
struct uhid_event ev;
memset(&ev, 0, sizeof(ev));
ev.type = UHID_INPUT;
ev.u.input.size = len;
memcpy(ev.u.input.data, rpt, len);
return uhid_write(fd, &ev); } ```
4. 相關debug
查看當前input設備詳細信息 : cat /proc/bus/input/devices , 其對應.kl文件應為 Vendor__Product_.kl ,如果找不到那么根據 device name 來找,如果還是找不到則加載 Generic.kl
獲取input設備event結點 : getevent
這時候我要獲取 Microsoft 這個設備的輸入信息:
這里會顯示3列,分別對應 type ,code ,value .例如上面是一個鼠標的左鍵點擊事件:
其中type 0001 (EV_KEY 按鍵事件) 0110代表按鍵值 , 最后的 1 和 0 分別對應 push 和 release 動作。
總結
以上是生活随笔為你收集整理的android hid自动重连,Android Bluetooth HID的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Winsock中accept函数获取到的
- 下一篇: android sina oauth2.