Bluetooth Low Energyのデータパケット
このトピックでは、EchoデバイスとガジェットがBluetooth Low Energy(BLE)経由のデータ交換に使用するパケットの形式について説明します。
Bluetoothに関連するAlexa Gadgets Toolkitの問題については、既知の問題ページを参照してください。
概念
EchoデバイスとガジェットがBLE経由で交換するパケットについて理解するには、ストリームとトランザクションの概念について学んでおく必要があります。
ストリーム
ストリームは、パケットをさまざまな種類に分割する方法です。ガジェットでは、次のストリームをサポートする必要があります。
- 制御ストリーム – Echoデバイスとガジェットはこのストリームによって通信できるようになります。これらのパケットのペイロードは、ガジェットのコンフィギュレーションを管理したり、最初のハンドシェイク時にデバイス情報を交換したりします。
- Alexaストリーム – Echoデバイスとガジェットはこのストリームを使って、すべてのAlexa Gadgets Toolkitインターフェースのディレクティブとイベントを送信します。
- OTA(無線)ストリーム – EchoデバイスとガジェットはOTAアップデートプロセスでこのストリームを使い、ガジェットファームウェアをアップデートします。
どの時点においても、存在するのは1つの制御ストリーム、1つのAlexaストリーム、1つのOTAストリーム(該当する場合)だけです。各パケットはこれらのストリームのいずれかに属します。どのストリームに属するかは、パケットヘッダーのストリームIDフィールドで指定します。ストリームIDにより、受信側(ガジェットまたはEchoデバイス)はパケットのペイロードを解釈できます。
トランザクション
トランザクションは、処理対象データの論理チャンクです。トランザクションは、MTUサイズに応じて、1つまたは複数のデータパケットで構成されます。トランザクションの種類(各パケットヘッダーのオフセット12)により、パケットがトランザクションの最初なのか、最後なのか、中間なのかを指定します。トランザクションIDとストリームIDの組み合わせにより、メッセージを一意に識別できます。
パケットの形式
パケットはバイナリーで、各フィールドはビッグエンディアンで格納されます。各パケットは、ヘッダーとペイロードで構成されます。ヘッダーにはストリームID、トランザクションIDなどが含まれます。ペイロードの形式はストリームの種類(制御ストリームかAlexaストリームか)によって異なります。
確認(ACK)パケット
Echoデバイスがリクエストした場合、ガジェットはトランザクションの最終パケットへの応答として、Echo deviceにACKパケットを送信する必要があります。ACKパケットの全体的な構成はほかのパケットと同じですが、一部のフィールドにはACKパケットの詳細に記載した値をセットする必要があります。
ガジェットがトランザクションでACKが必要かどうかを判断するには、トランザクションの最終パケットのヘッダーで、ACKフラグ(オフセット14)を確認する必要があります。トランザクションの最終パケットかどうかは、パケットのトランザクションの種類(オフセット12)で判断できます。複数パケットの場合は10、単一パケットの場合は00です。
ACKパケットは、確認しているトランザクションと同じストリームIDとトランザクションIDを使用する必要があります。制御ストリーム、Alexaストリームはいずれも、ACKパケットをサポートします。現時点では、EchoデバイスからガジェットにACKパケットを送信するようリクエストすることはできますが、その逆はできません。
ヘッダー
各パケットにはヘッダーがあります。パケットヘッダーのサイズは、次の2つの要因によって変わります。
- トランザクション内でのパケットの位置 – トランザクションの最初のパケットは、ヘッダーに追加の24ビット(予約されたフィールドとトランザクション長のフィールド)を含みます。
- ペイロード長のフィールド拡張 – ヘッダーのペイロード長フィールドは、拡張なし(8ビット)、拡張あり(16ビット)のいずれかになります。1ビットのパケット長拡張フィールドは、ペイロード長が拡張されているかどうかを示します。
以下は、ペイロード長フィールドを拡張しない場合とした場合のヘッダーを図式化したものです。図のとおり、一部のフィールドはトランザクションの最初のパケットにのみ存在します。MTUや総トランザクション長の異なるAlexa.Discovery.Discover
ディレクティブヘッダーの例については、パケットシーケンスの例を参照してください。
ヘッダー(ペイロード長フィールドの拡張なし)

ヘッダー(ペイロード長フィールドの拡張あり)

ヘッダーのフィールドは次のとおりです。
オフセット(ビット) | 長さ(ビット) | 説明 | 値 |
---|---|---|---|
0 | 4 |
ストリームIDです。 |
|
4 | 4 |
トランザクションIDです。 |
1つのストリームIDのトランザクション内では常に一意の数字となります。別のストリームに属するパケットであれば、同時に同じトランザクションIDを使うことができます。 |
8 | 4 |
シーケンス番号です。長さが4ビットのため、任意の時点で最大16パケットのシーケンス指定をサポートできます。 シーケンス番号は戻すことができます。パケットの順序がずれた場合(つまりシーケンス番号の順序がずれた場合)、トランザクションを中断する必要があります。たとえば、16の次が0の場合は正しい順序ですが、16の次が10の場合は順序がずれています。 |
番号は、トランザクションのたびに増えていきます。 |
12 | 2 |
トランザクションの種類です。パケットがトランザクションのどの位置にあるかを示します。単一パケットのトランザクションの種類とプロトコルは、トランザクションの最初のパケットで定義されます。 |
|
14 | 1 |
確認(ACK)フラグです。 |
|
15 | 1 |
パケット長を拡張するかどうかを示します。 |
|
16 | 8 | 予約済みです。トランザクションの最初のパケットにのみ存在します。 |
|
24 | 16 | 総トランザクション長です。トランザクションの最初のパケットにのみ存在します。単一パケットのトランザクションにもこのフィールドはあります。 | トランザクションの長さ(バイト)です。 |
40または16 | 8または16 |
ペイロード長です。ペイロード長はパケットごとに異なります。 |
ペイロードの長さ(バイト)です。 |
ペイロードの種類
各ペイロードは、proto3の構文を使ったプロトコルバッファー形式です。ペイロードの種類は、ストリームの種類によって次の2つのいずれかになります。
制御ストリームのペイロード
制御ストリームによって、Echoデバイスとガジェットの通信が可能になります。各制御ストリームのメッセージは、ペイロードを含むエンベロープで構成されます。
エンベロープ
制御ストリームペイロードのエンベロープ(プロトコルバッファー形式)は、次のようになります。
message ControlEnvelope {
Command command = 1;
oneof payload {
// 応答
Response response = 9;
// メッセージ
// ...
}
}
enum Command {
NONE = 0;
GET_DEVICE_INFORMATION = 20;
GET_DEVICE_FEATURES = 28;
UPDATE_COMPONENT_SEGMENT = 94;
APPLY_FIRMWARE = 95;
}
応答
ガジェットがEchoデバイスからサポート対象の制御ストリームメッセージを受信すると、ガジェットは応答として制御ストリームメッセージを送信する必要があります。応答メッセージのペイロードは、そのメッセージに関連するコマンドによって異なります。ガジェットが理解できない制御ストリームを受信した場合、UNSUPPORTED
の結果コードで応答してください。
message Response {
ErrorCode error_code = 1;
oneof payload {
// 任意のデータ
}
}
enum ErrorCode {
SUCCESS = 0;
UNKNOWN = 1;
UNSUPPORTED = 3;
}
制御ストリーム固有のペイロード
ガジェットとEchoデバイスが交換する制御ストリームパケットは、以下のいずれかのペイロードを持ちます。
メッセージ | コマンドID | 送信元 | 用途 |
---|---|---|---|
20 |
Echoデバイス |
||
20 |
ガジェット |
||
28 |
Echoデバイス |
||
28 |
ガジェット |
||
94 |
Echoデバイス |
||
94 |
ガジェット |
||
95 |
Echoデバイス |
||
95 |
ガジェット |
DeviceInformationコマンド(コマンドID 20)
ハンドシェイク中にデバイス情報をガジェットに照会するには、Echoデバイスがコマンドに20(GET_DEVICE_INFORMATION
)をセットしてガジェットに制御エンベロープを送信します。このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
DeviceInformation応答
ハンドシェイク中にEchoデバイスからデバイス情報を照会されると、ガジェットはデバイス情報を含むペイロードを持つ制御エンベロープのパケットで応答する必要があります。
このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
message DeviceInformation {
string serial_number = 1;
string name = 2;
repeated Transport supported_transports = 3;
string device_type = 4;
}
enum Transport {
BLUETOOTH_LOW_ENERGY = 0;
}
フィールド名 | 説明 | 値 | 必須 |
---|---|---|---|
|
ガジェットに一意のデバイスシリアル番号(DSN)です。 |
検出応答の |
◯ |
|
ガジェットのユーザーフレンドリー名です。この名前はユーザーが変更できます。 |
検出応答の |
◯ |
|
ガジェットがサポートする転送方法のコレクションです。このフィールドにより、Echoデバイスはガジェットとの通信に最適な転送方法を選択できます。 |
サポートされる転送方法のリストです。現在、この値は[ |
◯ |
|
Amazonが割り当てた一意のデバイスタイプです。 |
検出応答の |
◯ |
DeviceFeaturesコマンド(コマンドID 28)
ハンドシェイク中にデバイスの機能をガジェットに照会するには、Echoデバイスがコマンドに28(GET_DEVICE_FEATURES
)をセットしてガジェットに制御エンベロープを送信します。このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
DeviceFeatures応答
Echoデバイスからガジェットのデバイス機能を照会したとき、ガジェットはサポートする機能を記載したパケットで応答する必要があります。このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
message DeviceFeatures {
uint64 features = 1;
uint64 device_attributes = 2;
}
フィールド名 | 説明 | 値 | 必須 |
---|---|---|---|
|
ガジェットがサポートする機能です。 |
|
◯ |
|
予約済みです。 |
|
◯ |
UpdateComponentSegmentコマンド(コマンドID 94)
AlexaサービスがガジェットにOTAアップデートが必要と判断した場合、EchoデバイスはガジェットにUpdateComponentSegment
メッセージを送信します。このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
message UpdateComponentSegment {
string component_name = 1;
uint32 component_offset = 2;
uint32 segment_size = 3;
string segment_signature = 4;
}
フィールド名 | 説明 | 値 | 必須 |
---|---|---|---|
|
コンポーネント名です。 |
文字列です。 |
◯ |
|
コンポーネントのオフセット(バイト)です。 |
|
◯ |
|
ファームウェアイメージのサイズ(バイト)です。 |
ファームウェアイメージのバイト数の値をセットした |
◯ |
|
ファームウェアイメージのSHA-256署名です。 |
ファームウェアイメージ全体のSHA-256ハッシュを表すbase-16エンコードされた文字列です。 |
◯ |
UpdateComponentSegment応答
ファームウェアイメージ全体を受信したら、ガジェットはコマンドIDに94を指定し、ペイロードなしのUpdateComponentSegment
コマンドで応答する必要があります。
ApplyFirmwareコマンド(コマンドID 95)
OTAアップデート中、EchoデバイスはガジェットにApplyFirmware
メッセージを送信し、ガジェットに新しいファームウェアを使うよう指示します。このパケットの例については、Bluetooth Low Energyハンドシェイクのサンプルコードを参照してください。
message ApplyFirmware {
FirmwareInformation firmware_information = 1;
bool restart_required = 2;
}
message FirmwareInformation {
uint32 version = 1;
string name = 2;
repeated FirmwareComponent components = 3;
string locale = 4;
string version_name = 5;
}
message FirmwareComponent {
uint32 version = 1;
string name = 2;
uint32 size = 3;
string signature = 4;
}
フィールド名 | 説明 | 値 | 必須 |
---|---|---|---|
|
新しいファームウェアバージョンや名前などの情報を含むメッセージです。 |
|
◯ |
|
予約済みです。 |
この値は無視してください。 |
◯ |
|
このガジェットにインストールされているファームウェアのバージョンです。 |
新しいファームウェアバージョンを表す |
◯ |
|
Alexaクラウドにアップロードされたファームウェアイメージのバージョンに対応するバージョン文字列です。 |
バージョン文字列が入ります。例: |
◯ |
|
ファームウェアバージョンやコンポーネント名などの情報を含むメッセージです。 |
|
◯ |
|
言語と国を含む文字列です。 |
nullまたは空白を指定できます。 |
◯ |
|
バージョン名です。 |
現時点では、 |
◯ |
|
ファームウェアのバージョンです。 |
現時点では、 |
◯ |
|
コンポーネント名です。 |
文字列です。 |
◯ |
|
ファームウェアイメージのサイズ(バイト)です。 |
ファームウェアイメージサイズを含む |
◯ |
|
予約済みです。 |
この値は無視してください。 |
◯ |
ApplyFirmware応答
ApplyFirmware
コマンドを受信した直後、ガジェットはコマンドIDに95を指定し、ペイロードなしのメッセージで応答する必要があります。
Alexaストリームのペイロード
Alexaストリームのペイロード形式については、Alexa Gadgetのプロトコルバッファー形式を参照してください。
ACKパケットの詳細
トランザクションの最終パケットのヘッダーにACKフラグ(オフセット14)がセットされている場合、ガジェットはACKパケットで応答する必要があります。トランザクションの最終パケットかどうかは、パケットのトランザクションの種類(オフセット12)で判断できます。複数パケットの場合は10、単一パケットの場合は00です。
ACKパケットの全体的なパケット構造はほかのパケットと同じですが、フィールドの値には次のような制限があります。
オフセット(ビット) | 長さ(ビット) | 説明 | 値 |
---|---|---|---|
0 |
4 |
確認をリクエストされたパケットのストリームIDです。 |
以下のいずれかになります。 |
4 | 4 |
確認をリクエストされたパケットのトランザクションIDです。 |
関連するトランザクションIDです。 |
8 | 4 | シーケンス番号です。 | 任意の値を指定できます。 |
12 | 2 |
トランザクションの種類です。 |
|
14 | 1 |
このパケットがACK、NACKのどちらであるかを示します。 |
|
15 | 1 |
パケット長を拡張するかどうかを示します。 |
|
16 | 8 |
予約済みです。 |
|
24 | 8 |
ACKパケット長(バイト)です。 |
|
32 | 8 |
予約済みです。 |
|
40 | 8 |
結果コードです。ACK、NACKのどちらになるかに応じて異なります。 |
|
結果コード
一部のメッセージではペイロードに結果コードが含まれます。結果コードはほとんどの場合応答メッセージで使用されます。特に明記されない限り、ガジェットとEchoデバイスでは、「成功」か「成功でない」結果のみを区別します。通常、具体的なエラーメッセージに機能的な違いはありませんが、結果コードはデバッグに役立つ場合があります。
一部のメッセージでは、「成功」以外のすべての結果コードが切断の理由となります。これらのメッセージに成功応答がなければ、ガジェットのコア機能が保証できないからです。以下のメッセージがエラー応答を受け取った場合、接続は切断されます。
GetDeviceInformation
GetDeviceFeatures
次の表は、メッセージへの応答に使用可能なすべての結果コードの一覧です。
エラー | 16進数の値 | 説明 |
---|---|---|
|
|
メッセージは有効で、正常に処理されました(該当する場合)。 |
|
|
メッセージは有効でしたが、結果は失敗またはエラーになりました。 |
|
|
受信側がサポートしていないコマンドやほかのフィールドが含まれていたため、メッセージは無効です。これは、受信側がサポートしていないすべてのコマンドで使用されます。また、受信側の状態により、メッセージを処理できなかった場合にも使用されます。たとえば、Echoデバイスがインターネットに接続されていない場合、Echoデバイスはエラーコード |
パケットシーケンスの例
以下の図は、MTUや総トランザクション長の異なるAlexa.Discovery.Discover
ディレクティブのパケットシーケンスの例です。ペイロード長の拡張を使用した例も1つ紹介しています。
MTUが小さい場合の例
次の例では、MTUが23バイト、総トランザクション長が35バイトです。

MTUが大きい場合の例
次の例では、MTUが247バイト、総トランザクション長が490バイトです。

パケット長を拡張した場合の例
次の例では、MTUが247バイト、総トランザクション長が490バイトで、最初のパケットでペイロードが16ビットであることを示すペイロード長の拡張を使用しています。
