その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

iBeacon と BLE

昨年末〜今年初めにかけて一世を風靡した iBeacon ですが、なんというか、本来期待されるべき方向ではない方向で期待され、「不当に」ガッカリされることが多いような印象を受けます。

  • 「コンテンツを内部に保持して直接配信することはできない」
  • 「双方向通信はできない」*1
  • 「距離はあてにならない」
  • 「検出できたりできなかったりする」
  • 「ビーコンのバッテリーが意外ともたない」

などなどなどなど。


で、個人的にはこういうガッカリは、「BLEをどのように利用することでiBeaconという領域観測サービスが実現されているか」を理解していれば、そもそもそういう期待は方向性違いであると気付けたり、何らかの改善指針を持てたりする部分があるなぁと感じてまして、本記事では「iBeacon と BLE」にフォーカスして書きたいと思います。


なお、本記事は 「Bluetooth Low Energy Advent Calendar 2014 - Qiita」の8日目の記事となります。

ビーコン = アドバタイズ専用デバイス

iBeaconにおける「ビーコン」というのは、BLEの観点から簡単にいうと、「アドバタイズに特化したペリフェラル」です。*2


通常のBLEペリフェラルバイスの場合は、アドバタイズしてセントラルから見つけてもらい、そのあと接続し、データのやりとりを行うわけですが、ビーコンはそれらの機能をすっ飛ばして自分の存在を知らせる機能(アドバタイズ)だけに特化することで、シンプル、低コスト、低消費電力に振り切っている、というのが最大のポイントです。*3


BLEガジェットは安いものでも5000円以上はする中で、ビーコンモジュールは安いものだと1台200円ほどだったり、寿命が数年間と謳われていたりするのは、このためです。


ちなみに、ビーコン界ではもっともよく知られている(と僕は思っている)、「Estimote」のビーコンはシリコンケースががっちり糊付けされていて、ケースをカッター等で切らないと(つまり破壊しないと)電池交換できないようになっていて、


estimoteが届いたので分解してみた - yumulog より)


もちろんスイッチ等でon/offできるわけでもないので、これが届いた当初は「まじで!?」「回路を見られたくないのかな?」とか思ったのですが、今思えば、

  • シリコンケース糊付け・・・安価な防水効果。設置して放置しておける
  • 電池交換ができない・・・ビーコンなので使い捨てでOK

と上述したiBeaconの思想から考えると、大いに納得がいきます。

アドバタイズ周期・電波強度とバッテリー消費

上述した通り、ビーコンはアドバタイズに(ほぼ)特化したデバイスであり、アドバタイズはざっくり言うと電波を発して自身の存在を知らせる機能なので、バッテリー寿命について「アドバタイズ周期」「電波強度」からシンプルに考えられることになります。*4


アドバタイズ周期を上げれば *5 電波を発する頻度が多くなるのでバッテリー消費は大きくなりますし、電波強度ももちろん強くすればより早くバッテリーを消費します。


逆に、アドバタイズ周期を下げればビーコンの発見されやすさが下がりますし *6、電波強度を下げれば領域観測の範囲が狭まります。


多くのビーコンモジュールはこれら「アドバタイズ周期」「電波強度」を変更できるようになっているので、適用しようとしているサービスに応じてバッテリー消費とのトレードオフを考慮しながら適切に設定することが肝要です。


またビーコンモジュールを販売している各社のページには、(バッテリーが)「約1年持ちます」「2年持ちます」等と書かれている場合がありますが、アドバタイズ周期や電波強度をどのように設定した上での話なのか、に注意する必要があります。

iBeaconのアドバタイズメントパケット

iBeaconのビーコン側の仕様は一般には公開されていない(要iBeaconライセンス取得)のですが、上述の通り要はBLEのペリフェラルなので、容易にそのアドバタイズメントパケットを観測できます。


そのフォーマットに沿ってパケットを構成してアドバタイズを行えば、MacでもAndroidでもBLE113等の開発キットでもiBeaconのビーコンモジュールとしてふるまえますし、そのルールに従ってビーコンのアドバタイズメントパケットを解析すれば、iOSバイス以外からもそのビーコンのUUIDやmajor,minorを取得可能(すなわち、領域観測と同じような挙動を実現可能)です。

アドバタイズメントパケットのフォーマット

BLEのアドバタイズメントパケットの各バイトがどのように構成されているかは、Bluetooth SIG によるドキュメント「Bluetooth Specification」 にある下記の図がわかりやすいです。



ここでは詳細説明を省略しますが、AD Type が `FF` の場合、その AD Structure は "Manufacturer Specific Data" であることを意味し、Manufacturer が自由にその AD Structure の長さと内容を決めることができます


Apple はこの AD Type を利用し、Apple は iBeacon のアドバタイズメントパケットのフォーマットを定義しているわけです。

iBeaconのアドバタイズメントパケットの詳細

iBeacon のアドバタイズメントパケットのうち、iBeacon 特有の部分、すなわち AD Type が `FF` である AD Structure だけ抜き出すと、そのパケットフォーマットは次のようになっています。

1A # AD Structure の長さ(bytes)
FF # AD type
4C 00 # Company identifier code (0x004C は Apple を示す)
02 # Byte 0 of iBeacon advertisement indicator
15 # Byte 1 of iBeacon advertisement indicator
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX # iBeacon の proximity uuid
XX XX # major 
XX XX # minor 
XX # Tx Power

(参考:http://stackoverflow.com/questions/18906988/what-is-the-ibeacon-bluetooth-profile


`XX` とした部分以外のバイト値はiBeaconにおいて固定値です。


Bluetooth Explorer 等のアプリケーションで iBeacon のアドバタイズメントパケットを監視してみると、上記のフォーマットに則っていることが確認できます。


Core Bluetooth に対する iBeacon のアドバンテージ

ここまでで、iBeaconにおける「ビーコン」はBLEにおけるペリフェラルのサブセット仕様である、ということを書いてきました。BLEのペリフェラルになれるあらゆるBLEモジュールは、「ビーコン」になれます。


そして、ビーコン自体がただのアドバタイズだけを行うペリフェラルだとすると、セントラル側であるiOSバイスからは当然 Core Location のビーコン領域観測の機能を使用しなくても、Core Bluetooth を使えば問題なく検出できる、ということになります。むしろ、Core Bluetooth を使用した方が、ペリフェラルのより詳細な情報を得られるというメリットさえあります。


しかし、Core Bluetooth での実装では実現できない、Core Location の領域観測サービスならではのアドバンテージ もあります。

ロック画面表示をトリガとするビーコン検出

ビーコン自体はただのペリフェラルなので、Core Bluetooth で検出できるわけですが、バックグラウンドモードにおける Core Bluetooth のスキャンにはいくつかの制限があり、その一つにスキャン間隔が長くなる、というものがあります。


これが、Core Location の領域観測サービスを使用してビーコン領域を検出する場合、ユーザーがiPhoneのロック画面を表示した瞬間にだけビーコン領域検出 を行ってくれるようになります。


ユーザビリティの観点からも、バッテリー消費の観点からも、非常にメリットの大きい機能です。


参考書籍:

iBeacon ハンドブック
iBeacon ハンドブック
posted with amazlet at 14.12.08
(2014-03-25)
売り上げランキング: 11,647

ロック画面へのアプリアイコン表示

iOS 8 より、あるアプリで観測している領域が検出された場合に、そのアプリのアイコンがロック画面の左下に表示されるようになりました。



この状態でアイコンをドラッグして上方向にスライドすると、そのアプリが起動します。


Core Bluetooth を利用してバックグラウンドでペリフェラルを検出しても、iOSのロック画面に直接の動線を置く等ということはできないので、これもまたiBeaconならではの大きなアドバンテージといえます。

「検出できたりできなかったり」への対処

ビーコンがBLEのアドバタイザに過ぎないということを知っていれば、Core Location の `locationManager:didEnterRegion:` や `locationManager:didRangeBeacons:` でビーコン検出を観測する以外に、いろいろな検証手段の選択肢が増えてきます。


たとえば、iOS の LightBlue や BLExplr でスキャンして検出されるか確認してみたり、そちらでは検出されるようであれば、MacBluetooth Explorer でアドバタイズメントパケットの中身を確認 し、パケットのフォーマットが正しいかを確認したり、等々。


またビーコン本体のアドバタイズ周期が長すぎると検出されにくくなりますし、電波強度が弱く設定されていると電波が届いていない可能性も考えられます。

おわりに

iBeaconという領域観測サービスを実現するために、BLEがどのように用いられているのか、について書きました。


割り切った仕様なのでできないことも多いのは事実ですが、「安いので大量にバラまける」「低消費電力なので小型な電池で長持ちする+構造がシンプルなので簡単に防水にできる+安い = 放置して使い捨てにできる」などなど、iBeaconならではの特長も多くあります。


さらに、アドバタイズや電波のことを理解してサービス設計やチューニングを行えば、つながりやすさやバッテリーの持ちに関しても改善が見込めます。


これらiBeaconの方式や特性をうまく活かし、より有益なiBeaconサービスに繋げていきましょう!


関連記事:


*1:UUID・major・minor等のアドバタイズメントパケットの内容を動的に変更することでiBeaconと双方向通信的なものを実現することは可能ですが、やはり「そもそもBLEのサブセット仕様である」ということを考えるとそうした力技で双方向通信を行うことに意味はないかと。

*2:セントラルがスキャンで発見できるよう、ペリフェラルバイスが「ここにいるよー」と電波を発することを「アドバタイズ」(日本語でいうと広告)と呼びます

*3:そもそもBLEにおけるセントラル・ペリフェラルという概念には、「高度な機能はセントラル側に持たせ、ペリフェラル側のデバイスはシンプル・低コスト・低消費電力に済むように」という思想が込められているのですが、さらにそれをシンプルにしたものがiBeaconです

*4:UUIDの更新やファーム更新等、ビーコンによってはアドバタイズ以外の要因でバッテリーを消費します

*5:BLEの規格ではアドバタイズ周期は最小 20[ms] 〜 最大 10.24[s]の範囲で 0.625[ms]の整数倍、と定められています

*6:たとえば、アドバタイズ周期を10.24sにして、アドバタイズが終わった直後に領域観測側がスキャンを行ったとすると、約10.24sビーコンの発見が遅れることになります