

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# デバイスで AWS IoT の MQTT ベースのファイル配信の使用
<a name="mqtt-based-file-delivery-in-devices"></a>

データ転送プロセスを開始するには、デバイスは、少なくともストリーミング ID を含む**初期データセット**を受信する必要があります。[AWS IoT ジョブ](iot-jobs.md) を使用して、ジョブドキュメントに初期データセットを含めることで、デバイスのデータ転送タスクをスケジュールできます。デバイスが最初のデータセットを受信すると、 AWS IoT MQTT ベースのファイル配信とのやり取りを開始する必要があります。 AWS IoT MQTT ベースのファイル配信でデータを交換するには、デバイスは以下を行う必要があります。
+ [MQTT ベースのファイル配信のトピック](reserved-topics.md#reserved-topics-mqtt-based-file-delivery) にサブスクライブするには、MQTT プロトコルを使用します。
+ リクエストを送信し、MQTT メッセージを使用して応答を受信するのを待機します。

必要に応じて、ストリーミングファイル ID とストリーミングバージョンを初期データセットに含めることができます。ストリーミングファイル ID をデバイスに送信すると、デバイスからこの ID を取得するための `DescribeStream` リクエストを行う必要がなくなるため、デバイスのファームウェア/ソフトウェアのプログラミングを簡素化できます。ストリーミングが予期せず更新された場合に備えて、デバイスは `GetStream` リクエストでストリーミングバージョンを指定して、整合性チェックを実施できます。

## DescribeStream を使用してストリーミングデータを取得する
<a name="mqtt-based-file-delivery-describe-stream"></a>

AWS IoT MQTT ベースのファイル配信は、ストリームデータをデバイスに送信する `DescribeStream` API を提供します。この API によって返されるストリーミングデータには、ストリーミング ID、ストリーミングバージョン、ストリーミングの説明、およびストリーミングファイルのリストが含まれており、それぞれにファイル ID とファイルサイズ (バイト単位) が含まれています。この情報を使用して、デバイスは任意のファイルを選択してデータ転送プロセスを開始できます。

**注記**  
デバイスが初期データセットで必要なすべてのストリーミングファイル ID を受信する場合、`DescribeStream` API を使用する必要はありません。

`DescribeStream` リクエストを実行するには、以下の手順に従います。

1. 「承諾済み」トピックフィルター を`$aws/things/ThingName/streams/StreamId/description/json`サブスクライブします。

1. 「拒否済み」トピックフィルター `$aws/things/ThingName/streams/StreamId/rejected/json` をサブスクライブします。

1. `$aws/things/ThingName/streams/StreamId/describe/json`にメッセージを送信して、`DescribeStream` リクエストを発行します。

1. リクエストが受け入れられた場合、デバイスは「承諾済み」トピックフィルターで `DescribeStream` 応答を受け取ります。

1. リクエストが拒否された場合、デバイスは「拒否済み」トピックフィルターでエラー応答を受け取ります。

**注記**  
表示されているトピックとトピックフィルターで `json` を `cbor` に置き換えると、デバイスは JSON よりもコンパクトな CBOR 形式でメッセージを受信します。

### DescribeStream リクエスト
<a name="mqtt-based-file-delivery-describe-stream-request"></a>

JSON での典型的な `DescribeStream` リクエストは、次の例のようになります。

```
{
    "c": "ec944cfb-1e3c-49ac-97de-9dc4aaad0039"
}
```
+ (オプション)「`c`」はクライアントトークンフィールドです。

  クライアントトークンは 64 バイトを超えない範囲にします。64 バイトより長いクライアントトークンは、エラー応答と `InvalidRequest` エラーメッセージを引き起こします。

### DescribeStream レスポンス
<a name="mqtt-based-file-delivery-describe-stream-response"></a>

JSON での `DescribeStream` 応答は次の例のようになります。

```
{
    "c": "ec944cfb-1e3c-49ac-97de-9dc4aaad0039",
    "s": 1,
    "d": "This is the description of stream ABC.",
    "r": [
        {
            "f": 0,
            "z": 131072
        },
        {
            "f": 1,
            "z": 51200
        }
    ]
}
```
+ 「`c`」はクライアントトークンフィールドです。`DescribeStream` リクエストで指定された場合、これが返されます。クライアントトークンを使用して、応答をそのリクエストに関連付けます。
+ 「`s`」は整数としてのストリーミングバージョンです。このバージョンを使用して、`GetStream` リクエストの整合性チェックを実行できます。
+ 「`r`」にはストリーミング内のファイルのリストが含まれています。
  + 「`f`」は整数としてのストリーミングファイル ID です。
  + 「`z`」はストリーミングファイルのサイズ (バイト数) です。
+ 「`d`」にはストリーミングの説明が含まれています。

## ストリーミングファイルからデータブロックを取得する
<a name="mqtt-based-file-delivery-get-getstream"></a>

`GetStream` API を使用すると、デバイスが小さなデータブロックでストリーミングファイルを受信できるため、大きなブロックサイズの処理に制約があるデバイスで使用できます。データファイル全体を受信するには、すべてのデータブロックが受信されて処理されるまで、デバイスは複数のリクエストと応答を送受信する必要がある場合があります。

### GetStream リクエスト
<a name="mqtt-based-file-delivery-getstream-request"></a>

`GetStream` リクエストを実行するには、以下の手順に従います。

1. 「承諾済み」トピックフィルター を`$aws/things/ThingName/streams/StreamId/data/json`サブスクライブします。

1. 「拒否済み」トピックフィルター `$aws/things/ThingName/streams/StreamId/rejected/json` をサブスクライブします。

1. トピック `$aws/things/ThingName/streams/StreamId/get/json` に `GetStream` リクエストを発行します。

1. リクエストが承諾された場合、デバイスは「承諾済み」トピックフィルターで 1 つ以上の `GetStream` 応答を受け取ります。各応答メッセージには、1 つのブロックの基本情報とデータペイロードが含まれます。

1. ステップ 3 と 4 を繰り返して、すべてのデータブロックを受信します。リクエストされたデータ量が 128 KB を超える場合は、これらの手順を繰り返す必要があります。リクエストされたすべてのデータを受信するには、複数の `GetStream` リクエストを使用するようにデバイスをプログラムする必要があります。

1. リクエストが拒否された場合、デバイスは「拒否済み」トピックフィルターでエラー応答を受け取ります。

**注記**  
表示されているトピックとトピックフィルターで「json」を「cbor」に置き換えると、デバイスは JSON よりもコンパクトな CBOR 形式でメッセージを受信します。
AWS IoT MQTT ベースのファイル配信は、ブロックのサイズを 128 KB に制限します。128 KB を超えるブロックをリクエストすると、リクエストは失敗します。
合計サイズが 128 KB を超える複数のブロックをリクエストできます (例えば、合計 160 KB のデータに対して、それぞれ 32 KB の 5 つのブロックをリクエストする場合)。この場合、リクエストは失敗しませんが、リクエストされたすべてのデータを受信するには、デバイスが複数のリクエストを行う必要があります。デバイスが追加のリクエストを行うと、サービスは追加のブロックを送信します。以前の応答が正しく受信されて処理された後でのみ、新しいリクエストを続行することをお勧めします。
リクエストされたデータの合計サイズに関係なく、ブロックが受信されなかった場合、または正しく受信されなかった場合に再試行を開始するようにデバイスをプログラムする必要があります。

JSON での典型的な `GetStream` リクエストは、次の例のようになります。

```
{
    "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380",
    "s": 1,
    "f": 0,
    "l": 4096,
    "o": 2,
    "n": 100,
    "b": "..."
}
```
+ [オプション]「`c`」はクライアントトークンフィールドです。

  クライアントトークンは 64 バイトを超えない範囲にします。64 バイトより長いクライアントトークンは、エラー応答と `InvalidRequest` エラーメッセージを引き起こします。
+ [オプション]「`s`」はストリーミングバージョンフィールド (整数) です。

  MQTT ベースのファイル配信では、このリクエストされたバージョンとクラウド内の最新のストリーミングバージョンに基づいて整合性チェックが適用されます。`GetStream` リクエストでデバイスから送信されたストリーミングバージョンがクラウド内の最新のストリーミングバージョンと一致しない場合、サービスはエラー応答と `VersionMismatch` エラーメッセージを送信します。通常、デバイスは、初期データセットまたは `DescribeStream` への応答で、想定される (最新の) ストリーミングバージョンを受け取ります。
+ 「`f`」はストリーミングファイル ID (0～255 の整数) です。

  ストリームファイル ID は、 AWS CLI または SDK を使用してストリームを作成または更新するときに必要です。デバイスが存在しない ID でストリーミングファイルをリクエストする場合、サービスはエラー応答と `ResourceNotFound` エラーメッセージを送信します。
+ 「`l`」はデータブロックサイズ (バイト単位) です (256～131,072 の範囲の整数)。

  ビットマップフィールドを使用して、`GetStream` 応答で返されるストリーミングファイルの部分を指定する方法については、「[GetStream リクエストのビットマップを構築します](#mqtt-based-file-delivery-build-a-bitmap)」を参照してください。デバイスが範囲外のブロックサイズを指定した場合、サービスはエラー応答と `BlockSizeOutOfBounds` エラーメッセージを送信します。
+ [オプション]「`o`」は、ストリーミングファイル内のブロックのオフセット (0～98,304 の範囲の整数) です。

  ビットマップフィールドを使用して、`GetStream` 応答で返されるストリーミングファイルの部分を指定する方法については、「[GetStream リクエストのビットマップを構築します](#mqtt-based-file-delivery-build-a-bitmap)」を参照してください。最大値 98,304 は、24 MB のストリーミングファイルサイズ制限と最小ブロックサイズの 256 バイトに基づいています。指定されなかった場合、デフォルト値は 0 です。
+ [オプション]「`n`」は、リクエストされたブロックの数です (0～98,304 の範囲の整数)。

  「n」フィールドは、(1) リクエストされたブロック数、または (2) ビットマップリクエストによって返されるブロック数の制限 (ビットマップフィールド (「b」) が使用されている場合) のいずれかを指定します。この 2 つ目の使用はオプションです。定義されていない場合、デフォルトで 131072/*DataBlockSize* になります。
+ [オプション]「`b`」は、リクエストされているブロックを表すビットマップです。

  ビットマップを使用すると、デバイスは非連続ブロックをリクエストできるため、エラー後の再試行の処理がより便利になります。ビットマップフィールドを使用して、`GetStream` 応答で返されるストリーミングファイルの部分を指定する方法については、「[GetStream リクエストのビットマップを構築します](#mqtt-based-file-delivery-build-a-bitmap)」を参照してください。このフィールドでは、ビットマップを 16 進表記でビットマップの値を表す文字列に変換します。ビットマップは 12,288 バイト未満である必要があります。

**重要**  
「`n`」か「`b`」のいずれかを指定する必要があります。どちらも指定されていない場合、`GetStream`要求は、ファイルサイズが 131072 バイト (128 KB) 未満の場合は有効ではない可能性があります。

### GetStream レスポンス
<a name="mqtt-based-file-delivery-getstream-response"></a>

リクエストされた各データブロックに対する JSON の `GetStream` 応答は、次の例のようになります。

```
{
    "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380",
    "f": 0,
    "l": 4096,
    "i": 2,
    "p": "..."
}
```
+ 「`c`」はクライアントトークンフィールドです。`GetStream` リクエストで指定された場合、これが返されます。クライアントトークンを使用して、応答をそのリクエストに関連付けます。
+ 「`f`」は現在のデータブロックペイロードが属するストリーミングファイルの ID です。
+ 「`l`」はデータブロックペイロードのサイズ (バイト単位) です。
+ 「`i`」はペイロードに含まれるデータブロックの ID です。データブロックは 0 から番号付けされます。
+ 「`p`」には、データブロックのペイロードが含まれます。このフィールドは、[Base64](https://en.wikipedia.org/wiki/Base64) でエンコードされたデータブロックの値を表す文字列です。

### GetStream リクエストのビットマップを構築します
<a name="mqtt-based-file-delivery-build-a-bitmap"></a>

`GetStream` リクエストでビットマップフィールド (`b`) を使用して、ストリーミングファイルから連続しないブロックを取得できます。これは、RAM 容量が限られているデバイスがネットワーク配信の問題に対処するのに役立ちます。デバイスは、受信されなかったブロックまたは正しく受信されなかったブロックのみをリクエストできます。ビットマップは、ストリーミングファイルのどのブロックが返されるかを決定します。ビットマップで 1 に設定されているビットごとに、ストリーミングファイルの対応するブロックが返されます。

`GetStream`リクエストでビットマップとそのサポートフィールドを指定する方法の例を次に示します。例えば、ストリーミングファイルを 256 バイト (ブロックサイズ) のチャンクで受信するとします。256 バイトの各ブロックには、ファイル内の位置を指定する番号が付いていると考えてください。この番号は 0 から始まります。したがって、ブロック 0 はファイル内の 256 バイトの最初のブロックであり、ブロック 1 は 2 番目のブロックであり、以下同様です。ファイルからブロック 20、21、24、および 43 をリクエストします。

**ブロックオフセット**  
最初のブロックの番号は 20 であるため、オフセット (フィールド `o`) を 20 に指定して、ビットマップのスペースを節約します。

**ブロックの数**  
デバイスが限られたメモリリソースで処理できる以上のブロックを受信しないようにするために、MQTT ベースのファイル配信によって送信される各メッセージで返されるブロックの最大数を指定できます。ビットマップ自体が指定する値がこのブロック数より少ない場合、または MQTT ベースのファイル配信によって送信される応答メッセージの合計サイズが、`GetStream` リクエストごとのサービス制限である 128 KB よりも大きくなる場合、この値は無視されることに注意してください。

**ブロックビットマップ**  
ビットマップ自体は、16 進数表記で表現された符号なしバイトの配列であり、数値の文字列表現として `GetStream` リクエストに含まれます。しかし、この文字列を構築するために、ビットマップをビットの長いシーケンス (2 進数) と考えることから始めましょう。このシーケンスのビットが 1 に設定されている場合、ストリーミングファイルの対応するブロックがデバイスに返送されます。この例では、ブロック 20、21、24、および 43 を受信する必要があるため、ビットマップでビット 20、21、24、および 43 を設定する必要があります。ブロックオフセットを使用してスペースを節約できるため、各ブロック番号からオフセットを差し引いた後、次の例のようにビット 0、1、4、および 23 を設定します。  

```
 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
```
一度に 1 バイト (8 ビット) を取ると、これは通常、「0b00010011」、「0b00000000」、「0b10000000」のように記述されます。ビット 0 は、最初のバイトの終わりにバイナリ表現で表示され、最後のバイトの最初にビット 23 が表示されます。慣習を知らなければ、これは混乱を招く可能性があります。最初のバイトにはビット 7～0 が (この順序で) 含まれ、2 番目のバイトにはビット 15～8 が含まれ、3 番目のバイトにはビット 23～16 が含まれ、以降同様です。これは 16 進数表記では「0x130080」に変換されます。  
標準のバイナリを 16 進表記に変換できます。一度に 4 桁の 2 進数を取り、それらを同等の 16 進数に変換します。例えば、「0001」は「1」になり、「0011」は「3」になり、以降同様です。

![\[GetStream リクエストで文字列を構築するためのブロックビットマップの内訳。\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/images/blockBitmap.png)

これをすべてまとめると、`GetStream` リクエストの JSON は次のようになります。  

```
{
    "c" : "1",       
    "s" : 1,         
    "l" : 256,       
    "f" : 1,         
    "o" : 20,        
    "n" : 32,       
    "b" : "130080"
}
```
+ 「`c`」はクライアントトークンフィールドです。
+ 「`s`」は想定されるストリームバージョンです。
+ 「`l`」はデータブロックペイロードのサイズ (バイト単位) です。
+ 「`f`」はソースファイルインデックスの ID です。
+ 「`o`」はブロックオフセットです。
+ 「`n`」はブロック数です。
+ 「`b`」はオフセットから始まる欠落している blockId ビットマップです。この値は base64 でエンコードする必要があります。

## AWS IoT MQTT ベースのファイル配信によるエラーの処理
<a name="mqtt-based-file-delivery-errors"></a>

`DescribeStream` API と `GetStream` API の両方のデバイスに送信されるエラー応答には、クライアントトークン、エラーコード、およびエラーメッセージが含まれます。典型的なエラー応答は、次の例のようになります。

```
{
    "o": "BlockSizeOutOfBounds", 
    "m": "The block size is out of bounds", 
    "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380" 
}
```
+ 「`o`」はエラーが発生した理由を示すエラーコードです。詳細については、このセクションの後半にあるエラーコードを参照してください。
+ 「`m`」はエラーの詳細を含むエラーメッセージです。
+ 「`c`」はクライアントトークンフィールドです。`DescribeStream` リクエストで指定されている場合は、これが返される場合があります。クライアントトークンを使用して、応答をそのリクエストに関連付けることができます。

  クライアントトークンフィールドは、常にエラー応答に含まれるわけではありません。リクエストで指定されたクライアントトークンが無効または不正な形式の場合、エラーレスポンスで返されません。

**注記**  
下位互換性のために、エラー応答のフィールドは省略形ではない場合があります。例えば、エラーコードは「code」または「o」フィールドで指定される場合があり、クライアントトークンフィールドは「clientToken」または「c」フィールドで指定される場合があります。上記の省略形を使用することをお勧めします。

**InvalidTopic**  
ストリーミングメッセージの MQTT トピックが無効です。

**InvalidJson**  
Stream リクエストは有効な JSON ドキュメントではありません。

**InvalidCbor**  
Stream リクエストは有効な CBOR ドキュメントではありません。

**InvalidRequest**  
通常、リクエストは形式が不正であると識別されます。詳細については、エラーメッセージを参照してください。

**Unauthorized**  
リクエストは、Amazon S3 などのストレージメディア内のストリーミングデータファイルへのアクセスを許可されていません。詳細については、エラーメッセージを参照してください。

**BlockSizeOutOfBounds**  
ブロックサイズが範囲外です。[AWS IoT Core Service Quotas](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#limits_iot) の「**MQTT ベースのファイル配信**」のセクションを参照してください。

**OffsetOutOfBounds**  
オフセットが範囲外です。[AWS IoT Core Service Quotas](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#limits_iot) の「**MQTT ベースのファイル配信**」のセクションを参照してください。

**BlockCountLimitExceeded**  
リクエストブロックの数が範囲外です。[AWS IoT Core Service Quotas](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#limits_iot) の「**MQTT ベースのファイル配信**」のセクションを参照してください。

**BlockBitmapLimitExceeded**  
リクエストビットマップのサイズが範囲外です。[AWS IoT Core Service Quotas](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#limits_iot) の「**MQTT ベースのファイル配信**」のセクションを参照してください。

**ResourceNotFound**  
リクエストされたストリーミング、ファイル、ファイルバージョン、またはブロックが見つかりませんでした。詳細については、エラーメッセージを参照してください。

**VersionMismatch**  
リクエストのストリーミングバージョンが、MQTT ベースのファイル配信機能のストリーミングバージョンと一致しません。これは、ストリーミングバージョンがデバイスによって最初に受信されてから、ストリーミングデータが変更されたことを示します。

**ETagMismatch**  
ストリーミング内の S3 ETag が最新の S3 オブジェクトバージョンの ETag と一致しません。

**InternalError**  
MQTT ベースのファイル配信で内部エラーが発生しました。