« iPhoneからmbedをBluetooth LE (BTLE)で制御する | トップページ | ブログタイトル変更 »

Bluetooth LE (BTLE)のAdvertisement packet format

btstackのコードを追いかけていると、BTLEペリフェラルがadvertisementを行う際のパケットを規定している配列があります。具体的には、こんなのです:

const uint8_t adv_data[31]="\x02\x01\x05" "\x05\x09mbed" "\x03\x02\xf0\xff";

なんとなく、名前やUUIDを定義していると分かるのですが、この値をいじったときに、iOSのCoreBluetoothでスキャンできなくなるなどの動きになったため、どういう構造になっているのかを知りたいと思っていました。Google先生に聞いてもうまくヒットするコンテンツがなかったのですが、結局本家のBluetooth 4.0 Specificationドキュメントで答えを見つけました。2000ページ以上あるドキュメントなので、目次くらいしかみていませんが、Volume-3 (Core System Package), Part-C (Generic Access Profile), Section-11 “ADVERTISING AND SCAN RESPONSE DATA FORMAT”に必要な情報を見つけました。

小ネタですが、BTLEのadvertisement packet formatということで以下に記載します。


Packet Format

Bluetooth Specificationからの抜粋です。

image

  • Advertisement dataは31byteで構成されます
  • AD Structureと呼ばれる情報要素が31byteのpacketに詰め込まれます
  • 個々のAD Structureは、Length – AD Type – AD Dataで構成されます
  • 未使用部分は0で埋める

AD Type値の意味が分かれば、個々のAD Structureが何をしているのかが分かります


AD Type値の割り当て

AD TypeはAssigned Numberという別のドキュメントで定義しています(デバイス種別の追加などで新規割り当て値が増えていくため、規格文書本体とは分けて管理しているようです)。Assigned Numberを公開しているWebサイトはこちらで、そこから、Generic Access Profileに飛ぶと、目的の情報が出てきます。主な情報を記載すると:

名称
0x01 Flag
0x02 Incomplete List of 16-bit Service UUIDs
(more 16-bit UUIDs available)
0x03 Complete List of 16-bit Service Class UUIDs
0x09 Complete Local Name
0x10 Device ID


Flagは各bitが意味を持っており、以下の定義になっています:

bit位置 意味
0 LE Limited Discoverable Mode
1 LE General Discoverable Mode
2 BR/EDR Not Supported
3 Simultaneous LE and BR/EDR capable (Controller)
4 Simultaneous LE and BR/EDR capable (Host)
5..7 Reserved

btstackでは0x05 = 0101bですので、「LE Limited Discoverable Mode & BR/EDR Not Supported」をadvertiseすることになります。


最終的なAdvertise Data

btstackのケースでは、以下のAD Structureをadvertiseしています(要素と記載した部分は、advertise dataには含まれません):

要素 Length Type Data
AD1 2 1 (flag) 0x05: LE Limited Discoverable & BR/EDR Not Supported
AD2 5 9 (Complete Local Name) mbed
AD3 3 2 (Incomplete List of 16-bit Service UUID) 0xFFF0 (配列上では、上位下位バイトを逆に並べる)

UUIDのType値を2 (Incomplete)としているのは、advertiseでは0xFFF0のみを広報しますが、GATT profileとして0x1800, 0x1801も別途通知できるようにしているためだと思います。


おわりに

AdvertiseにService UUIDを含めないことも出来るのですが、その場合、iOS CoreBluetoothのCBCentralManagerクラスインスタンスに対してscanForPeripheralsWithServices: メッセージを送った際に、引数としてUUIDを指定するとペリフェラルを検出してくれません(nil指定にする必要あり)。UUIDをadvertiseしていなので当たり前ですが、最初はbtstackが何をadvertiseしているのかを分かっていなかっため悩みました。Twitterで呟いたら、ランニングエレクトロニクスさん(@sibu2)にService UUIDを追加するように教えていただいた次第でした。


参考資料

« iPhoneからmbedをBluetooth LE (BTLE)で制御する | トップページ | ブログタイトル変更 »

Bluetooth」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ