Advertising Dataとは、BLEデバイスが自身とそのサービスを識別するために広告パケットで送信する構造化データです。Bluetooth Core Specification 5.4(2023)はAD Structureフォーマットを定義しています。各要素には長さ(1バイト)、タイプ(1バイト)、値(最大29バイト)が含まれます。仕様書は30以上のADタイプを説明しています——FlagsやLocal NameからService UUID、Manufacturer Specific Dataまで。advertising dataの適切なパッキングは、iOS、Android、その他のプラットフォームとのデバイス互換性にとって重要であり、検出速度と広告のエネルギー効率も決定します。
重要なポイント
Advertising Dataは、BLEデバイスが自身を識別し、その機能を説明するために広告パケットで送信する、構造化されたフィールドのセットです。Centralは電波をスキャンし、このデータを読み取って、デバイスに接続するか、無視するか、Scan Responseを介して追加情報を要求するかを決定します。
データはTLV(Type-Length-Value)の原則に従って編成されます。各AD要素は3つのフィールドで構成されます。Length(1バイト)はValue + Typeの長さです(つまり、要素の全長からLengthの1バイトを引いたもの)。Type(1バイト)はBluetooth Assigned Numbersからのデータタイプ識別子です。Value(Nバイト)はタイプに応じた内容です。
標準の広告パケットには最大31バイトのADデータを含めることができます。これで不十分な場合は、Scan Response(さらに31バイト)またはExtended Advertising(BLE 5.0、最大251バイト)が使用されます。広告パケットの最初の数バイトはPDUヘッダーとデバイスアドレス用に予約されており、ADペイロードはオフセットから始まります。
各AD要素は広告パケット内でLengthフィールド(1バイト)で始まります。Lengthの値は、Lengthに続くバイト数、つまりType + Valueを示します。たとえば、Length=3の要素は、Lengthの後に1バイトのTypeと2バイトのValueがあることを意味します。すべての要素の長さの合計が広告データサイズに達すると、パケットは終了します。
| フィールド | サイズ | 説明 |
|---|---|---|
| Length | 1バイト | Type + Valueの長さ(Lengthを除く) |
| Type(AD Type) | 1バイト | Bluetooth SIGからのデータタイプ識別子 |
| Value | 0~29バイト | 指定されたタイプのデータ |
Centralパーサーは、ヘッダー後の最初のバイトからAD要素のシーケンスを読み取ります。Length=0の場合、その要素は無視され、パーサーは次のバイトに移動します。重複するADタイプ(1つのパケット内に同じTypeを持つ複数の要素)は許可されていますが、Centralはスタックの実装に応じて最初または最後のみを処理する場合があります。
重要なルール:パケット内のすべてのLength(+1)の合計は、広告データサイズ(advertising PDUの場合は31バイト)を超えてはなりません。データが収まらない場合は、優先順位を設定する必要があります——どのADタイプが初期検出に重要で、どのタイプをScan Responseに移動できるか。
Flags(AD Type 0x01)は、すべてのBLEデバイスの広告パケットにおける必須要素です。3バイトを占有します:Length(0x02)、Type(0x01)、Value(1バイトのビットフラグ)。フラグは検出モードとデバイス機能を定義します。Core Specificationは、すべての広告パケットにFlagsを含めることを推奨しています。
主要なフラグ:LE Limited Discoverable Mode(ビット0)——デバイスが限られた時間のみ検出可能、LE General Discoverable Mode(ビット1)——デバイスが常に検出可能、BR/EDR Not Supported(ビット2)——デバイスがLEのみをサポート、Simultaneous LE and BR/EDR(ビット3)——両方のモードをサポート。純粋なBLEデバイスの場合、LE General Discoverable + BR/EDR Not Supportedの組み合わせが必須です。
Flagsの値が正しくないことは、デバイスがiOSやAndroidで検出されない一般的な原因の1つです。たとえば、BR/EDR Not Supportedフラグが設定されていない場合、iOSはBLEの代わりにクラシックBluetooth経由で接続しようとする可能性があります。Bluetoothアナライザー(nRF Connect、Wireshark)を使用して広告パケットをデバッグする際は、Flagsの値を確認してください。
Local Name(AD Type 0x08または0x09)は、BLEデバイスの表示名です。Type 0x08(Shortened Local Name)は短縮名で、完全な名前が広告パケットに収まらない場合に使用されます。Type 0x09(Complete Local Name)はデバイスの完全な名前です。最大名前長は248バイトですが、標準の広告パケットでは28バイトまでしか利用できません。
デバイス名が広告パケットの利用可能なスペースを超える場合は、短縮名をadvertising PDU(タイプ0x08)に配置し、完全な名前をScan Response(タイプ0x09)に配置することをお勧めします。iOSはスキャン中に広告パケットから名前を表示し、完全な名前は接続後またはScan Response後に利用可能になります。
デバイス名を選択する際は、名前が長すぎると、Service UUIDやその他の重要なデータに使用できるスペースを占有することに注意してください。推奨される名前の長さは8~16文字です。非標準の文字やスペースは避けてください——一部のBLEスタックでは正しく処理されない可能性があります。
Service UUID(AD Type 0x02~0x07)は最も重要なADタイプの1つで、Centralがデバイスに接続せずに、デバイスが提供するサービスを判断できるようにします。Bluetooth SIGはサイズに応じて複数のUUID送信形式を定義しています:0x02(Incomplete 16-bit)、0x03(Complete 16-bit)、0x04(Incomplete 32-bit)、0x05(Complete 32-bit)、0x06(Incomplete 128-bit)、0x07(Complete 128-bit)。
16ビットUUID(2バイト)は標準のBluetooth SIGサービス用です(例:0x180F Battery Service、0x180A Device Information)。128ビットUUID(16バイト)は開発者が定義するカスタムサービス用です。16ビットUUIDはADでわずか4バイト(Length + Type + 2バイトUUID)しか占有しませんが、128ビットUUIDは18バイトを占有します。1つのパケットで複数のカスタムUUIDを送信する必要がある場合、31バイトに収まらない可能性があります。
デバイスのすべてのUUIDを送信するのではなく、フィルタリングに最も重要なものだけを送信する場合は、Incomplete(0x02/0x04/0x06)タイプを使用することをお勧めします。UUIDの完全なリストは、接続後のScan ResponseまたはGATT Discoveryを介して送信されます。これにより、他のADタイプ用の広告パケットのスペースを節約できます。
Manufacturer Specific Data(AD Type 0xFF)は最も柔軟なADタイプで、メーカーのカスタムデータを送信するために設計されています。Valueの最初の2バイトは、Bluetooth SIGによって割り当てられたCompany Identifier Codeです(例:Appleの場合は0x004C、Samsungの場合は0x0075)。残りのバイトは、メーカーが定義した形式の任意のデータです。
AppleはiBeacon用にManufacturer Dataを使用します:Company ID(0x004C)、Beaconタイプ(0x0215)、UUID(16バイト)、Major(2バイト)、Minor(2バイト)、TX Power(1バイト)。GoogleはEddystone用に類似の形式を使用します。IoTデバイスメーカーは、センサーの読み取り値やデバイスの状態をManufacturer Dataに配置することがよくあります。
// Parse Manufacturer Specific Data on Central
function parseManufacturerData(data) {
const view = new DataView(data.buffer);
// Company Identifier Code (first 2 bytes)
const companyId = view.getUint16(0, true);
// Check for Apple iBeacon
if (companyId === 0x004C) {
return parseIBeacon(view);
}
return null;
}
Manufacturer Dataを使用する際は、サイズ制限を守ることが重要です:必須のADタイプを除いた広告パケット全体で31バイト。Apple iBeaconの場合、パケット全体で30バイトを占有し、Flags(3バイト)用のスペースのみが残ります。Eddystoneの場合は最大31バイトです。コンパクトなカスタム形式では、4~8バイトで温度、湿度、気圧を含めることができます。
advertising dataの適切なパッキングは、31バイトの限られたスペースに最大限の有用な情報を配置する技術です。戦略はデバイスの目的によって異なります:ビーコンには識別子が必要で、IoTセンサーには測定値が必要で、フィットネストラッカーには名前とサービスUUIDが必要です。一般的な原則:Centralがより迅速に判断を下す必要があるほど、advertising PDU内のデータはより重要であるべきです。
推奨戦略:advertising PDU(最初の31バイト)——Flags(3バイト)+ 1つの16ビットService UUID(4バイト)+ 短縮名(最大12文字 = 14バイト)+ Manufacturer Data(最大10バイト)。Scan Response(次の31バイト)——完全な名前(残り)+ 追加のService UUID + TX Power Level(3バイト)。この配分により、CentralはUUIDによってデバイスを迅速にフィルタリングできます。
| 優先度 | ADタイプ | サイズ | 配置先 |
|---|---|---|---|
| 1(必須) | Flags(0x01) | 3バイト | Advertising PDU |
| 2(フィルタリング) | Service UUID(0x02~0x03) | 4+バイト | Advertising PDU |
| 3(識別) | Local Name(0x08~0x09) | 2+バイト | Advertising PDU(短縮) |
| 4(追加) | TX Power Level(0x0A) | 3バイト | Scan Response |
| 5(カスタム) | Manufacturer Data(0xFF) | 4+バイト | Advertising PDU / Scan Response |
| 6(完全なデータ) | 残りのUUID | サイズによる | Scan Response |
advertising dataのデバッグは、BLEデバイス開発の必須段階です。パケットの生データを表示するには、nRF Connect(Nordic Semiconductor)またはBluetoothアナライザーを使ったWiresharkを使用してください。すべてのADタイプのLengthが正しいこと、長さの合計が31バイトを超えていないこと、使用シナリオに合わせてFlagsが正しく設定されていることを確認してください。
よくある質問
Bluetooth Controllerスタックは、制限を超えるデータを破棄するか、パケットを送信しません。広告パケットを組み立てる際は、AD要素の全長を確認してください。データが収まらない場合は、一部をScan Responseに移動するか、251バイトの制限があるExtended Advertising(BLE 5.0)を使用してください。
はい、Manufacturer Specific Data(0xFF)を介して可能です。測定値を4~8バイトにパックします:たとえば、温度(固定小数点形式で2バイト)、湿度(2バイト)、バッテリー電圧(2バイト)。このアプローチにより、Centralは接続せずにデータを読み取ることができ、エネルギーを節約できます。
カスタムサービスには、128ビットUUID(AD Type 0x06~0x07)を使用してください。UUIDがadvertising PDU(UUIDあたり16バイト)に収まらない場合は、Scan Responseに移動するか、最初の1つまたは2つのUUIDのみを指定するためにIncomplete短縮形式(0x06)を使用してください。
Complete——パケット内にデバイスのすべてのサービスUUIDがリストされます。Incomplete——UUIDの一部のみ(通常は最も重要なもの)。CentralはIncompleteを完全なリストとして信頼できませんが、迅速なフィルタリングに使用します。完全なリストはGATT Discovery後に利用可能になります。
一般的な原因は、誤ったFlags(0x01)です。BR/EDR Not Supportedビットが設定されていることを確認してください。2番目の原因は、広告パケットにService UUIDがないことです(iOSはUUIDでフィルタリングします)。3番目の原因は、デバイスの広告頻度が低すぎることです(iOSは1000 ms以下の間隔を期待します)。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。