BLE (個人的にあとで読み返したい基本)

## 動機

ラズパイやarduinoでBLEを使う機会が増えたので、実装する上で抑えておきたいところをまとめました。

基本的に下記の記事から学習したものを自分があとで振り返る用ですが、何かあればご指摘いただけると幸いです。
https://techweb.rohm.co.jp/product/wireless/bluetooth/175/

## BLEとはそもそも何か

- BLEは、Bluetooth v4（旧Bluetooth SMART、別称Bluetooth low energy）のことを示す  
  - 要はbluetoothの低消費電力版のことを指す  

  - v3までのBluetoothは、音声や音楽など連続データを扱い、乾電池で駆動することが前提。条件によっては、あまり低消費とは言えなかった。対して、Bluetooth v4.0からは、センシングデータ（温度、脈拍など）など少量データの伝送に用途をしぼり、インターバルを含んで非連続で伝送し、コイン電池等での動作が可能になるように低消費化を図ったバージョンとなる  
    - v3との主な変更点としては、「無線仕様をゆるくすることにより、RF回路規模の縮小を行ったこと」、「用途を限定したことによる通信スループットを下げたこと」の２つ。  
      - チャネル数が79→40,最大パケットサイズが1021 octets/s → 27 octets/s  

  - Bluetooth v4.1以降とv3以前には互換性はなし  
    - ただし、使用する帯域に関しては無線LANなどでも利用している2.4GHz（ISM帯）。また、物理層もIEEE802.15.1でv3と同じ  

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

BLEの通信にはセントラルとペリフェラルという機能を持つデバイスが存在する。

![セントラルとペリフェラル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/8c3f3b6c-2a7f-039d-70a5-21140c8f0de2.png)

それぞれの役割を簡単に説明すると、セントラルは親機となり、ペリフェラルが子機となる。要はマスタースレーブ方式のような形での通信が行われており、親機となるセントラルから通信開始
されることが多い。

## BLEの無線方式

- 最小7.5ms(最大4s)のインターバルを持って間欠的に通信を行う(非連続データを対象にしているため)

- デバイス毎にマスターとスレーブの関係がある。各々は、Scanning、Advertising、Standby、Initiateing、Connectionの5つのステータスをもつ
  - 接続を要求する側(アドバタイザ)がAdvertisingステート、接続側(パッシブスキャナ)がScanningステートになり、アドバタイザを見つける。接続が行われると、アドバタイザはスレーブに、パッシブスキャナはマスターとなる。要はスレーブになるデバイスが、自分を発見してもらうための通信(アドバタイズ)を行う

### AFH(Adaptive Frequency Hopping)

- エラーが頻発するチャネルを検出し、使用しないようにホッピング(エラーの頻発しないチャンネルへ移る動作)を行う。無線LANのチャネルが占有している帯域を回避するホッピングパターンを作りだす。

### 通信開始手順

- Bluetoothでは、ペリフェラルとなるデバイスがアドバタイジング（自分のデバイスがbluetoothに対応していることを示す情報を周囲に送ること）を行い、スキャナとなるデバイスがそのアドバタイザを見つけ次第、コネクトリクエストを送り接続する  

![アドバタイジング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/23a8f094-f279-3c41-4801-9969d8b3ac4c.png)


- Bluetooth v4(BLE)以降のアドバタイジングでは、以下の内容のデータが送られる  
  - Local Name＝デバイスの名称
  - Manufacturer Specific Data＝LSIベンダが任意に使用  
  - Tx Power Level＝送信デバイスの設定送信電力  
  - Service UUID＝デバイスの機能  

- コネクトリクエストは以下のデータが送られる。Connection〜のデータはスループットを設定するためのものになる  

  - Transmit Window Offset＝次の送信までの時間
  - Transmit Window Size＝パケット送信サイズ
  - Connection Interval＝通信間隔
  - Connection Slave Latency＝マスターの接続確認に応答しなくても良い回数
  - Connection Supervision Timeout＝接続機器を切断したと判断するまでの秒数(タイムアウトと判断する秒数)  
      - Slave Latencyとはスレーブ側が送りたいデータがなくても実施する必要があるマスターとの接続確認ように通信を間引く動作のこと
          - ex. Connection Slave Latency = 4ならば４回接続確認用の通信を無視できる
      - スレーブはSlave Latencyの応答を無視している間でもデータを受信可能(クイックトランスミッション)

### Bluetooth v4 アドレス

- BD_ADDR, BDアドレスとも呼ばれる。アドレスは48bitで表現される。public addressとrandom addressの２種類が使用可能

#### Public Address

- IEEE802準拠のアドレス。EthernetのMACアドレスと同義。ハードウェアにつけられたアドレスを指す

#### Random Address

- セキュリティを考慮した、各端末で自動生成される端末アドレス。乱数を使用。

- Random Addressには、Static Device Address、Non-Resolvable Private Address、Resolvable Private Addressの3種類が定義ある
  - Resolvable Private Addressはi PHONEで使用されており、各端末で乱数により自動生成されるものの、接続毎にIRKと呼ばれる鍵でアドレスをさらに再生成し、受信した側もIRKによりアドレスの正当性を検証する。(鍵暗号方式?)

### ペアリングとセキュリティ

- ペアリングは接続したデバイス同士の情報を互いに持ち合い、同じ暗号鍵(LTK)を使用し、暗号化を成立させる。つまりペアリングとセキュリティは同一のようなものになる

  - ペアリングをしなくても通信は可能。ただし暗号化されないため、使用しない場合は上位層のアプリケーションで暗号化を行う必要がある

#### ペアリングの暗号化情報の交換

- LE Legacy Pairing
  - 暗号化情報の交換方法の一つ。脆弱性が指摘されているため非推奨
- LE Secure Connections（LESC）
  - Bluetooth4.2で追加された暗号化情報の交換方法。楕円曲線暗号を利用している。こちらが推奨


#### ペアリングの種類

- PassKey(Level2) : 6桁のパスキーを交換(パスワードの照合を行う)しペアリングを行うもの

- Just Work(Level1) : 固定値(000000)をパスキーとしてペアリングを行う。
  - 多くの場合、スレーブ側がパスキーを問う表示をすることになるが、ディスプレイを持たないスレーブも少なくなく、表示ができないために接続ができないという問題がある。そこで、あらかじめ000000をパスキーと決めてペアリングを行う

#### セキュリティ通信設定

- ペアリング(セキュリティ通信開始)時は、以下の２パターンがある
  - スレーブ側(peripheral)がセキュリティ開始要求(Security Request)をマスタに送り、セキュリティ認証を行う  (androidがよく行う手法)
  - マスタ(Central)からのATT(Attribute)ライト要求(ATT_WRITE_REQ)をスレーブが受け、ATT_ERROR_RSPを返す(エラー応答のようなもの)ことによりセキュリティ認証を行う  (iOSでよく行われる手法)

- ペアリング開始後、マスタ(Central)からセキュリティ認証開始request(Paring Request(Authentication))が送られ、その応答(Pairing Response(Authentication))が返される。これを何度か繰り返すことにより、鍵の桁数、暗号化レベルの情報交換が行われる

- その後は、Passkey入力/表示が行われ、STK（短期鍵）生成に必要な情報交換が行われる。その後は、Passkey入力/表示が行われ、STK（短期鍵）生成に必要な情報交換がされる

- STK生成情報の交換ののち、STKを使用した短期暗号化が開始される。
  - まず、スレーブが鍵情報やアドレス情報をマスタに送り、マスタも同様の情報を送ってくる

#### ボンディング(Bonding)

- ペアリングすることとボンディングはほぼ同義(上記のセキュリティ通信が終わった状態のことを指す)。「ボンデッドデバイス：Bonded Device」という表現もよく使われおり、これは、鍵を交換し終えてペアリングが完了した状態の機器をさす

### プロトコル

BLEのハードウェアとソフトウェアの構成は下記の図のようになっている。

![BLE構造.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/11ff62ea-7665-b93a-52e0-0f274f36aea0.png)


ここでは、ホストとプロファイルについて説明する。

#### L2CAP(Logical Link Control and Adaptation Protocol)

- マスタとスレーブ間のデータ伝送に必要な論理的なチャネルを確保するプロトコル。

- Bluetooth Core Specification 4.0のリンクレイヤの伝送は1回27バイトに決まっているが、Attribute ProtocolのMTU（Maximum Transmission Unit）サイズである、最大512バイト以下の長いパケットを扱える。しかし、長いパケットをリンクレイヤが扱える長さに分割して送信する仕様になっており、受信側はそれをまとめなおす作業(defragment)作業を行う

  - ただし、Bluetooth Core Specification 4.2からは、27オクテットから251オクテットに拡張され、パケットを分割せずに送受信することが可能になり、高速な処理が可能になった。

#### Attribute Protocol(ATT)

- Bluetooth® 4.0から追加されたプロトコルで、Client-Serverアーキテクチャを実現するためのプロトコル
  - どちらがサーバか、クライアントかは指定可能。マスタがサーバにもクライアントにもなれるし、スレーブがサーバにもクライアントにもなれる

- サーバとクライアントはそれぞれAttribute（属性）データを持っており、双方の確認のためにその属性のやり取りをするプロトコルがATTプロトコル。データを読み込む動作は一つ上のGATTで行われる

### Attribute

- サーバとクライアントがそれぞれ持っているAttributeは、Handle、Type、Value、Permissionの4つの値で構成される

- Attribute Handle（アトリビュートハンドル）：各属性が持つ連番のインデックス。値の範囲は0x0001から0xffff（2octets）まで。

- Attribute Type（アトリビュートタイプ）： 128ビットのUUID（Universally Unique IDentifier：汎用一意識別子）。その値によってサービス名（Service）や、キャラクタリスティック（Characteristic）と言われるものを示したりする。サービス名の例を以下に示す


| サービス名| UUID  | 
|:----------------|-------------|
| GAP             | 0x1800 | 
| GATT           |  0x1801 |  
| DEVICE INFORMATION  | 0x180A | 
| HEALTH THERMOMETER | 0x1809 | 
| BATTERY SERVICE | 0x180F | 
  
- Attribute Value（アトリビュート値）：属性値で、上位レイヤが利用するデータが入る。サイズは512バイトまで

- Attribute Permission（アトリビュートパーミッション）：読み書きの権限。値の意味はATTではなく上位層（GATT）で決められる。サーバ側が保持しているもので、長さなどは実装で自由に設定可能

  
参考資料：
https://techweb.rohm.co.jp/product/wireless/bluetooth/12131/

### プロファイル

#### GATT(Generic attribute profile)

- GATTはデバイスが公開するデータの種類や使用方法の定義を示すもので、BLE通信のプロファイルは全てGATTを使用して構築されている

- GATTにはBluetooth SIGが公式に提供しているプロファイルと、機器メーカなどの独自提供のものがある
  - Alert Notification（アラート通知）、Blood Pressure（血圧計）、Health Thermometer（体温計）、Heart Rate（心拍数）、Location and Navigation（位置とナビ）が公式プロファイル

  - GATTはクライアント－サーバ方式のアーキテクチャだが、「サービス（Service）」と「キャラクタリスティック（Characteristic）」から構成される。GATTは複数のサービスからなり、サービスは1個以上のキャラクタリスティックを持つ

#### GATTの構造

下記を参照している
https://techweb.rohm.co.jp/product/wireless/bluetooth/3792/

  - 「サービス」「キャラクタリスティック」「ディスクリプタ」の3つのアトリビュートで構成される
    - GATTプロファイルのサービスは1つ以上で構成される
    - サービスは０個以上のキャラクタリスティックで構成される
    - キャラクタリスティックはプロパティ、バリュー、0個以上のディスクリプタで構成される

![サービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/9d9d3f9d-a301-015e-e2fb-5cf77c28330e.png)

  - サービス
    - 機器の機能を示すもの
    - 例えば、体温計のハードウェアの機能が体温の測定と測定完了の通知音の２つなら、サービスは体温測定のサービスと測定完了の通知オンのサービスの2つになる
  
  - キャラクタリスティック
    - 機器の内部状態、動作指示、外部センサ値などを読み書きする。アクセス方法を定義するプロパティとディスクリプタで構成される
    - サービスの時の例で言えば、温度を読み出すキャラクタリスティックと通知のオンオフ指示を書き込むキャラクタリスティックがある

  - ディスクリプタ
    - キャラクタリスティクスのバリューの変数の型や単位などの情報の追加と、そのバリューが変更された時にクライアントへの通知の有無といった動作指示に使う

##### GATTの機能
  - GATTに基づくデータのやり取りのための手順。ATTが提供する様々な操作に基づく
    - 機能(プロシージャ)にはサブプロシージャがあり、
      - クライアントとサーバの設定情報の交換
      - サービスとキャラクタリスティックの検索
      - キャラクタリスティックの読み出し（Read）と書き込み（Write）
      - キャラクタリスティックの通知（Notification）と通告（Indication）

  - 主な機能とサブプロシージャは以下を参照
https://micro.rohm.com/jp/techweb_iot/knowledge/iot02/s-iot02/04-s-iot02/3592


### 参考文献

https://techweb.rohm.co.jp/product/wireless/bluetooth/175/

https://www.musen-connect.co.jp/blog/course/trial-production/ble-beginner-8/