Bluetooth Low Energyのデータ通信プロトコルの基本(★)

 接続処理が完了すると、マスター、スレーブともにデータチャネルに移ります。どちらかがサーバになり、もう一方がクライアントになります。通常は、アドバータイズをしている側(スレーブ側)が、サーバになります。そのサーバに対して、スマートフォンなどのクライアントがアクセスに行くことになります(1つの機器で、サーバの役割、クライアントの役割とも持つことが可能です)。

下記のようなプロトコルスタックになっています。正確にはGAPからLinkLayerにアクセスするケース(スキャン時、接続時)など例外的なパスはありますが、おおよそこの図で説明できます。

なお、上記のプロトコルスタック図は、サーバ側、クライアント側の両方で共通です。
LinkLayerは、LLと略すこともあります。HCIは、Host Control Interfaceの略ですが、昔はこのレイヤでHost CPUとBluetoothデバイスがUART等で接続され制御していたのですが、現在はすべてSingle Chipで処理されていますので、このレイヤはなくなっています。
ATTは、Attribute Protocolの略です。GATTは、Generic Attribute Profileの略です。GAPは、Generic Access Profileの略です。これらの詳しい説明は、以降で行います。LayerとかProfileとかProtocolとかいろいろな名称が使われてますが、通信ですので中身はプロトコル(約束事)です。


属性(Attribute)

 サーバには属性(Attribute)というデータの箱があり、それにクライアント側からアクセスします。この属性のやり取りをするプロトコルをATT(Attribute)プロトコルと呼んでいます。さらに、この属性(Attribute)を複数組み合わせて、GATTデータベースというものを作ります。そのGATTデータベースにアクセスするプロトコルをGATTプロトコルと呼んでいます。

属性(Attribute)は、下記の集まりです。これらはサーバ内部で保存しておく値ですので、どのような形で保存しておいてもかまいません。

  • Attributeハンドル2Byte)
  • Attributeタイプ(2 or 16Byte)
  • Attribute値(0-512Byte)
  • Attributeパーミッション

 Attributeハンドルは、通し番号です。Attributeタイプは、UUIDという識別子で、その値によってサービス名(Service)を示したり、キャラクタリスティック(Characteristic)と言われるものを示したりします。Attribute値は、アプリケーションレイヤが利用するデータが入ります。Attributeパーミッションは、読み書きできるとか、読み込みのみとかの属性です。この属性(Attribute)が、いくつも集まりGATTデータベースとなっています。


ATTプロトコル

属性(Attribute)にアクセスするATTプロトコルで使われるパケットフォーマットです。

Attribute OpCode
(1Byte)

Attribute Parameter
(0- Byte)

Authentication Signature
(0 or 12Byte)

ATTプロトコルでは主に下記の操作ができます。

  • Error Handling
  • Server Configuration
  • Find Information
  • Reading Attributes
  • Writing Attributes
  • Server Initiated

 例えば、Reading Attributesの中のコマンドの1つで、クライアントがサーバのデータを読む場合は、Read Request(Attribute OpCode:0x0A)というのをクライアントからサーバに送り、サーバがRead Response(Attribute OpCode:0x0B)というのを返してきます。

 このATTプロトコルは非常に低レベルのプロトコルなので、温度計の値を読みこむとかの操作はできません。センサーの値を読むときなどは、一つ上のレイヤのGATTプロトコルが必要になります。


GATTデータベース

属性(Attribute)を集めたGATTデータベースですが、イメージがしづらいので、実際のセンサーの値を格納したデータベースで説明します。Bluetooth Low Energy規格では、この辺が非常に理解しずらいです。理解しづらいのは、サービスの宣言までが、1つの属性(Attribute)に割り当てられてしまっているからです。
通信の世界ではなく、MySQL等のデータベースの世界になっています。

 具体的な温度計のGATTデータベースは下記のようになります。1行ずつは、属性(Attribute)になってます。

Handle Type Value Permission
0x0023

0x2800
(=サービス)

0xAA00 Read
0x0024

0x2803
(=キャラクタリスティック)

0x12(プロパティ), 0x0025(データのHandle値), 0xAA01(データのUUID値) Read
0x0025

0xAA01
(=温度計データ)

0x00, 0x00, 0x00, 0x00 (=温度値) Read
0x0026

0x2902
(=Client Config)

0x00, 0x00 Read/Write
0x0027

0x2901
(=ユーザーデータ)

“Temp Data” Read
0x0028

0x2803
(=キャラクタリスティック)

0x0A, 0x0029(データのHandle値), 0xAA02(データのUUID値) Read
0x0029

0xAA02
(=設定用)

0x01 Read/Write
0x002A

0x2901
(=ユーザーデータ)

“Temp Conf” Read

GATTプロトコル

 GATTプロトコルは、GATTデータベースにアクセスするプロトコルです。いくつかのATTプロトコルの組み合わせで実現します。

 よく使われる操作には下記のようなものがあります。

  • Discover Characteristic:クライアントがCharacteristicを探す
  • Read Characteristic Value:クライアントがCharacteristic値を読む
  • Write Characteristic Value:クライアントがCharacteristic値を書く
  • Notify Characteristic Value:サーバがCharacteristic値を通知する