HID Proxy機能のあるドングルを使うとOSを介さずUSB HIDキーボードとしてBIOS起動時に認識させることができます。(BIOSというか、近年だと UEFI ですが)
MM-BTUD43 (CSR8510 A10)
一部の BLE USB アダプタには HID Proxy モードが結構前から実装されているようです。これは CSR 社製のものです。たまたま手元にあったのですが、どうやらこれも HID Proxy モードをそなえいるようです。
経緯
BIOS 画面で BLE キーボードを使うため、HID Proxy モードのあるアダプタを探していました。当初そんなものはなさそうと思ってたのですが、最近になって以下のようなページを見つけました。
How to put CSR8510 A10 into HID Proxy Mode?
対象は BLE デバイスのみです。もちろん事前にOSを起動した状態でペアリング(正確にはボンディング)してある必要があります。これによってデバイスに情報が保存され、HID Proxy モードでも通信が可能になります。
しかし、デフォルトでは PSKEY_INITIAL_BOOTMODE は 0x0000 のようで、HID Proxy として働きません。本来メーカーで設定する項目で、ユーザが書きかえられる部分ではありません。ただ、ちょっと面倒ですがデバイスを再設定することができました。
bccmd
Linux の bluez に CSR のデバイスを設定するためのコマンドが含まれており、これを使って HID Proxy モードを有効にします。
手元にさっと利用できる Linux が Raspberry Pi しかなかったので、Raspberry Pi で行いました。bluez が入ってさえいればなんでもいいはずです。おそらく VM 上で起動しても一時的にデバイスを VM 側に接続するようにすれば動くはずです。
USB にデバイスを接続した上で以下のコマンドを実行していきます。
# 現在のブートモードを確認 $ sudo bccmd psget bootmode Initial device bootmode: 0x0000 (0) # アドレスを確認 $ sudo bccmd psread -s 0 ... 0x03cd - Initial device bootmode (2 bytes) ... # アドレスにブートモードを書きこむ 0x0002 が HID Proxy モードらしい $ sudo bccmd psset -s 0 0x03cd 0x0002 # 確認 $ sudo bccmd psget bootmode Initial device bootmode: 0x0002 (2)
しかしどうも、OS起動後は HCI モードに移行というのは全くうまく動きません。HID Proxy から抜けられない。そして、 HID Proxy から抜けられないと bccmd がデバイスを認識しません (productId も変化するんですが、bccmd がそれに対応してないのでUSBデバイスを見付けられない)
ってことで、試したはいいけど戻せなくなってあせりました。
bluez の tools をコンパイル
bluez のツールとして /lib/udev/hid2hci という hid から hci に移行させるツールがあって、これで強制的に HCI にできるかと思いきや、できませんでした。調べているとシステムにインストールされているやつが古かったので、自力でコンパイルします。
http://www.bluez.org/download/
sudo apt-get install libglib2.0-dev sudo apt-get install libdbus-1-dev sudo apt-get install libudev-dev sudo apt-get install libical-dev sudo apt-get install libreadline-dev sudo apt-get install libbluetooth-dev
本来必要ない依存もあるかと思いますが、これらを入れないと configure が通らず Makefile が生成されないので全て入れています。
wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.41.tar.xz tar xJvf bluez-5.41.tar.xz cd bluez-5.41 ./configure make tools/hid2hci
全部ビルドする必要はないので hid2hci のみビルドしました。これで以下のように戻します。
sudo ./tools/hid2hci --method=csr2 --devpath=$(udevadm trigger --subsystem-match=usb --attr-match=idVendor=0a12 --attr-match=idProduct=100b --verbose | cut -d '/' -f 3-) # HCI モードに戻ったので bccmd が普通に使えるように sudo bccmd psget bootmode
method=csr2 がポイントです。最新だとこのメソッドが使えるようになっていて、HCI モードに移行できます。
なお、このコマンドでやっていることは冒頭で引用した中にある feature report を送っているだけです。なので HID のレポートを送れさえすれば bluez をコンパイルする必要はないはずです…… が、さくっと feature report 送るみたいなのもなかなか難しいのでコンパイルしてみました。
HID Proxy モードを活用するためには…
ペアリングするときだけ HCI として起動してくれればいいので、基本的には HID モードでも良いかという気はします。ただ、キーボード1つにつき1つのBLEドングルが必要になりますので、Bluetooth デバイスが他にもあるなら OS 起動中はちゃんと HCI モードになってほしいところです。
ということで、OS起動時にhid2hci相当のことをやるコマンドを起動すれば問題なさそうです。しかしWindows でこれをやるのは若干面倒です。検索すると hid2hci.exe という CSR のツールがあることはわかるのですが、公式に入手する方法が見つけられませんでした (デバイススタックと一緒にインストールされるのかもしれませんが、OS 標準のスタックを使ってるのでインストールしたくありません)。他のところから怪しい .exe なんてダウンロードして実行するのは愚かなことなので、自分でなんとかします。
hid2hcix.exe
結局、自分で書くのが一番てっとり早いので、hidapi を使って書いてみました。mingw でクロスコンパイル環境にして OS X でコンパイルしています。
Linux には hid2hci があるのでいいとして、OSX でも無駄にコンパイルできるので、主要OSで HCI モードにできる安心感が生まれます。
hidapi がそのままだとキーボードのHIDデバイスに対して使えないので、1行だけ修正をいれてあります。キーボード・マウスのようなHIDデバイスはWindowsがOSレベルで握ってしまっていて、デバイスファイルを CreateFile できないという問題があるようです。また、キーボードやマウスには Feature Report のやりとりしかできません。
Linux の hid2hci をまるまる再実装したほうが便利かもしれませんが、HCI から HID に戻す実装は HCI にアクセスする必要があって面倒ですし、自分の環境だと CSR の CSR8510 A10 以外に入手できるものがないので、決め打ちの実装になっています。
レポジトリ内のコードだけでコンパイルも簡単だしこれで必要十分でしょう。これをOS起動時に自動実行するようにすれば、OS起動前はHID Proxy、OS起動後は Bluetooth ドングルとして働くことになります。
国内販売で CSR8510 A10 を使ってると確認できるもの
レビューとかを見るとプロトコルスタックをインストールしている記述が多かったりしますが、Windows 10 なら OS にプロトコルスタックがあるので不要です。自分ではインストールしたことありません。かなり古いレビューがずっと残ってるので注意が必要です。
上にも書きましたが MM-BTUD43 は手元にあって、確認済みです。
PLANEX BT-Micro4 は公式に技術情報を公開していて、CSR 8510A10 であることを表記しています。これも手元にあって、確認済みです。
ロジテック LBT-UAN04C1BK も CSR 8510A10 のようです。これは持ってないので確認してません。高いので特にこれを選ぶ理由はなさそうです。