All Products
Search
Document Center

IoT Platform:Kode contoh

Last Updated:Jun 17, 2026

Kode contoh ./demos/fota_multi_file_demo.c menunjukkan cara perangkat mengunduh paket pembaruan OTA multi-file melalui HTTPS dan melakukan pembaruan OTA.

Informasi latar belakang

Catatan Hanya C Link SDK yang diunduh setelah 9 September 2021 yang mendukung paket pembaruan OTA multi-file.

Untuk informasi lebih lanjut tentang cara memperoleh SDK, lihat Memperoleh C Link SDK.

Langkah 1: Inisialisasi fitur OTA

  1. Tambahkan file header.
    ……
    ……
    #include "aiot_ota_api.h"
    ……

  2. Konfigurasikan dependensi dasar dan output log.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Panggil aiot_ota_init untuk membuat instans OTA.
        ota_handle = aiot_ota_init();
        if (NULL == ota_handle) {
            printf("aiot_ota_init failed\r\n");
            aiot_mqtt_deinit(&mqtt_handle);
            return -2;
        }

Langkah 2: Konfigurasi fitur OTA

Panggil aiot_ota_setopt untuk mengonfigurasi opsi-opsi berikut.

  1. Asosiasikan handle koneksi MQTT.
    Penting Sebelum mengonfigurasi parameter OTA, Anda harus mengonfigurasi parameter seperti kredensial perangkat. Untuk informasi lebih lanjut, lihat Konfigurasi parameter koneksi untuk MQTT.
    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);
    • Item konfigurasiContohDeskripsi
      AIOT_OTAOPT_MQTT_HANDLEmqtt_handlePermintaan fitur OTA didasarkan pada koneksi MQTT. Item konfigurasi ini mengasosiasikan handle koneksi MQTT.

  2. Konfigurasikan callback untuk pesan instruksi pembaruan OTA.
    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler);
    • Item konfigurasiContohDeskripsi
      AIOT_OTAOPT_MQTT_HANDLERdemo_ota_recv_handlerSaat perangkat menerima instruksi pembaruan OTA dari IoT Platform, fungsi callback ini dipanggil.

Langkah 3: Laporkan versi perangkat saat ini

Setelah perangkat menjalin koneksi MQTT, panggil aiot_ota_report_version untuk melaporkan nomor versi saat ini dari perangkat. IoT Platform menentukan apakah pembaruan diperlukan berdasarkan nomor versi tersebut.

Dalam kode contoh berikut, nomor versi yang dilaporkan oleh perangkat sebelum pembaruan OTA adalah 1.0.0. Dalam aplikasi Anda, Anda harus memperoleh nomor versi aktual dari area konfigurasi perangkat dan memodifikasi kode sesuai kebutuhan.

Penting

Perangkat harus melaporkan nomor versinya setidaknya satu kali sebelum pembaruan OTA.

    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);
    }

Langkah 4: Menerima instruksi pembaruan

  1. Setelah Anda menambahkan paket pembaruan dan memulai tugas pembaruan di Konsol IoT Platform, IoT Platform mengirim instruksi pembaruan ke perangkat.
    Untuk informasi lebih lanjut, lihat Menambahkan paket pembaruan.
  2. Perangkat memanggil aiot_mqtt_recv untuk menerima pesan. Saat sebuah pesan diidentifikasi sebagai instruksi pembaruan OTA, fungsi callback demo_ota_recv_handler dipanggil.
  3. Tulis logika pemrosesan untuk fungsi callback.
    Anda dapat menggunakan informasi berikut untuk menulis logika pemrosesan fungsi callback:
    • IoT Platform mengirim instruksi paket pembaruan OTA ke perangkat melalui topik /ota/device/upgrade/${ProductKey}/${DeviceName}.

      Untuk informasi lebih lanjut tentang ${ProductKey} dan ${DeviceName}, lihat Memperoleh kredensial perangkat.

    • Tipe instruksi pembaruan OTA adalah AIOT_OTARECV_FOTA.
      void demo_ota_recv_handler(void *ota_handle, aiot_ota_recv_t *ota_msg, void *userdata)
      {
          switch (ota_msg->type) {
              case AIOT_OTARECV_FOTA: {
                  uint32_t res = 0;
                  uint16_t port = 443;
                  uint32_t max_buffer_len = (8 * 1024);
                  aiot_sysdep_network_cred_t cred;
                  void *dl_handle = NULL;
                  multi_download_status_t *download_status = NULL;
      
                  if (NULL == ota_msg->task_desc) {
                      break;
                  }
           ……
           ……
      
      }
    • Tipe struktur data untuk pesan instruksi pembaruan OTA adalah aiot_ota_recv_t. Link SDK secara otomatis mengurai pesan instruksi pembaruan yang diterima.
    • Anda dapat merujuk pada kode contoh untuk menulis logika pemrosesan fungsi callback. Untuk informasi lebih lanjut, lihat Langkah 5: Mengunduh paket pembaruan dan melakukan pembaruan OTA.



Langkah 5: Mengunduh paket pembaruan dan melakukan pembaruan OTA

Penting Perangkat tidak secara otomatis mengunduh paket pembaruan setelah menerima pesan paket pembaruan dari IoT Platform. Anda harus memanggil API Link SDK untuk memulai pengunduhan.

Saat fungsi demo_ota_recv_handler dipicu, downloader memulai permintaan unduh melalui HTTPS untuk mengunduh paket pembaruan dan melakukan pembaruan OTA.

  1. Inisialisasi downloader.
    Panggil aiot_download_init untuk membuat download
    Catatan

    Pembaruan OTA mendukung paket pembaruan multi-file. Untuk informasi lebih lanjut, lihat Menambahkan paket pembaruan.

    dl_handle = aiot_download_init();
                if (NULL == dl_handle) {
                    break;
                }
    
                if (NULL != ota_msg->task_desc->file_name) {
                    printf("\r\nTotal file number is %d, current file id is %d, with file_name %s\r\n", ota_msg->task_desc->file_num,
                           ota_msg->task_desc->file_id, ota_msg->task_desc->file_name);
                }
    
                printf("OTA target firmware version: %s,  size: %u Bytes \r\n", ota_msg->task_desc->version,
                       ota_msg->task_desc->size_total);
    
    
                if (NULL != ota_msg->task_desc->extra_data) {
                    printf("extra data: %s\r\n", ota_msg->task_desc->extra_data);
                }
    
                memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
                cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;
                cred.max_tls_fragment = 16384;
                cred.x509_server_cert = ali_ca_cert;
                cred.x509_server_cert_len = strlen(ali_ca_cert);



  2. Konfigurasi parameter unduh.
    Panggil aiot_download_setopt untuk mengonfigurasi parameter untuk tugas unduh.
    Catatan

    Pembaruan OTA mendukung paket pembaruan multi-file. Saat Anda mengunduh paket, Anda harus membedakan ID, jumlah, dan progres unduh setiap file.

                /* Set the download protocol to TLS. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_CRED, (void *)(&cred));
                /* Set the server port for the download. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_PORT, (void *)(&port));
                /* Set the download task information. This is obtained from the task_desc member of the ota_msg input parameter. It includes the download URL, firmware size, firmware signature, and more. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_TASK_DESC, (void *)(ota_msg->task_desc));
                /* Set the callback function that the SDK calls when the downloaded content arrives. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_RECV_HANDLER, (void *)(demo_download_recv_handler));
                /* Set the maximum cache length for a single download. The user is notified each time this memory buffer is full. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_BODY_BUFFER_MAX_LEN, (void *)(&max_buffer_len));
                /* Set the data to be shared between different calls of AIOT_DLOPT_RECV_HANDLER. For example, the sample stores the progress here. */
                last_percent = malloc(sizeof(uint32_t));
                if (NULL == last_percent) {
                    aiot_download_deinit(&dl_handle);
                    break;
                }
                memset(download_status, 0, sizeof(multi_download_status_t));
                download_status->file_id = ota_msg->task_desc->file_id;
                download_status->file_num = ota_msg->task_desc->file_num;
                aiot_download_setopt(dl_handle, AIOT_DLOPT_USERDATA, (void *)download_status);
    
                /* If this is the first download task, report a progress of 0. */
                if (0 == ota_msg->task_desc->file_id) {
                    aiot_download_report_progress(dl_handle, 0);
                }
                            



  3. Memulai permintaan unduh.
    1. Mulai thread unduh demo_ota_download_thread.
                  res = pthread_create(&g_download_thread, NULL, demo_ota_download_thread, dl_handle);
                  if (res != 0) {
                      printf("pthread_create demo_ota_download_thread failed: %d\r\n", res);
                      aiot_download_deinit(&dl_handle);
                      free(download_status);
                  } else {
                      /* The download thread is set to the detach type. It can exit on its own after the firmware content is obtained. */
                      pthread_detach(g_download_thread);
                  }



    2. Di dalam thread unduh demo_ota_download_thread, panggil aiot_download_send_request untuk mengirim permintaan HTTPS GET ke server penyimpanan paket pembaruan yang ditentukan.
      • void *demo_ota_download_thread(void *dl_handle)
        {
            int32_t     ret = 0;
        
            printf("\r\nstarting download thread in 2 seconds ......\r\n");
            sleep(2);
        
            /* Request to download from the update package storage server. */
            /*
             * TODO: The following code uses one request to get the entire firmware content.
             *       For devices with limited resources or poor network conditions, you can also download in segments. To do this, combine the following statements:
             *
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_START, ...);
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_END, ...);
             *       aiot_download_send_request(dl_handle);
             *
             *       In this case, you need to place the combined statements in a loop and call send_request and recv multiple times.
             *
             */
        
             ……
             ……
        
        }
      • Anda dapat mengunduh paket pembaruan secara bertahap menggunakan AIOT_DLOPT_RANGE_START dan AIOT_DLOPT_RANGE_END.

        Sebagai contoh, untuk mengunduh paket pembaruan berukuran 1024 byte dalam dua bagian, Anda dapat mengatur parameter sebagai berikut:
        • Bagian pertama: AIOT_DLOPT_RANGE_START=0, AIOT_DLOPT_RANGE_END=511
        • Bagian kedua: AIOT_DLOPT_RANGE_START=512, AIOT_DLOPT_RANGE_END=1023



  4. Menerima paket pembaruan.
    1. Setelah permintaan unduh dikirim, panggil aiot_download_recv di dalam thread unduh demo_ota_download_thread untuk menerima data paket pembaruan. Data yang diterima memicu fungsi callback demo_download_recv_handler. Di dalam fungsi callback, Anda harus menyimpan paket pembaruan yang telah diunduh ke penyimpanan lokal atau sistem file perangkat.
      void *demo_ota_download_thread(void *dl_handle)
      {
           ……
           ……
      
         aiot_download_send_request(dl_handle);
          // while (1) {
          while (should_stop == 0) {
              /* Receive the firmware content from the server over the network. */
              ret = aiot_download_recv(dl_handle);
      
              /* When the entire firmware is downloaded, the return value of aiot_download_recv() is STATE_DOWNLOAD_FINISHED. Otherwise, it is the number of bytes obtained in the current call. */
              if (STATE_DOWNLOAD_FINISHED == ret) {
                  printf("download completed\r\n");
                  break;
              }
              if (STATE_DOWNLOAD_RENEWAL_REQUEST_SENT == ret) {
                  printf("download renewal request has been sent successfully\r\n");
                  continue;
              }
              if (ret <= STATE_SUCCESS) {
                  printf("download failed, error code is %d, try to send renewal request\r\n", ret);
                  continue;
              }
          }
           ……
           ……
      }



    2. Definisikan fungsi callback demo_download_recv_handler untuk menyertakan logika penyimpanan dan pembaruan paket setelah unduhan selesai.
      Catatan Kode contoh hanya mencetak informasi dan tidak menyertakan logika untuk menyimpan serta membakar paket pembaruan. Anda harus menulis kode untuk menyimpan paket pembaruan berdasarkan lingkungan Anda, lalu membakar firmware untuk menyelesaikan pembaruan OTA.
      • Jika pembaruan OTA menggunakan paket satu file, Anda dapat membakar file tersebut ke lokasi penyimpanan lokal tertentu.
      • Jika pembaruan OTA menggunakan paket multi-file, setiap file dapat sesuai dengan alamat penyimpanan yang berbeda. Anda harus mengidentifikasi bidang file_name dari setiap firmware.
      void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
      {
          uint32_t data_buffer_len = 0;
          int32_t last_percent = 0;
          int32_t  percent = 0;
          multi_download_status_t *download_status = (multi_download_status_t *)userdata;
      
          /* Currently, only the case where packet->type is AIOT_DLRECV_HTTPBODY is supported. */
          if (!packet || AIOT_DLRECV_HTTPBODY != packet->type) {
              return;
          }
          percent = packet->data.percent;
      
          /* userdata can store data that needs to be shared between different entries into demo_download_recv_handler(). */
          /* Here, it is used to store the firmware download percentage from the last time this callback function was entered. */
          if (userdata) {
              last_percent = (download_status->last_percent);
          }
      
          data_buffer_len = packet->data.len;
      
          /* If percent is negative, a packet reception exception or a digest verification error occurred. */
          if (percent < 0) {
              printf("exception: percent = %d\r\n", percent);
              if (userdata) {
                  free(userdata);
              }
              return;
          }
           ……
           ……
      
      }



  5. Laporkan progres unduhan.

    Di dalam fungsi callback demo_download_recv_handler, panggil aiot_download_report_progress untuk melaporkan progres unduhan dan pengecualian apa pun yang terjadi selama proses pembaruan, seperti kegagalan pembakaran atau pemutusan jaringan, ke IoT Platform.

    • Lihat progres yang dilaporkan:

      Progres ditampilkan di Konsol IoT Platform. Untuk informasi lebih lanjut, lihat Melihat status pembaruan.

    • Melaporkan progres untuk unduhan normal dan abnormal:
      • Jika unduhan normal, progres unduhan dilaporkan ke IoT Platform sebagai persentase bilangan bulat. Link SDK secara otomatis menghitung nilai parameter percent dan melaporkannya ke IoT Platform.
      • Jika unduhan abnormal atau terjadi pengecualian pembakaran firmware setelah unduhan, Anda harus melaporkan pengecualian tersebut ke IoT Platform. Untuk daftar kode kesalahan protokol antara perangkat dan IoT Platform, lihat aiot_ota_protocol_errcode_t.
    • Metode pelaporan progres:
      • Jika pembaruan OTA menggunakan paket satu file, progres yang dilaporkan adalah progres total.
      • Jika pembaruan OTA menggunakan paket multi-file, jangan laporkan progres unduhan file individual karena hal ini dapat menimbulkan kebingungan. Saat melaporkan progres, kami menyarankan agar Anda menghitung persentase menggunakan ukuran total file sebagai penyebut dan jumlah total byte yang diunduh untuk semua file sebagai pembilang. Kemudian, Anda dapat melaporkan progres unduhan yang dihitung.
        Anda dapat mengembangkan skenario pelaporan progres paket pembaruan berdasarkan kebutuhan bisnis Anda. Sebagai contoh:
        • Laporkan 0% saat unduhan dimulai. Lalu, laporkan progres hanya ketika progres unduhan total mencapai kelipatan bilangan bulat 10%, hingga 100%.
        • Untuk menyederhanakan pelaporan progres, Anda dapat melaporkan 0% saat unduhan dimulai dan 100% setelah selesai. Artinya, Anda hanya melaporkan progres dua kali.
    void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
    {
         ……
         ……
    
        /*
         * TODO: When a segment of firmware is successfully downloaded, the user should save the memory
         *       starting at packet->data.buffer with a length of packet->data.len to a local storage location.
         *
         *       If the burning fails, you should also call aiot_download_report_progress(handle, -4) to report the failure to IoT Platform.
         *       Note: The error codes agreed upon with the cloud platform in the protocol are in the aiot_ota_protocol_errcode_t type. For example:
         *           -1: indicates an update failure.
         *           -2: indicates a download failure.
         *           -3: indicates a verification failure.
         *           -4: indicates a burning failure.
         *
         */
    
        /* When the value of the percent input parameter is 100, it means the SDK has finished downloading the entire firmware content. */
        if (percent == 100) {
            g_finished_task_num++;
            /*
             * TODO: At this point, all firmware burning should be complete. Save the current work, restart the device, and start with the new firmware.
                     The new firmware must report the new version number to IoT Platform using the following code. For example, if updating from 1.0.0 to 1.1.0, the value of new_version is 1.1.0.
                     aiot_ota_report_version(ota_handle, new_version);
                     IoT Platform considers the update successful only after receiving the new version number. Otherwise, the update is considered failed.
                     If the update fails after a successful download, you should also call aiot_download_report_progress(handle, -1) to report the failure type.
             */
        }
    
        /* Simplified output. The progress is printed and reported to the server only when the download progress has increased by 5% or more since the last report. */
        if (percent - last_percent >= 5 || percent == 100) {
            if (NULL != download_status) {
                printf("file_id %d, download %03d%% done, +%d bytes\r\n", download_status->file_id, percent, data_buffer_len);
                download_status->last_percent = percent;
                if (g_finished_task_num == download_status->file_num) {
                    /* Considering concurrent downloads by multiple threads, report 100% progress only after all files are downloaded. */
                    aiot_download_report_progress(handle, 100);
                }
            }
    
            if (percent == 100 && userdata) {
                free(userdata);
            }
        }
    }
  6. Keluar dari downloader.

    Setelah konten paket pembaruan diunduh, panggil aiot_download_deinit untuk menghapus sesi download. Thread unduh kemudian keluar.

        aiot_download_deinit(&dl_handle);
        printf("download thread exit\n");

Langkah 6: Laporkan nomor versi setelah pembaruan

  • Jika pembaruan OTA menggunakan paket satu file yang hanya berisi satu firmware, laporkan nomor versi firmware yang termasuk dalam paket tersebut ke IoT Platform untuk menyelesaikan pencocokan versi.
  • Jika pembaruan OTA menggunakan paket multi-file, file-file tersebut dapat sesuai dengan satu atau beberapa firmware. Jika setiap file memiliki nomor versi firmware yang berbeda, seperti a1, b1, dan c1, laporkan nomor versi paket gabungan, seperti a1b1c1.

Untuk kode contoh pelaporan nomor versi, lihat Langkah 3: Laporkan nomor versi perangkat saat ini.

Catatan
  • Setelah perangkat menyelesaikan pembaruan OTA, perangkat harus melaporkan nomor versi terbaru. Jika tidak, IoT Platform menganggap tugas pembaruan OTA gagal.

  • Jika perangkat perlu di-restart setelah pembaruan, perangkat harus melaporkan nomor versi terbaru setelah restart.

  • Kode contoh tidak menyertakan logika untuk melaporkan nomor versi setelah pembaruan selesai. Anda harus menambahkan logika ini ke kode Anda.

Langkah 7: Putuskan koneksi

Catatan

MQTT biasanya digunakan untuk perangkat yang memerlukan koneksi persisten. Oleh karena itu, program biasanya tidak mencapai titik ini.

Dalam program contoh, thread utama bertanggung jawab untuk mengonfigurasi parameter dan menjalin koneksi. Setelah koneksi terjalin, thread utama dapat masuk ke mode hibernasi.

Anda dapat memanggil aiot_mqtt_disconnect untuk mengirim pesan pemutusan koneksi ke IoT Platform dan memutuskan koneksi jaringan.

    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;
    }

Langkah 8: Keluar dari program OTA

Panggil aiot_ota_deinit untuk menghapus instans OTA.

    aiot_ota_deinit(&ota_handle);

Langkah selanjutnya