Android BLE為例分析內核UHID


一、Android BLE HID 大致框架

開局一張圖,文章全靠編:

以 Android BLE 架構簡單分析下 UHID 機制,圖中①②不探索,畢竟 bluedroid 這個東西也不是很快就能分析透徹的。

 

二、分析開始

在Android連接中藍牙設備后,會向內核 UHID 發送 creat 消息,中間的橋梁是 /dev/uhid 節點。

UHID驅動會調用到 uhid_dev_create 來初始化bus、vendor、product等信息,並拷貝 report 報文(這個東西很重要,用來描述BLE設備都支持什么操作,例如:INPUT)

進而調用到 uhid_dev_create2 ,期間會 alloc hid 設備,並在最后利用工作隊列中將 hid device 注冊到 hid bus 當中。

有了 device,和對應driver匹配之后才能有后戲,那么它來了 hid_generic ,ANY_BUS、ANY_ID,來吧,它是個 device 就能匹配。

熟悉的總線設備驅動模型,那么之后將調用 bus 的 probe 回調,它是 hid_device_probe ,插入一段簡短的代碼湊字。

 1 static int hid_device_probe(struct device *dev)  2 {  3     struct hid_driver *hdrv = to_hid_driver(dev->driver);  4     struct hid_device *hdev = to_hid_device(dev);  5  ...  6     if (!hdev->driver) {  7         id = hid_match_device(hdev, hdrv);  8         if (id == NULL) {  9             ret = -ENODEV; 10             goto unlock; 11  } 12 
13         hdev->driver = hdrv; 14         if (hdrv->probe) { 15             ret = hdrv->probe(hdev, id); 16         } else { /* default probe */
17             ret = hid_open_report(hdev); 18             if (!ret) 19                 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 20  } 21         if (ret) { 22  hid_close_report(hdev); 23             hdev->driver = NULL; 24  } 25  } 26  ... 27 }

 hid_open_report 用來解析我們前面說的比較重要的那個 report 報文,適配 HID 設備的所有 capability,它也會檢查 report 是否完成通過 COLLECTION 與 END_COLLECTION 的匹配,檢查不通過后就沒有下方了。

 hid_hw_start 是創建給 Android 傳送信息的 event 通道,

 1 int hid_hw_start(struct hid_device *hdev, unsigned int connect_mask)  2 {  3     int error;  4 
 5     error = hdev->ll_driver->start(hdev);  6     if (error)  7         return error;  8 
 9     if (connect_mask) { 10         error = hid_connect(hdev, connect_mask); 11         if (error) { 12             hdev->ll_driver->stop(hdev); 13             return error; 14  } 15  } 16 
17     return 0; 18 }

這里的 ll_driver 指的是 uhid_hid_driver ,ll_driver 會發回 UHID_START 消息通知內核已准備好。hid 是真正的主角,在其內部注冊了 input_device 和 hidraw 字符設備,至此所有的准備工作已就緒。

創建 OK,內核會有類似這樣的打印:

1 [ 0000.0000] input: BLE Remote as /devices/virtual/misc/uhid/0006:0095:0001.0006/input/input9 2 [ 0000.0000] hid-generic 0006:0095:0001.0006: input,hidraw3: BLUETOOTH HID v1.11 Device [BLE Remote] on

 

那再來看看 Bluedroid 是怎么將解析后的數據信息發到 event 的。

Bluedroid 中會調用 bta_hh_co_write 通過 UHID_INPUT 來向內核發送 HID 信息,進而內核調用到 uhid_dev_input 來將上層發過來的 HID 信息寫入到 event 節點和 hidraw 節點,具體細節暫不做深入分析。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM