コンテンツにスキップ

Top

BLE(Bluetooth Low Energy)

つくりかけでござるよ

BLEの勉強をしたのでまとめました。

BLEの勉強のみで、いわゆるBluetooth全般の勉強はしておらず、クラシックBluetoothと呼ばれる BR/EDR(Basic Rate/Enhanced Data Rate) についてはわかりません。

この本とネットで勉強しました。

Bluetooth Low Energyをはじめよう 2015/2/25

Bluetooth団体

BluetoothはSIG(Bluetooth Special Interest Group)という団体が規格を定めたりライセンス認証したりしています。
https://www.bluetooth.com/

BR/EDR と BLE

Bluetoothには大きく2つの規格があります。

Version3.0 以前の BR/EDR と Version 4.0 以降の BLE です。

旧来の BR/EDR は クラシックBluetooth や レガシーBluetooth などと呼ばれ、新しいBLEは Bluetooth Smart と呼ばれることもあります(ただし、後者はほとんどの場合BLEと呼ばれています)。

これらは同じ2.4GHz帯をつかうBluetoothであるにも関わらず、互換性はありません。

BLEは元々はフィンランドのNokiaが開発した短距離無線通信技術「Wibree」で、それをBluetooth規格に持ってきたので互換性を保つのは難しかったのだと思います。

※なお、WindowsがBLEを標準サポートするようになったのはWindows8からです(Windows7で使えない、というわけではなく、メーカーがドライバーソフトを添付したりして対応しています)。

BluetoothのVersion

バージョンはざっくりこんな感じです。大事なのは4.0以前と以降で互換性のないレベルで大きく変わったことですね。
(旧来のBluetoothは現在ももちろん使われています。でも、そのうちなくなるんだろうとは思います)

Version 概略
1.0 最初のやーつ
1.1 普及したやーつ。IEEEに登録されたよ!
1.2 無線LANとの干渉対策(周波数ホッピング)の対応を追加
2.0 EDRできたよ
2.1 NFCに対応したり、バッテリー持つようにしたよ
3.0 Hish Speedモードでたよ!でもWiFi Directのほうが使われてるよ!
4.0 BLE爆誕でござる
4.1 直接インターネットにつながるようになったよ!ホストとクライアントの両方に同時になれるようになったよ!
4.2 BLEが速くなったよ!
5.0 BLEがさらに速くなったよ!ついでに遠くまで送れるようになったぞ!
5.1 方向がわかるようになったよ!ごいすー!

個人的には5.1で登場した方向探知機機能に商業的な将来性を感じているところです。

もうすこしちゃんとしたのは以下のwikipediaで確認できます。
Wikipedia:Bluetoothバージョン

もっとちゃんと書け!という人はこのページをそっと閉じて、以下のページに遷移してください。
Bluetooth 公式 Core仕様

Bluetoothのハードウェアの互換性

先ほどから述べているように、クラシックBluetoothとBLEには互換性はありませんが、デバイスは両対応しているものが多いです。

対応しているかどうかはロゴを見ればわかるようになっています。

名称 対象
Bluetooth クラシックBluetoothのみ対応
Bluetooth Smart Ready クラシックBluetoothもBLEもどっちも対応。デュアルモードとも言う
Bluetooth Smart BLEのみ対応。シングルモードとも言う

でもまぁ、実際にUSBドングルとかを購入する際は、このロゴなんかよりバージョンとプロファイル(後述)の確認のが大事ですが。

BLEの接続形態(トポロジー)

BLEは以下の2パターンの接続形態を持ちます。

■ ブロードキャストモード

ブロードキャスター コネクションができない(接続不可属性をつけた)Advertiseパケットをブロードキャストする。大抵の場合データも付けて送信している
オブザーバー コネクションができないAdvertiseパケットがブロードキャストされるのを待ち受けている

■ コネクションモード

セントラル コネクションができる(接続可能属性をつけた)Advertiseパケットを事前に設定された周波数でスキャンし続け、必要に応じてコネクションし、データの相互通信を行う
ペリフェラル コネクションができるAdvertiseパケットを送信し、必要に応じてコネクションする。コネクション後はセントラルのタイミングでデータのやり取りをする

ちなみに、セントラルをマスター、ペリフェラルをスレーブとも言います。
しかしながら最近では、スレーブが奴隷という意味を持っていることから、人種差別問題上好ましくないと使用を取りやめる動きが出ているのでもう使わないほうが良いようです。

また、Version 4.0 のBLEは、1つのセントラルに同時接続できるペリフェラルの数は7台までというクラシックBluetoothと同じ制限がありましたが、version 4.1以降ではその制限はなくなりました。

それだけではなく、1台のデバイスがセントラルとペリフェラルの両方を兼ねることができるようになったり、

ペリフェラルが複数のセントラルと接続することもできるようになりました。

ブロードキャストモードとコネクションモードの使い分けとしては、ブロードキャストモードは一方的に定期的に情報を通知するセンサーやビーコンといったものに適しており、コネクションモードは多くのデータやその仕組みから通信を暗号化できるので、盗聴されない情報のやり取りなどに適しています。

勉強していてわかりにくかったのが、ブロードキャスターもコネクション(のペリフェラル)も、Advertiseパケットをブロードキャストする点です。
アドバタイズパケットは接続しないものだ、という頭だったので、コネクションのできる Advertiseパケットというものの存在が最初理解できず、コネクション時もAdvertiseパケットがブロードキャストされることになんで?戸惑いました。

■ブロードキャストモードのシーケンス

■コネクションモードのシーケンス

また、セントラルとペリフェラルという言い方も混乱しました。
サーバーとクライアントという言い方にしてくれれば・・・と。

しかしこれに関しては完全に間違いでした。

以降に出てきますが、BLEでは、データを提供する側をGATTサーバー、受け取る側をGATTクライアントと表現します。

そして、通常はキーボードやセンサーなどの「ペリフェラル側」がGATTサーバーになるのです。
(絶対というわけではなく、データを提供する側はペリフェラル側であることが多い、ということです)

よって、サーバー、クライアントという概念でセントラル、ペリフェラルを見てしまうと、GATTサーバーとGATTクライアントが逆になってしまい、あとあと混乱してしまいます。

BLEのプロトコル

BLEのプロトコルは以下のようになっています。

BLE通信プログラムを書く上で、公式の仕様書を読まないといけなくなるのは「特定用途用プロファイル」の部分ですね。
他のブロックはライブラリ任せになると思います。

アプリケーション
プロファイル
GAP
ATT/GATT
GATT
SM
L2CAP
HCI
リンク層
物理層 アナログ信号の変調、復調、ディジタル変換とか

SIGによって定義されているプロファイルは結構な数があり、一部を以下に紹介します。

■Profile Specification
https://www.bluetooth.com/specifications/gatt/

プロファイル名 概略
BLP Blood Pressure Profile 血圧計
FMP Find Me Profile デバイスの検索
HOGP HID over GATT Profile キーボードやマウス
HRP Heart Rate Profile 心拍計
HTP Health Thermometer Profile 体温計
WSP Weight Scale Profile 体重計

物理層

よくわからん。というか真面目に読んでない。ハード系エンジニアには必要だろうけど、ソフトのエンジニアにはおそらく必要ない知識。
主にアナログ信号の変調、復調、ディジタル変換とかしてるみたい。

リンク層

よくわからん。アドバタイズパケットを送信したり受信したり、コネクションを開始したり終了したりする処理もここがやっているみたい。

HCI(ホストコントローラーインターフェース)

HCI(ホストコントローラーインターフェース)もよくわからん。

物理層、リンク層からなるホスト層と、L2CAP等からなるコントローラー層をつなぐ役割としか。

ちなみに、オーバーヘッドをなくすため、小さなセンサーとかはHCIを省いている場合もある。

が、AndroidでBluetoothのデバッグをする際にHCIのデータをダンプすることができる。
ので、プロトコル図のHCIの「位置」ぐらいはわかっていたほうが良いかも。

Androidでデバッグする方法は以下。

Android デバッグ [Android 10]Bluetooth HCIスヌープログの取り方 https://qiita.com/KentaHarada/items/42ed619e8f571d1de845

L2CAP

ここもよくわからん。
簡単に言うと上から来たデータをパケットに分割して下に渡したり、逆にしたから来たパケットを組み立てて上に投げたりするような中間管理職。

GAP

デバイスがブロードキャスターやペリフェラルの時はAdvertiseパケットを送信する役目を担います。

デバイスがオブザーバーやセントラルの時はスキャンをしたり接続要求を送信したりする役目を担います。

なお、接続後はGATTに制御を移し、GAPはいったんお休みになります。(接続中にAdvertiseを投げたらいけないので)

ATT(アトリビュートプロトコル)

GATTがエータをやり取りする際のトランスポート層のプロトコル。

GATT

SM(セキュリティマネージャー)

SMP(セキュリティマネージャープロトコル)とも言います。
暗号鍵を生成して交換するプロトコルです。

セキュリティ手順

① ペアリング

一時的な鍵を作成し、通信を暗号化する

② ボンディング(を伴うペアリング)

ペアリングによって暗号化した後で、永続的に用いる暗号鍵を生成し、交換します。この暗号鍵は保存します。

③ 暗号化再確立

保存した暗号鍵を用いて再接続をします。

これら ①、②、③は順番に実行されます、①しかしない、または、①、②しかしない、というケースもあります。

ペアリングの種類

ペアリングには以下のような種類があります。

なお、初期のクラシックBluetooth(Version 2.1以前)は4桁の確認コードを用いるPIN方式しか存在していませんでした。

Just Works 確認しない
Passkey Display 6桁の認証コードを表示(目視で確認)
Passkey Entry 6桁の認証コードを打ち込むことで確認
Out-Of-Band(OOB) NFCなど、Bluetooth 以外の通信を用いて確認

このようにいろんなパターンがあることから、Bluetooth機器の接続時にやや混乱するユーザーが出てくるのかもしれません。

プロファイル

ざっくり言うと、プロファイルは1つ以上のサービスを持っています。

サービスは1つ以上のキャラクタリスティック(特性)を持っています。

プロファイルがどのようなサービスやキャラクタリスティックを持つかは仕様によってきめられています。

例えばですが、HOGPプロファイルの場合は以下の図のようになります。

HOGPプロファイル HID Service Protocol Mode Characteristic Report Characteristic Report Map Characteristic Boot Keyboard Input Report characteristic Boot Keyboard Output Report characteristic HID Information Characteristic HID Control Point Characteristic Battery Service

1
Device Information Service

まだ先の話になりますが、プログラム的には、例えばHID Informationの値が欲しい場合は、HOGPプロファイル情報からからHID サービスを取得し、HID サービスからHID Information Characteristicを取得し、その値を読み書きする、といった流れになります。

サービス

キャラクタリスティック(特性)

GAPとATTとGATTとSMと

Generic Access Profile

Generic

Security Manager

GAP

ATTとGATTとプロファイルとサービスとキャラクタリスティック(特性)と

ペアリングの話

Bluetooth機器と接続するとき、昔は4桁のPINを入力しないといけなかったよな?
今は6桁になってる。
あれ?このキーボードはPIN入力がない!?

など、Bluetoothのペアリングは挙動がいろいろ異なって???となることが多かったかと思います。

4桁のPINはクラシックBluetooth時代のものですね。
BLEからは6桁になっています。
それどころか、PIN不要にもできます。

このあたりのルールについては以下のSMで

ATTとGATTとプロファイルとサービスとキャラクタリスティックの関係をあえて大雑把に関係性をJavaに置き換えてみると、以下の表のようになる。

名称 対象
ATT インターフェースクラス
GATT ATTを実装したクラス
プロファイル GATTクラスを継承したクラス
サービス メンバ関数
キャラクタリスティック メンバ変数

図にするとこんな感じ。

なお、サービスとメンバ関数、キャラクタリスティックをメンバ変数と書いたが、関数名や変数名は?というと、すべて「UUID」で表す。 getなんたら、setなんたらとかじゃなくUUID。
そこの違和感になれたらもう大丈夫。

HOGPプロファイル HID Service Protocol Mode Characteristic Report Characteristic Report Map Characteristic Boot Keyboard Input Report characteristic Boot Keyboard Output Report characteristic HID Information Characteristic HID Control Point Characteristic Battery Service Device Information Service

※HOGP仕様でHID ServiceとBattery ServiceとDevice Information Serviceはマンダトリーになっているので存在しないといけない。(Scan Parameters Service はオプショナル)
※これらのCharacteristic は HIDServiceの仕様書に規定されている

HOGPに対応

プロトコルとプロファイル

プロファイルって結局通信プロトコルってことね!
と思ったが、Bluetoothの世界ではプロトコルとプロファイルは明確に分けている。

プロトコル:下の図みたいなやつのこと

プロファイル:体温計、体重計、GPS、キーボードやマウスといったような機能を実現するための仕様

なので、BLEの世界ではプロファイルのことをプロトコルと言ってはだめ。

汎用プロファイルとプロファイル

汎用プロファイルはGAPとGATTの2つである。これらはBLE機器同士が互いに接続してデータをやり取りするために必要となる情報を規定している。

プロファイルは心拍計や体重計など固有のユースケースの時にデータをやり取るするために必要となる情報を定義している。

要はつながってデータやり取りするまでは汎用プロファイルで。データの中身はなんじゃろな?が、各ユースケースごとのプロファイルで、ということ。

GAPとGATTでつながってデータやり取りするまではできるんで、あとはプロファイル使わんでも自分たちで好き勝手なルールでデータのやり取りできるんじゃね?と気づいたかもしれない。

実はその通りで、全く新しいサービスで、Bluetoothのプロファイルにない場合なんかは、独自でプロファイルをつくってやり取りなんてのもできてしまう。
(旧来のクラシックBluetoothでもSPP(シリアルポートプロファイル)を用いて似たようなことはしていたらしい)

HIDとHOGP

クラシックBluetoothにはデバイスをマウスやキーボードとして利用するためのプロファイル、HID (Human Interface Device Profile)というのが存在していた。

BLEになってもHIDという名前にしてしまうととうぜんわけワカメになってしまうので、BLEではHOGP(HID Over GATT Profile)というふうに名前が変わった。 GATTの中身は当然サービスでなければいけないので、HIDS(Human Interface Device Service)という仕様が生まれた。

・・・わかりにくい。

Wi-Fiは避ける

Bluetoothは2.4GHz帯、すなわち無線LANと同じHz帯を用いている。ので、当然、同時に使うと混線する。
そのため、Bluetooth側が、あれ?この周波数帯にWiFiがいるぞ、と思ったら周波数を変える、周波数ホッピング機能を追加し、混線を避けるようになった。(パワー的にWiFiのほうが圧倒的に強いので、Bluetooth側が避けるようになった)

セントラルとペリフェラル

データのやり取りはRead、Write、Notifyの3つ。
Readはそのまま。セントラルがペリフェラルに対してデータを読む。
Writeも。書き込む。
NotifyはセントラルがペリフェラルにNotify通知するように依頼すると、ペリフェラルが一定間隔で通知し続ける、というもの。
NotifyはクラシックBluetoothにはないBLE特有のコマンド。

以上。

次はプログラミングについてです。