

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 디바이스에서 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 프로토콜을 사용하여 [MQTT 기반 파일 전송 주제](reserved-topics.md#reserved-topics-mqtt-based-file-delivery)을(를) 구독합니다.
+ 요청을 전송한 다음 MQTT 메시지를 사용하여 응답을 받을 때까지 기다립니다.

선택적으로 초기 데이터 세트에 스트림 파일 ID와 스트림 버전을 포함할 수 있습니다. ID를 얻기 위해 디바이스에서 `DescribeStream` 요청을 할 필요가 없기 때문에 스트림 파일 ID를 디바이스에 전송하면 디바이스의 펌웨어/소프트웨어 프로그래밍을 단순화할 수 있습니다. 디바이스는 스트림이 예기치 않게 업데이트된 경우 일관성 검사를 시행하기 위해 `GetStream` 요청에서 스트림 버전을 지정할 수 있습니다.

## DescripbeStream을 사용하여 스트림 데이터 가져오기
<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. 요청이 수락되면 디바이스에 하나 이상의 “수락된” 주제 필터에 대한 `GetStream` 응답을 수신합니다. 각 응답 메시지에는 단일 블록에 대한 기본 정보와 데이터 페이로드가 포함됩니다.

1. 3 및 4단계를 반복하여 모든 데이터 블록을 수신합니다. 요청된 데이터 양이 128KB보다 큰 경우 이러한 단계를 반복해야 합니다. 여러 `GetStream` 요청을 통해 요청된 모든 데이터를 수신하도록 디바이스를 프로그래밍해야 합니다.

1. 요청이 거부되면 디바이스에서 “거부된” 주제 필터에 대한 오류 응답을 수신하게 됩니다.

**참고**  
표시된 주제 및 주제 필터에서 “json”을 “cbor”로 바꾸면 디바이스에서 JSON보다 더 컴팩트한 CBOR 형식으로 메시지를 수신합니다.
AWS IoT MQTT 기반 파일 전송은 블록 크기를 128KB로 제한합니다. 128KB를 초과하는 블록에 대한 요청을 하면 요청이 실패합니다.
총 크기가 128KB보다 큰 여러 블록에 대해 요청할 수 있습니다(예: 총 160KB의 데이터에 대해 각각 32KB의 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\$1255 사이의 정수)입니다.

  스트림 파일 ID는 AWS CLI 또는 SDK를 사용하여 스트림을 생성하거나 업데이트할 때 필요합니다. 디바이스가 존재하지 않는 ID를 가진 스트림 파일을 요청하면 서비스에서 오류 응답과 `ResourceNotFound` 오류 메시지를 전송합니다.
+ “`l`“은(는) 바이트 단위의 데이터 블록 크기(256\$1131,072 사이의 정수)입니다.

  비트맵 필드를 사용하여 `GetStream` 응답에서 반환될 스트림 파일 부분을 지정하는 방법에 대한 지침은 [GetStream 요청을 위한 비트맵 빌드](#mqtt-based-file-delivery-build-a-bitmap)을(를) 참조하세요. 디바이스가 범위를 벗어나는 블록 크기를 지정하는 경우 서비스는 오류 응답과 `BlockSizeOutOfBounds` 오류 메시지를 전송합니다.
+ [선택 사항] ”`o`“은(는) 스트림 파일에 있는 블록의 오프셋(0\$198,304 사이의 정수)입니다.

  비트맵 필드를 사용하여 `GetStream` 응답에서 반환될 스트림 파일 부분을 지정하는 방법에 대한 지침은 [GetStream 요청을 위한 비트맵 빌드](#mqtt-based-file-delivery-build-a-bitmap)을(를) 참조하세요. 최대 값 98,304는 24MB 스트림 파일 크기 제한과 최소 블록 크기의 256바이트를 기준으로 합니다. 지정하지 않은 경우 기본값은 0입니다.
+ [선택 사항] ”`n`“은(는) 요청된 블록 수(0\$198,304 사이의 정수)입니다.

  “n” 필드는 (1) 요청된 블록 수 또는 (2) 비트맵 필드(“b”)가 사용되는 경우 비트맵 요청에 의해 반환될 블록 수에 대한 제한을 지정합니다. 이 두 번째 사용은 선택 사항입니다. 정의되지 않은 경우 기본값은 131,072/*DataBlockSize*입니다.
+ [선택 사항] ”`b`“은(는) 요청되는 블록을 나타내는 비트맵입니다.

  비트맵을 사용하면 디바이스에서 비연속 블록을 요청할 수 있으므로 오류 발생 후 재시도를 보다 편리하게 처리할 수 있습니다. 비트맵 필드를 사용하여 `GetStream` 응답에서 반환될 스트림 파일 부분을 지정하는 방법에 대한 지침은 [GetStream 요청을 위한 비트맵 빌드](#mqtt-based-file-delivery-build-a-bitmap)을(를) 참조하세요. 이 필드의 경우 비트맵을, 16진수 표기법으로 비트맵의 값을 나타내는 문자열로 변환합니다. 비트맵은 12,288바이트 미만이어야 합니다.

**중요**  
"`n`" 또는 "`b`"를 지정해야 합니다. 둘 다 지정하지 않으면 파일 크기가 131,072바이트(128KB) 미만인 경우 `GetStream` 요청이 유효하지 않을 수 있습니다.

### 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이 두 번째 블록이 되는 방식입니다. 파일에서 블록 20, 21, 24 및 43을 요청하려고 합니다.

**블록 오프셋**  
첫 번째 블록이 숫자 20이기 때문에 오프셋(`o` 필드)을 20으로 지정하여 비트맵의 공간을 절약할 수 있습니다.

**블록 수**  
디바이스가 제한된 메모리 리소스로 처리할 수 있는 것보다 많은 블록을 수신하지 않도록 하려면 MQTT 기반 파일 전송에서 전송한 각 메시지에 반환해야 하는 최대 블록 수를 지정할 수 있습니다. 비트맵 자체가 이 블록 수보다 작게 지정하거나 MQTT 기반 파일 전송에서 전송한 응답 메시지의 총 크기가 `GetStream` 요청당 128KB의 서비스 제한보다 크게 되는 경우 이 값은 무시됩니다.

**블록 비트맵**  
비트맵 자체는 16진법으로 표현된 부호 없는 바이트 배열이며 `GetStream` 요청에 숫자의 문자열 표현으로 포함됩니다. 그러나 이 문자열을 구성하기 위해 비트맵을 긴 비트 시퀀스(이진수)로 생각해봅시다. 이 시퀀스의 비트가 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(순서대로), 두 번째 바이트는 15-8비트를 포함하고, 세 번째 바이트는 23-16비트 등을 포함합니다. 16진수 표기법에서는 "0x130080"으로 변환됩니다.  
표준 바이너리를 16진수 표기법으로 변환할 수 있습니다. 한 번에 네 개의 2진수를 가져와서 16진수로 변환하세요. 예를 들어 “0001"은 “1"이 되고 “0011"은 “3"이 됩니다.

![\[GetStream 요청에서 문자열을 구성하기 위한 비트맵 분석을 차단합니다.\]](http://docs.aws.amazon.com/ko_kr/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` 및 `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**  
스트림 요청이 유효한 JSON 문서가 아닙니다.

**InvalidCbor**  
스트림 요청이 유효한 CBOR 문서가 아닙니다.

**InvalidRequest**  
요청은 일반적으로 잘못된 형식으로 식별됩니다. 자세한 내용은 오류 메시지를 참조하세요.

**권한이 없음**  
요청에는 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 기반 파일 전송에서 내부 오류가 발생했습니다.