MQTT上の単一のファイルを含む無線 (OTA) 更新パッケージをダウンロードし、デバイスで更新を実行します。、。/demo/mota_multi_file_demo.cサンプルコードファイルは使用されん。
背景情報
ステップ1: クライアントの初期化
- ヘッダーファイルを追加
…… …… # 「aiot_ota_api.h」を含む # 「aiot_mqtt_download_api.h」を含む …… /* portfiles/aiot_portフォルダに格納されているシステム関連関数のコレクション。 * / extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile; /* TODO: ロギングを無効にする必要がある場合は、次の機能を実装しないでください。 ログエントリを減らす必要がある場合は、コードパラメータに基づいて印刷ロジックを指定できます。 * 例: [1578463098.611][LK-0309] pub: /ota/device/upgrade/a13FN ******/ota_demo * 上記のログエントリのコードは0309 (16進数) です。 codeパラメーターの値の詳細については、core/aiot_state_api.hをご参照ください。 * / /* SDKのログを印刷するためのコールバック。 * / int32_t demo_state_logcb(int32_t code, char * message) { printf("% s" 、メッセージ); 0を返します。}- aiot_ota_init操作を呼び出してOTAを作成
ota_handle = aiot_ota_init(); if (NULL == ota_handle) { goto出口; }
ステップ2: 必要な機能の設定
aiot_ota_setopt操作を呼び出して、次の項目を設定します。
MQTT接続ハンドルに関連付けます。
重要OTA更新固有のパラメーターを設定する前に、デバイス認証情報が指定されていることを確認してください。 詳細については、「例」をご参照ください。
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);パラメーター
例
説明
AIOT_OTAOPT_MQTT_HANDLE
mqtt_handle
MQTT接続を確立する必要があります。 このパラメータは、MQTT接続ハンドルに関連付けるために使用されます。
- OTA更新コマンドを処理するようにコールバックを設定します。
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, user_ota_recv_handler);パラメーター 例 説明 AIOT_OTAOPT_MQTT_HANDLER
user_ota_recv_handler このコールバック関数は、デバイスがIoT PlatformからOTA更新コマンドを受信したときに呼び出されます。
ステップ3: デバイスのバージョン番号を送信する
デバイスがIoT PlatformとのMQTT接続を確立した後、aiot_ota_report_version操作を呼び出して、デバイスのバージョン番号を送信します。 IoT Platformは、バージョン番号に基づいて更新が必要かどうかを判断します。
この例では、送信されたバージョン番号は1.0.0です。 実際のビジネスシナリオでは、デバイス設定からバージョン番号を取得し、バージョン番号を送信するロジックを指定する必要があります。
OTAアップデートを実行する前に、バージョン番号を少なくとも1回送信する必要があります。
cur_version = "1.0.0";
res = aiot_ota_report_version(ota_handle, cur_version);
if (res < STATE_SUCCESS) {
printf("aiot_ota_report_version failed: -0x % 04X\r\n" 、-res);
}ステップ4: 更新コマンドの受信
IoT Platformに更新パッケージを追加して更新タスクを開始すると、IoT Platformは更新コマンドをデバイスに送信します。
詳細については、「アップデートパッケージの追加」をご参照ください。
- デバイスは、aiot_mqtt_recv操作を呼び出してメッセージを受信します。 デバイスがメッセージをOTA更新コマンドとして認識した後、
demo_ota_recv_handlerコールバックが呼び出されます。 - コールバックの処理ロジックを指定します。 コールバックの処理ロジックを指定する場合は、次の項目に注意してください。
IoT Platformは、
/ota/device/upgrade/${ProductKey}/${DeviceName}トピックを使用して、OTA更新コマンドをデバイスに送信します。${ProductKey} および ${DeviceName} の詳細については、「デバイス検証情報の取得」をご参照ください。
- AIOT_OTARECV_FOTAはメッセージタイプを示します。
void user_ota_recv_handler(void * ota_handle, aiot_ota_recv_t * ota_msg, void * userdata) { uint32_t request_size = 10*1024; switch (ota_msg->type) { ケースAIOT_OTARECV_FOTA: { if (NULL == ota_msg->task_desc | | ota_msg->task_desc->protocol_type != AIOT_OTA_PROTOCOL_MQTT) { break; } …… …… } OTA更新コマンドのAlinkデータ形式の詳細については、「OTA更新パッケージに関する情報をデバイスにプッシュする」をご参照ください。
aiot_ota_recv_tはデータ形式を示します。 Link SDKは、受信したメッセージを自動的に解析します。
- サンプルコードに基づいて、コールバックの処理ロジックを指定できます。 詳細については、「ステップ5: アップデートパッケージのダウンロードとOTAアップデートの実行」セクションのステップ1とステップ2をご参照ください。
ステップ5: アップデートパッケージをダウンロードしてOTAアップデートを実行する
デバイスがIoT Platformによってプッシュされた更新コマンドを受信した後、デバイスは更新パッケージを自動的にダウンロードしません。 パッケージをダウンロードするには、Link SDKのAPI操作を呼び出す必要があります。
user_ota_recv_handlerコールバックが呼び出された後、ダウンローダはOTA更新パッケージを受信するためのMQTTリクエストを開始します。
- ダウンローダーを初期化します。 aiot_mqtt_download_init操作を呼び出して、
ダウンロードvoid user_ota_recv_handler(void * ota_handle、aiot_ota_recv_t * ota_msg、void * userdata) を作成します。{ …… …… printf("OTAターゲットファームウェアバージョン: % s、サイズ: % u Bytes\r\n" 、ota_msg->task_desc->version、 ota_msg->task_desc->size_total); void * md_handler = aiot_mqtt_download_init(); …… …… } - パラメーターを設定します。 aiot_mqtt_download_setopt操作を呼び出して、ダウンロードタスクに関連するパラメーターを設定します。
-
aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_TASK_DESC, ota_msg->task_desc); /* ダウンロードできる各データパケットの最大サイズ。 リソースが制限されたデバイスの値を指定できます。 */ aiot_mqtt_download_setopt(md_handler、AIOT_DLOPT_DATA_REQUEST_SIZE、&request_size); /* 各セグメントの開始位置と終了位置のバイトシーケンス番号。 更新パッケージをセグメントごとにダウンロードする場合、または更新パッケージのセグメントをダウンロードする必要がある場合は、これらのパラメーターを指定する必要があります。 * 指定されたセグメント内で更新パッケージをダウンロードした場合、データパケットに巡回冗長検査 (CRC) が実装されます。 SDKは、ダウンロードしたコンテンツのMD5検証を実装しません。 * デフォルトでは、完全なファイルがダウンロードされます。 この場合、データパケットにCRCが実装され、SDKはダウンロードされたコンテンツのMD5検証を実装します。 * 次のサンプルコードを使用する場合、ダウンロードはファイルの10バイト目から開始し、50キロバイトの10バイト目で終了します。 / // uint32_t range_start = 10、range_end = 50*1024 + 10; // aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_RANGE_START, &range_start); // aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_RANGE_END, &range_end); aiot_mqtt_download_setopt(md_handler、AIOT_MDOPT_RECV_HANDLE、user_download_recv_handler); g_dl_handle = md_handler; パラメーター 例 説明 AIOT_MDOPT_TASK_DESC ota_msg->task_desc ダウンロードタスクに関連する基本パラメータ。 AIOT_DLOPT_DATA_REQUEST_SIZE request_size IoT Platformからダウンロードできる各データパケットの最大サイズ。 AIOT_MDOPT_RANGE_START range_start 各セグメントの開始位置と終了位置のバイトシーケンス番号。 更新パッケージをセグメントごとにダウンロードする場合、または更新パッケージのセグメントをダウンロードする必要がある場合は、これらのパラメーターを指定する必要があります。 これらのパラメータを指定しないと、ファイル全体がダウンロードされます。
たとえば、2つのセグメントを使用して1,024バイトの更新パッケージをダウンロードする場合は、パラメーターに次の値を指定します。
最初のセグメント:
AIOT_DLOPT_RANGE_START=0、AIOT_DLOPT_RANGE_END=5112番目のセグメント:
AIOT_DLOPT_RANGE_START=512、AIOT_DLOPT_RANGE_END=1023
AIOT_MDOPT_RANGE_END range_end AIOT_MDOPT_RECV_HANDLE user_download_recv_handler OTA更新パッケージを管理するためのコールバック。 このコールバックは、デバイスがダウンロード要求を開始した後にIoT Platformが更新パッケージを返すときに呼び出されます。
-
- aiot_mqtt_download_process操作を呼び出して、ダウンロードリクエストをIoT Platformに送信します。
while (1) { aiot_mqtt_process(mqtt_handle); aiot_mqtt_recv(mqtt_handle); if(g_dl_handle! =NULL) { int32_t res = aiot_mqtt_download_process(g_dl_handle); …… …… } } - IoT Platformはリクエストを受信し、更新パッケージをデバイスに返します。 デバイスがメッセージを受信すると、
user_download_recv_handlerコールバックが呼び出されます。ダウンロードした更新パッケージをデバイスに保持するには、コールバックのロジックを指定する必要があります。void user_download_recv_handler(void * handle, const aiot_mqtt_download_recv_t * packet, void * userdata) { uint32_t data_buffer_len = 0; /* packet->typeはAIOT_MDRECV_DATA_RESPにのみ設定できます。 */ if (!packet | | AIOT_MDRECV_DATA_RESP != packet->type) { return; } /* ダウンロードしたファイルをデバイスに永続させます。 */ FILE * file = fopen("mota_demo.bin" 、"ab"); fwrite(packet->data.data_resp.data, packet->data.data_resp.data_size, sizeof(int8_t), file); fclose (ファイル); data_buffer_len = packet->data.data_resp.data_size; printf("download % 03d % % done, + % d bytes\r\n", packet->data.data_resp.percent, data_buffer_len); } - 更新パッケージファイルのダウンロード後、aiot_mqtt_download_deinitを呼び出してプログラムを終了します。
while (1) { aiot_mqtt_process(mqtt_handle); aiot_mqtt_recv(mqtt_handle); if(g_dl_handle! =NULL) { int32_t res = aiot_mqtt_download_process(g_dl_handle); if(STATE_MQTT_DOWNLOAD_SUCCESS == res) { /* 更新が成功しました。 デバイスを再起動し、新しいバージョン番号を送信できます。 */ printf("mqttダウンロードota success \r\n"); aiot_mqtt_download_deinit(&g_dl_handle); break; } else if(STATE_MQTT_DOWNLOAD_FAILED_RECVERROR == res | | STATE_MQTT_DOWNLOAD_FAILED_TIMEOUT == res | | STATE_MQTT_DOWNLOAD_FAILED_MISMATCH == res) { printf("mqttダウンロードota failed \r\n"); aiot_mqtt_download_deinit(&g_dl_handle); break; } } }
ステップ6: 更新後にバージョン番号を送信する
バージョン番号を送信するサンプルコードの詳細については、「手順3: デバイスのバージョン番号を送信する」をご参照ください。
デバイスの更新後、最新のバージョン番号を送信する必要があります。 それ以外の場合、IoT PlatformはOTA更新タスクが失敗したと判断します。
デバイスは、更新後に再起動する必要があります。 この場合、デバイスの再起動後に最新のバージョン番号を送信してください。
この例では、更新後に最新のバージョン番号を送信するロジックは指定されていません。 ビジネス要件に基づいてロジックを指定する必要があります。
ステップ7: 接続を終了する
aiot_mqtt_disconnect操作を呼び出して、デバイスをIoT Platformから切断します。
res = aiot_mqtt_disconnect(mqtt_handle);
if (res < STATE_SUCCESS) {
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_disconnect failed: -0x % 04X\n", -res);
return -1;
}ステップ8: プログラムを終了する
aiot_ota_deinit操作を呼び出して、OTAを破棄します。
aiot_ota_deinit(&ota_handle);