Bluetooth近接検知装置

http://q.hatena.ne.jp/1156781413
初めて注目の質問に載っちゃった!べつに嬉しくないけど!

Bluetoothを近接検地装置(proximity monitor)として使うのはそんなに目新しいことではなくて、たとえばここではGentoo Linuxで、PCから離れたら自動的にスクリーンセーバーが起動するという方法が説明されています。Bluetoothドングル、Bluetooth対応デバイス(何でも良い。イヤホンとかマウスでも!)とLinuxとちょっとしたシェルスクリプトで出来てしまいます。

Linuxにはだいたい標準でBluezというBTスタックがインストールされており、付属のツールであるhciconfig、hcitoolなどでBTをコントロールできる。ちなみにドングルはClass 1と2があって、Class 1は100メートルほど、Class 2は10メートル程度の範囲。スクリーンセーバー起動装置としてはClass 2が良いし、上司検知器としてはClass 1が良いだろう。

質問の通り、Windows XPでネイティブに実行するのは簡単じゃなさそうなんだけど、世の中も便利になり、無料のVMWareを使えば大丈夫です。USBは2つまで接続できて、試してみたけどストレージだけじゃなくてBluetoothドングルも使えました。

ドングルを接続して、Windowsが認識した後にVMWareで[VM - Removable Devices - USB - ]とメニューで選ぶと表示されるので、選びます。その後VMWareのUSBブリッジ(?)がWindowsに認識され、正式にホストOSから利用可能になる。そこでhciconfig(引数なし)を実行すると

#hciconfig
hci0: Type: USB
BD Address: 00:11:XX:YY:ZZ:AA ACL MTU: 678:8 SCO MTU: 48:10
UP RUNNING PSCAN ISCAN
RX bytes:117 acl:0 sco:0 events:15 errors:0
TX bytes:313 acl:0 commands:15 errors:0

みたいな結果が出てくるはずです。状態が"DOWN"の場合は、

#hciconfig hci0 up

としてあげれば走り出します。次にターゲットとなるデバイスのBDアドレス(MACアドレスと同じようなもの)を取得しなければなりませんが、これはデバイスの発見モードをONにして後で、hcitool scanでスキャンを開始します。

#hcitool scan
Scanning ...
00:22:XX:YY:ZZ:AA Palm OSハンドヘルド

上記の例ではSonyClieを発見モードにしてみました。このBDアドレスをメモしておきます。上司検知システムの場合はもうちょっと難しいですが、「部長の携帯ってBT対応なんですか?かっこいい、ちょっとやって見せてください」とかおだてて発見モードをONにしてもらうとか、またはメーカーからある程度予測できるので、btscannerといようなツールを使ってブルートフォース(総当り)で発見することも可能です。

最後に発見する方法ですが、hcitool name というコマンドを使えば、ペアリングしなくても装置が近くにいるか分かります。用は「あなたの名前は?」というコマンドで、BDAddressを知っていればパスワードはいりません。ここでデバイスの名前が返ってくれば「いる」、タイムアウトすれば「いない」という判定になります(質問で書いたRSSIというシグナルの強度は、残念ながらあらかじめConnectしていないと使えないみたいなんです)。

#hcitool name 00:22:XX:YY:ZZ:AA
Palm OS ハンドヘルド

最後のステップとしては、上記のコマンドを繰り返し実行して、返り値によって他のコマンドを実行するシェルスクリプトを書けばいいわけです。こんな感じ:

while [ 1 ]
do
RESULT=`hcitool name $1`
if [ "$RESULT" != "" ]; then
## (上司検知機の場合):近くにいるぞ、ゲームを隠せ!
## スクリーンセーバの場合:近くにいるからなにもしなくて良い
else
## (上司検知器の場合):居ないみたいだ、ゲームをしよう!
## スクリーンセーバの場合:スクリーンセーバー起動
fi
done

ちなみに、上のほうで紹介したGentooの例では、hcitool cc で接続した上でhcitool rssi で信号強度を測るという方法を使っています。これでも良いのですけど、ヘッドセットの場合はうまくconnectできなかったりしたので、hcitool nameが一番確実なのかな?あとはl2pingというのもあります。

参考までに、hcitoolとかのツール郡ではなくて直接ライブラリを使ったサンプルPerlとInline:Cを使っている)へのリンクもこちらに。