把進展記錄下來吧,編譯了這個文章提供的程式,SensorTile可以分別當成藍芽鍵盤或者滑鼠了,這一點讓我對藍芽的HID有了深入的瞭解。
藍芽4.0以上的HID是基於HID-over-GATT,如果藍芽IC支援GATT,那麼就可以通過修改韌體來實現作為藍芽HID裝置(例如常見的滑鼠或者鍵盤,以及不常見的TouchScreen)。SensorTile上帶的藍芽IC是BlueNRG-MS,其資料手冊上寫的已經支援的協議有:
Embedded Bluetooth low energy protocol stack: GAP, GATT, SM, L2CAP, LL, RFPHY
確實已經包含了GATT。
當我把鍵盤和滑鼠的例子跑起來的後,開始深入瞭解HID reports描述符相關知識,在這之前我只會使用Android裡的getevent去抓取輸入事件;使用lsusb -vvv查看USB裝置描述符。覺得這已經是最底層了,瞭解了HID reports描述符後,底層就更底了一層,從裝置上的實現方式也瞭解了一下。
關於抓取HID裝置描述符,這個文章USB與BT HID reports描述符實踐與抓包分析裡講得比較詳細了,教會我通過查看/sys/kernel/debug/hid/xxx/rdesc擷取USB或者BT的HID reports描述符以及使用usbhid-dump和hidrd-convert查看。
HID reports描述符描述符比較深奧,找到了一些中文資料USB HID協議中文版——USB介面HID裝置(英文原版資料在這裡),讀起來還比較易懂一些,但是還難以理解透徹。 HID Usage Digitizer(0Dh)
在一個hid-multitouch裝置的HID reports描述符看到了一些官方還沒有定義的Usage,比如Digitizer(0Dh)下的47h, 51h, 54h, 55h等,一直沒有查到相關資料,在Linux核心中查到了,這些已經被Windows超前使用了,並且已經成為規範。如下所示:
/* * as of May 20, 2009 the usages below are not yet in the official USB spec * but are being pushed by Microsft as described in their paper "Digitizer * Drivers for Windows Touch and Pen-Based Computers" */#define HID_DG_CONFIDENCE 0x000d0047#define HID_DG_WIDTH 0x000d0048#define HID_DG_HEIGHT 0x000d0049#define HID_DG_CONTACTID 0x000d0051#define HID_DG_INPUTMODE 0x000d0052#define HID_DG_DEVICEINDEX 0x000d0053#define HID_DG_CONTACTCOUNT 0x000d0054#define HID_DG_CONTACTMAX 0x000d0055
來源:https://elixir.bootlin.com/linux/v4.4/source/include/linux/hid.h#L338
分別代表了不同的意義。 Android
宿主機選用Android,比較開源且更新快,方便調試。
Android中關於藍芽HID,分兩塊,藍芽由bluedroid實現,HID則又經uhid轉回到Linux核心中處理,所以具體到Android上的藍芽HID,只需要深入到的核心中看就可以了,bluedroid只是實現了一個藍牙裝置到核心的通道,不過濾不處理任何具體的HID事件,全權交給核心的HID子系統處理。 Linux核心
Linux核心最終會拿到HID reports描述符,Linux核心中將HID裝置分了4個各類,根據HID reports描述符進行劃分,鍵盤滑鼠都屬於GENERIC(對應Usage Desktop),而最近流行的觸控筆觸控螢幕屬於MULTITOUCH裝置(對應Usage Digitizer)。
/* * HID device groups * * Note: HID_GROUP_ANY is declared in linux/mod_devicetable.h * and has a value of 0x0000 */#define HID_GROUP_GENERIC 0x0001#define HID_GROUP_MULTITOUCH 0x0002#define HID_GROUP_SENSOR_HUB 0x0003#define HID_GROUP_MULTITOUCH_WIN_8 0x0004
這裡就不貼圖了。