Bluetooth Low Energy（BLE）/ iBeaconとは

BLEとiBeaconについて勘違いしていたこともあり、まとめ直してみました。
間違ってたらご指摘いただけるとうれしいです・・・

#BLEとは

- Bluetooth 4.0規格の一部
- BLE、BTLEなどとも呼ばれる
- 特徴
 - 超低電力（ボタン電池1つで数年稼働）
 - 2.4GHz帯を利用して、最大1Mbpsの通信が可能
 - これまでのBluetoothとは互換性がない
 - 通信距離は2.5mから50m
 - 同時接続数に制約はない（従来のBluetoothでは最大7台）
 - 物理的な物、水、人体などによって電波強度に影響がでる

#iBeaconとは

- BLEのブロードキャスト通信を利用したiOSの近接通知機能
- 特徴
 - iOS7から搭載された機能
 - ある範囲に入った/出た、何階にいるか、等を簡単測定できるAPI
 - OSレベルでBLEのブロードキャスト通信を受信し、アプリに通知
 - 単方向のブロードキャスト通信のみで、双方向通信はできない
 - iBeaconの通知によって起動したアプリが端末と接続すれば双方向通信可能


#BLEについて
##BLE端末の役割
###1対1の通信
- BLE機器同士が1対1で接続してデータの送受信を行う
- 暗号化通信可能

![1対1の通信](https://qiita-image-store.s3.amazonaws.com/0/23385/a4758479-7909-b4e4-7926-200564b706c2.png "1対1の通信")

###N対1の通信
- BLE機器が、他の複数のBLE機器に対してブロードキャスト通信を行う
- 暗号化通信不可

![N対1の通信](https://qiita-image-store.s3.amazonaws.com/0/23385/9d8f058a-d639-9333-a3e5-c20a3049d6b4.png "N対1の通信")

##BLEの通信について
- 2400MHzから2483.5MHzまでの周波帯域を2MHz幅40個のチャンネルに分割して利用
- 40個のチャネルのうち、3つをアドバタイズメント・チャネル、残りをデータ・チャネルに割り当てている
 - アドバタイズメント・チャネル：BLEデバイスの発見と接続に利用
 - データ・チャンル：接続後のデータ通信に利用（37のチャンネルを次々に切替ながら通信）
- 40個の物理チャネルは時間単位のイベントに分割される
 - データはイベントに配置されてデバイスに送信される
 - イベントは2種類
  - アドバタイジング・イベント
 - コネクション・イベント
- 周波帯数ホッピングを利用
 - 干渉や混信を避けるための方法
 - 一定時間ごとに、データ通信に使うチャンネルをランダムに切り替える方式
 - 例えば、特定のチャンネルがWi-Fiとぶつかっていて通信出来なくても、一定時間後にチャンネルが切り替わればデータ通信が継続できる

##BLEのブロードキャスト通信のしくみ
- アドバタイジングPHYチャネルでアドバタイジング・パケットを送信するデバイスをadvertiserと呼ぶ
- advertiserに接続せず、アドバタイジング・パケットを受信する機器をscannerと呼ぶ
- アドバタイジングPHYチャネル上のデータ送信はアドバタイジング・イベントで行われる
- アドバタイジング・イベントのはじめに、アドバタイジング・イベント・タイプとしてパケットを送信する
- そのタイプによって、scannerはadvertiserにリクエストを送信する
- そのリクエストは同じアドバタイジングPHYチャネルを利用する
- リクエストに対するadvertiserからの応答も同じチャネル
- 同じアドバタイジング・イベントで、次のアドバタイジング・パケットが送信される際は別のアドバタイジングPHYチャネルが利用される


![BLEのブロードキャスト通信.png](https://qiita-image-store.s3.amazonaws.com/0/23385/3370c37d-1167-296d-4ffa-a628895f10a4.png "BLEのブロードキャスト通信.png")

##BLE端末が接続してにデータ送受信するしくみ
- 他のデバイスと接続しなくてはいけない場合、接続可能なアドバタイジング・パケットを待ち受ける
- このようなデバイスはinitiatorと呼ばれる
- advertiserが接続可能なアドバタイジング・イベントを使っていた場合、initiatorは同じアドバタイジングPHYチャネルを使って接続を要求することができる
- advertiserがinitiatorから接続要求を受け取ると、アドバタイジング・イベントは終了し、コネクション・イベントが始まる
- initiatorはピコネットのマスターとなり、advertiserはスレーブとなる
- コネクション・イベントはマスターとスレーブ間のデータ送信に使われる
- コネクション・イベント内でマスターとスレーブは、同じデータPHYチャネルを使ってデータの送受信を行う
- マスターはコネクション・イベントの開始し、いつでも終了することができる

![BLEの双方向通信の仕組み.png](https://qiita-image-store.s3.amazonaws.com/0/23385/a45426dd-4f53-581f-edd4-2ebf2e0505cf.png "BLEの双方向通信の仕組み.png")

###GATTについて
BLE端末同士が接続してデータの送受信を行う際は、GATTという仕様に基づいてやりとりします。
GATTでは以下のことが決められています。

- データを転送する際の最小単位を「キャラクタリスティクス」と呼ぶ
- 「ディスクリプタ」はキャラクタリスティクスはを構成する属性を定義する
- キャラクタリスティクスが集まって、1つの機能を構成するものを「サービス」と呼ぶ
- 複数のサービスが集まって構成される全体の機能を「プロファイル」と呼ぶ
- プロファイルに基づいてBLE機器同士がデータのやりとりを行う

プロファイルはBluetooth SIGという業界団体が標準を策定していますが、メーカーが独自のプロファイルを申請することも出来るようです。

図：GATTにおけるプロファイルの構造
![BLE.png](https://qiita-image-store.s3.amazonaws.com/0/23385/addee66c-ef4f-d05b-dc07-f3ee5ccdb052.png "BLE.png")

- 参考
 - [GATT Specifications](https://developer.bluetooth.org/gatt/Pages/default.aspx)
 - [GATTサービス一覧](https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx)



###BLEにおける端末の役割と責務の例

- 端末の役割：CentralとPeripheralがある
 - Central：接続を要求する端末（＝スマホ、PCなど）
 - Peripheral：接続を待ち受ける端末（＝BLE機器）
 - なお、 **Android Lより前のバージョンではCentralの端末用のAPIしか提供されていません（LからPeriperalに対応）** 

- GATTサーバとGATTクライアント
 - データを受け渡す方がGATTサーバ
 - データを受け取る方がGATTクライアント


実際の例：
（[Bluetooth Low Energy | Android Developers](http://developer.android.com/guide/topics/connectivity/bluetooth-le.html)より引用）

Androidの端末と、BLEのアクティビティトラッカーがあった場合

- Android端末：Central
- アクティビティトラッカー：Peripheral

端末とアクティビティトラッカーが接続すると、お互いにGATTでデータのやりとりを開始する。
どちらからデータを転送するかで、一方がサーバとなる。

- 端末がアクティビティトラッカーを更新する場合は、端末がサーバとなる
- 端末がアクティビティトラッカーからデータを受け取る場合は、端末がクライアントとなる

##状態遷移
- Standby
 - 初期状態
 - 電波の送受信はしない
- Advertising（＝advertiser）
 - アドバタイズメント・チャンネルでのアドバタイズメント・パケット送信
 - 送信したパケットに対するレスポンスによって、何か反応を返すかもしれない
- Scanning（＝scanner）
 - アドバタイズメント・パケットの受信
 - パッシブスキャンとアクティブスキャンがある
  - パッシブスキャン：アドバタイジング・パケットを受信
  - アクティブスキャン：SCAN_REQを送信して、
 - アドバタイジング・パケットに収まらなかった情報を更に取得
- Initiating（＝initiator）
 - 特定のデバイスからのアドバタイズメント・パケット受信
 - 特定のデバイスからと接続するためにレスポンスを返す
- Connection
 - 接続状態
 - InitiatingからConnectionに遷移：マスター
 - AdvertisingからConnectionに遷移：スレーブ
 - 同時にマスターかつスレーブになれる

![BLE状態遷移.png](https://qiita-image-store.s3.amazonaws.com/0/23385/e676c536-f288-cf3b-4b32-acbb5a6db8df.png "BLE状態遷移.png")




#iBeaconについて
- BLEのブロードキャスト通信を利用したiOSの近接通知機能
- iOSがiBeacon技術を利用して端末を検出するには・・・
 - BLE端末がUUID(128ビットのユニークな値)、major(16ビットの符号なし整数)、minor(16ビットの符号なし整数)データをアドバタイズする必要がある
 - iOSで監視するUUIDを指定する必要がある
 - 監視対象のUUIDは最大20
- iOSが、検出されたBLE端末をアプリに通知してくれる機能
 - アプリがバックグラウンドでも検出可能
 - アプリがバックグラウンドでも通知される
  - ただし、iOS7ではユーザにより、Background App Refreshが許可されている必要がある
- BLE端末までのおおよその距離と正確さを通知してくれる
 - おおよその距離
  - Immediate：至近距離（BLE端末を手に持っているくらいの距離）
  - Near：1〜3メートル
  - Far：検出できる
  - Unknown：検出不能
 - 正確さ
  - accuracy（メートル単位の数値）：値が大きくなるほど距離の正確性に欠ける
-Core Locatio  Frameworkを利用して実装する
-iBeaconによる通知を受け取ったあと端末に接続したり、自信がアドバタイジングする場合などはCore Bluetooth Framework を利用して実装する

#iOS/AndroidのBLE比較
##機能比較
||iOS|Android|
|:-----------|:-----------|:-----------|
|Central|iOS7以降|Android4.3以降|
|Peripheral|iOS7以降|Android5.0以降|
|受け取れるアドバタイジング・データ|UUID、major、minor以外は受け取れない（※Bluetooth Core APIを利用すれば取得可能）|端末に依存する（byte配列で受け取ることができる）|
|取得できるBLE端末の情報|UUID、major、minor（※Bluetooth Core APIでは、端末の状態、RSSI、端末名などが取得できる）|端末のMACアドレス、端末名、端末の接続状態（以前に接続したことがある、接続したことがない、接続中）、端末がサポートしている通信仕様（BR/BDR、LE-only、BR/EDR/LE、不明）、UUID配列など|
|距離の検出|信号強度からOSが算出：proximity（Immediate、Near、Far、Unknown）、accuracy（メートル単位の数値）、rssi|rssiから独自に算出する必要がありそう|
|検出できるBLE端末の条件|監視対象のUUIDを発信するBLE端末のみ検出可能（iBeaconによる通知）|なし（フィルタリングは可能）|
|バックグラウンドでの動作|アドバタイジング・データの受信はアプリがバックグランドでもOSから通知される（iOS7ではユーザ許可により通知できない場合もあり）が、送信はフォアグランドのみ|可能|
|接続後のデータ通信|Peripheral端末のGATTプロファイルに基づく|Peripheral端末のGATTプロファイルに基づく|
|その他制約|監視可能なUUIDは最大20件|なし|

#BLE対応のAndroid、iOS端末
AndroidやiOSでBLEが利用出来る端末は、以下の2つの条件を満たしているものになります。

- [条件1]： **案末に搭載されているOSが、アプリからBLEへアクセスするためのAPIを提供している**
 - iOS7以上
 - Android4.3(APIレベル18)以上
- [条件2]： **端末にがBluetooth4.0が搭載されいている端末**
 - iPhone 4S以降
 - 新しいiPad (第3世代)以降
 - Android端末は、各端末メーカーの仕様参照


#参考
- BLE
 - [BLUETOOTH SPECIFICATION Version 4.1](https://www.bluetooth.org/ja-jp/specification/adopted-specifications)
- iBeacon
 - [Getting Started with iBeacon](https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf)
 - [Core Location Framework Reference](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CoreLocation_Framework/index.html)
 - [Region Monitoring and iBeacon](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html#//apple_ref/doc/uid/TP40009497-CH9-SW1)
- iOS Bluetooth API
 - [Bluetooth for Developers](https://developer.apple.com/bluetooth/)
 - [Core Bluetooth Programming Guide](https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html)
 - [Core Bluetooth Framework Reference](https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CoreBluetooth_Framework/index.html)
 - [Region Monitoring and iBeacon](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html#//apple_ref/doc/uid/TP40009497-CH9-SW1)
- Android 
 - [Bluetooth](http://developer.android.com/guide/topics/connectivity/bluetooth.html)
 - [Bluetooth Low Energy](http://developer.android.com/guide/topics/connectivity/bluetooth-le.html)