全部产品
Search
文档中心

IoT Platform:Kode contoh

更新时间:Jul 06, 2025

Unduh paket pembaruan over-the-air (OTA) yang berisi beberapa file melalui HTTPS dan lakukan pembaruan pada perangkat. File kode contoh digunakan untuk proses ini.

Informasi latar belakang

Catatan Hanya Link SDK for C yang diunduh setelah 09 September 2021 (tidak termasuk tanggal ini) yang mendukung mengunduh paket pembaruan OTA yang berisi beberapa file.

Untuk informasi lebih lanjut tentang cara memperoleh SDK, lihat Peroleh SDK.

Langkah 1: Inisialisasi klien

  1. Tambahkan file header

    ...
    ……
    #include "aiot_ota_api.h"
    ……
  2. Tambahkan dependensi dasar dan konfigurasikan fitur output log.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Panggil operasi aiot_ota_init untuk membuat OTA.

        ota_handle = aiot_ota_init();
        if (NULL == ota_handle) {
            printf("aiot_ota_init gagal\r\n");
            aiot_mqtt_deinit(&mqtt_handle);
            return -2;
        }

Langkah 2: Konfigurasikan fitur yang diperlukan

Panggil operasi aiot_ota_setopt untuk mengonfigurasi item berikut.

  1. Asosiasikan dengan MQTT Connection Handler.

    Penting

    Sebelum menyetel parameter spesifik pembaruan OTA, pastikan informasi autentikasi perangkat telah ditentukan. Untuk detail lebih lanjut, lihat Contoh.

    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);
    • Parameter

      Contoh

      Deskripsi

      AIOT_OTAOPT_MQTT_HANDLE

      mqtt_handle

      Anda harus membangun koneksi MQTT. Parameter ini digunakan untuk mengasosiasikan dengan handle koneksi MQTT.

  2. Konfigurasikan callback untuk memproses perintah pembaruan OTA.

    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler);
    • Parameter

      Contoh

      Deskripsi

      AIOT_OTAOPT_MQTT_HANDLER

      demo_ota_recv_handler

      Fungsi callback ini dipanggil ketika perangkat menerima perintah pembaruan OTA dari IoT Platform.

Langkah 3: Kirim nomor versi perangkat

Setelah perangkat membangun koneksi MQTT dengan IoT Platform, panggil operasi aiot_ota_report_version untuk mengirim nomor versi perangkat. IoT Platform menentukan apakah pembaruan diperlukan berdasarkan nomor versi.

Dalam contoh ini, nomor versi yang dikirim adalah 1.0.0. Dalam skenario bisnis sebenarnya, Anda harus memperoleh nomor versi dari pengaturan perangkat dan menentukan logika untuk mengirim nomor versi.

Penting

Sebelum melakukan pembaruan OTA, Anda harus mengirim nomor versi setidaknya sekali.

    cur_version = "1.0.0";
    res = aiot_ota_report_version(ota_handle, cur_version);
    if (res < STATE_SUCCESS) {
        printf("aiot_ota_report_version gagal: -0x%04X\r\n", -res);
    }

Langkah 4: Terima perintah pembaruan

  1. Setelah menambahkan paket pembaruan ke IoT Platform dan memulai tugas pembaruan, IoT Platform mengirim perintah pembaruan ke perangkat.

    Untuk informasi lebih lanjut, lihat Tambahkan Paket Pembaruan.

  2. Perangkat memanggil operasi aiot_mqtt_recv untuk menerima pesan. Setelah perangkat mengenali pesan sebagai perintah pembaruan OTA, callback demo_ota_recv_handler dipanggil.


  3. Saat menentukan logika pemrosesan callback, perhatikan hal-hal berikut:
    • IoT Platform menggunakan topik /ota/device/upgrade/${ProductKey}/${DeviceName} untuk mengirim perintah pembaruan OTA ke perangkat.

      Untuk informasi lebih lanjut tentang ${ProductKey} dan ${DeviceName}, lihat Peroleh Informasi Verifikasi Perangkat.

    • AIOT_OTARECV_FOTA menunjukkan jenis pesan.
      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;
                  }
           ……
           ……
      
      }
    • aiot_ota_recv_t menunjukkan format data, dan Link SDK secara otomatis mengurai pesan yang diterima.

    • Anda dapat menentukan logika pemrosesan callback berdasarkan kode contoh. Untuk informasi lebih lanjut, lihat Langkah 5: Unduh Paket Pembaruan dan Lakukan Pembaruan OTA.

Langkah 5: Unduh paket pembaruan dan lakukan pembaruan OTA

Penting

Setelah perangkat menerima perintah pembaruan yang didorong oleh IoT Platform, perangkat tidak secara otomatis mengunduh paket pembaruan. Anda harus memanggil operasi API dari Link SDK untuk mengunduh paket tersebut.

Setelah callback demo_ota_recv_handler dipanggil, downloader memulai Permintaan HTTPS untuk menerima paket pembaruan OTA.


  1. aiot_download_initdownload
    Catatan

    Paket pembaruan OTA dapat berisi beberapa file. Untuk informasi lebih lanjut, lihat Tambahkan 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. aiot_download_setopt
    Catatan

    Jika paket pembaruan OTA berisi beberapa file, perhatikan ID, ukuran, dan kemajuan setiap file saat mengunduh paket tersebut.

                /* Atur protokol TLS untuk mengunduh. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_CRED, (void *)(&cred));
                /* Atur nomor port server yang akan diakses. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_PORT, (void *)(&port));
                /* Tentukan informasi tugas unduhan, yang dapat diperoleh dari anggota task_desc dalam parameter input ota_msg. Informasi tersebut mencakup URL unduhan, ukuran firmware, dan tanda tangan firmware. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_TASK_DESC, (void *)(ota_msg->task_desc));
                /* Atur callback yang dipanggil SDK saat konten yang diunduh diterima. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_RECV_HANDLER, (void *)(demo_download_recv_handler));
                /* Atur panjang buffer maksimum untuk satu unduhan. Pengguna diberitahu jika batas tercapai. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_BODY_BUFFER_MAX_LEN, (void *)(&max_buffer_len));
                /* Tentukan informasi yang dibagikan di antara panggilan berbeda dari AIOT_DLOPT_RECV_HANDLER. Dalam contoh ini, informasi kemajuan disimpan. */
                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);
    
                /* Kirim kemajuan 0 untuk tugas unduhan pertama. */
                if (0 == ota_msg->task_desc->file_id) {
                    aiot_download_report_progress(dl_handle, 0);
                }
                            
    1. 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 gagal: %d\r\n", res);
                      aiot_download_deinit(&dl_handle);
                      free(download_status);
                  } else {
                      /* Atur jenis thread unduhan menjadi detach. Setelah firmware diperoleh, thread unduhan otomatis keluar. */
                      pthread_detach(g_download_thread);
                  }
    2. demo_ota_download_threadaiot_download_send_request
      • void *demo_ota_download_thread(void *dl_handle)
        {
            int32_t     ret = 0;
        
            printf("\r\nmemulai thread unduhan dalam 2 detik ......\r\n");
            sleep(2);
        
            /* Mulai permintaan untuk mengunduh paket pembaruan dari server penyimpanan.
            /*
             * TODO: Sintaks berikut menggunakan satu permintaan untuk memperoleh semua konten firmware.
             *       Jika perangkat memiliki sumber daya terbatas atau koneksi jaringan buruk, Anda dapat mengimplementasikan unduhan tersegmentasi.
             *
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_START, ...);
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_END, ...);
             *       aiot_download_send_request(dl_handle);
             *
             *      Jika Anda mengimplementasikan unduhan tersegmentasi, tentukan tiga pernyataan sebelumnya dalam loop. Dalam hal ini, beberapa permintaan dikirim dan beberapa respons diterima.
             *
             */
        
             ……
             ……
        
        }
      • Untuk mengimplementasikan unduhan tersegmentasi, atur parameter AIOT_DLOPT_RANGE_START dan AIOT_DLOPT_RANGE_END.

        Sebagai contoh, jika Anda ingin mengunduh paket pembaruan 1.024 byte menggunakan dua segmen, tentukan nilai berikut untuk parameter:

        • Segmen pertama: AIOT_DLOPT_RANGE_START=0, AIOT_DLOPT_RANGE_END=511

        • Segmen kedua: AIOT_DLOPT_RANGE_START=512, AIOT_DLOPT_RANGE_END=1023

    1. aiot_download_recvdemo_ota_download_threaddemo_download_recv_handler
      void *demo_ota_download_thread(void *dl_handle)
      {
           ……
           ……
      
         aiot_download_send_request(dl_handle);
          // while (1) {
          while (should_stop == 0) {
              /* Terima firmware yang dikirim dari server. */
              ret = aiot_download_recv(dl_handle);
      
              /* Setelah firmware diunduh, nilai kembalian aiot_download_recv() adalah STATE_DOWNLOAD_FINISHED. Jika tidak, nilainya adalah jumlah byte yang diperoleh. */
              if (STATE_DOWNLOAD_FINISHED == ret) {
                  printf("unduhan selesai\r\n");
                  break;
              }
              if (STATE_DOWNLOAD_RENEWAL_REQUEST_SENT == ret) {
                  printf("permintaan pembaruan unduhan telah berhasil dikirim\r\n");
                  continue;
              }
              if (ret <= STATE_SUCCESS) {
                  printf("unduhan gagal, kode kesalahan adalah %d, coba kirim permintaan pembaruan\r\n", ret);
                  continue;
              }
          }
           ……
           ……
      }
    2. demo_download_recv_handler
      Catatan
      • Jika paket pembaruan OTA berisi satu file, Anda dapat membakar file tersebut ke lokasi penyimpanan lokal yang ditentukan.
      • Jika paket pembaruan OTA berisi beberapa file, file-file tersebut dapat dibakar ke lokasi penyimpanan yang berbeda. Anda harus mengidentifikasi bidang file_name dari setiap file 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;
      
          /* Anda dapat menyetel packet->type hanya ke AIOT_DLRECV_HTTPBODY. */
          if (!packet || AIOT_DLRECV_HTTPBODY != packet->type) {
              return;
          }
          percent = packet->data.percent;
      
          /* userdata dapat menyimpan data yang perlu dibagikan antara panggilan berbeda dari demo_download_recv_handler(). */
          /* Dalam contoh ini, persentase kemajuan unduhan firmware disimpan. */
          if (userdata) {
              last_percent = (download_status->last_percent);
          }
      
          data_buffer_len = packet->data.len;
      
          /* Nilai negatif dari percent menunjukkan bahwa terjadi pengecualian selama penerimaan data atau otentikasi digest gagal. */
          if (percent < 0) {
              printf("pengecualian: percent = %d\r\n", percent);
              if (userdata) {
                  free(userdata);
              }
              return;
          }
           ……
           ……
      
      }
  3. Setelah callback demo_download_recv_handler dipanggil, panggil operasi aiot_download_report_progress untuk mengirim kemajuan unduhan dan kesalahan pembaruan ke IoT Platform. Kesalahan pembaruan mencakup kegagalan pembakaran dan pemutusan jaringan.

    • Lihat kemajuan yang dikirim:

      Kemajuan ditampilkan di konsol IoT Platform. Untuk informasi lebih lanjut, lihat Lihat Status Pembaruan.

    • Kirim kemajuan dalam kondisi normal atau abnormal:

      • Jika unduhan berhasil, bilangan bulat yang menunjukkan kemajuan dikirim ke IoT Platform. Link SDK secara otomatis menghitung nilai parameter percent dan mengirimkan nilai tersebut ke IoT Platform menggunakan callback.

      • Jika terjadi kesalahan selama unduhan atau firmware yang diunduh gagal dibakar, kesalahan dikirim ke IoT Platform. Untuk informasi lebih lanjut tentang kode kesalahan, lihat aiot_ota_protocol_errcode_t.

    • Kirim kemajuan menggunakan metode berikut:
      • Jika paket pembaruan berisi satu file, kirim kemajuan file tersebut.
      • Jika paket pembaruan berisi beberapa file, jangan kirim kemajuan unduhan setiap file untuk mencegah kebingungan. Kami sarankan Anda menghitung persentase dengan menggunakan ukuran file total sebagai penyebut dan jumlah byte yang diunduh untuk semua file sebagai pembilang. Lalu, kirim kemajuan unduhan.
        Anda juga dapat menentukan logika untuk mengirim kemajuan berdasarkan kebutuhan bisnis Anda. Contoh:
        • Kirim kemajuan 0% saat unduhan dimulai. Lalu, kirim kemajuan setiap kali kemajuan bertambah 10% hingga unduhan selesai.
        • Kirim kemajuan 0% saat unduhan dimulai dan 100% saat unduhan selesai.
    void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
    {
         ……
         ……
    
        /*
         * TODO: Setelah segmen firmware diunduh, lakukan operasi berikut:
         *       Setelah Anda mengunduh paket pembaruan, simpan memori yang posisi awalnya adalah packet->data.buffer dan panjangnya adalah packet->data.len ke lokasi penyimpanan lokal.
         *
         *      Jika pembakaran gagal, Anda harus memanggil operasi aiot_download_report_progress(handle, -4) untuk mengirim pesan kesalahan ke IoT Platform.
         *       Kode kesalahan yang didefinisikan dalam protokol termasuk dalam variabel aiot_ota_protocol_errcode_t. Contoh:
         *           -1: menunjukkan bahwa pembaruan gagal.
         *           -2: menunjukkan bahwa unduhan gagal.
         *           -3: menunjukkan bahwa verifikasi gagal.
         *           -4: menunjukkan bahwa pembakaran gagal.
         *
         */
    
        /* Jika nilai parameter percent adalah 100, semua konten firmware telah diunduh. */
        if (percent == 100) {
            g_finished_task_num++;
            /*
             * TODO: Bakar firmware, simpan konfigurasi, mulai ulang perangkat, lalu beralih ke firmware baru untuk mem-boot perangkat. 
                     Gunakan kode berikut untuk mengirim nomor versi firmware baru ke IoT Platform. Sebagai contoh, jika versi diperbarui dari 1.0.0 menjadi 1.1.0, nilai new_version adalah 1.1.0 harus dikirim ke IoT Platform. 
                     aiot_ota_report_version(ota_handle, new_version);
                     IoT Platform menentukan bahwa pembaruan berhasil setelah menerima nomor versi firmware baru. Jika tidak, IoT Platform menentukan bahwa pembaruan gagal. 
                     Jika pembaruan gagal setelah paket pembaruan diunduh, panggil operasi aiot_download_report_progress(handle, -1) untuk mengirim jenis kesalahan. 
             */
        }
    
        /* Sederhanakan output. Setiap kali kemajuan unduhan bertambah minimal 5%, kemajuan dicetak dan dikirim ke IoT Platform. */
        if (percent - last_percent >= 5 || percent == 100) {
            if (NULL != download_status) {
                printf("file_id %d, unduh %03d%% selesai, +%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) {
                    /* Jika beberapa thread digunakan untuk mengunduh paket pembaruan, kirim kemajuan 100% setelah semua file diunduh. */
                    aiot_download_report_progress(handle, 100);
                }
            }
    
            if (percent == 100 && userdata) {
                free(userdata);
            }
        }
    }
  4. Keluar dari downloader.

    Setelah paket pembaruan diunduh, panggil operasi aiot_download_deinit untuk menghapus sesi download. Lalu, thread unduhan ditutup.

        aiot_download_deinit(&dl_handle);
        printf("thread unduhan keluar\n");

Langkah 6: Kirim nomor versi setelah pembaruan

  • Jika paket pembaruan OTA berisi satu file, paket tersebut membawa nomor versi firmware. Anda dapat mengirim nomor versi ke IoT Platform.
  • Jika paket pembaruan berisi beberapa file, file-file tersebut dapat sesuai dengan satu atau beberapa nomor versi firmware. Jika file-file tersebut sesuai dengan nomor versi firmware yang berbeda, seperti a1, b1, dan c1, Anda harus mengirim nomor versi gabungan dari paket pembaruan, seperti a1b1c1.

Untuk informasi lebih lanjut tentang kode contoh untuk mengirim nomor versi, lihat Langkah 3: Kirim Nomor Versi Perangkat.

Catatan
  • Setelah perangkat diperbarui, Anda harus mengirim nomor versi terbaru. Jika tidak, IoT Platform menentukan bahwa tugas pembaruan OTA gagal.

  • Perangkat mungkin perlu dimulai ulang setelah pembaruan. Dalam hal ini, kirim nomor versi terbaru setelah perangkat dimulai ulang.

  • Dalam contoh ini, logika untuk mengirim nomor versi terbaru setelah pembaruan tidak ditentukan. Anda harus menentukan logika berdasarkan kebutuhan bisnis Anda.

Langkah 7: Tutup koneksi

Catatan

Koneksi MQTT diterapkan pada perangkat yang tetap terhubung secara persisten. Anda dapat memutuskan koneksi perangkat dari IoT Platform secara manual.

Dalam contoh ini, thread utama digunakan untuk mengonfigurasi parameter dan membangun koneksi. Setelah koneksi dibangun, Anda dapat menangguhkan thread utama.

Panggil operasi aiot_mqtt_disconnect untuk memutuskan koneksi perangkat dari IoT Platform.

    res = aiot_mqtt_disconnect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_disconnect gagal: -0x%04X\n", -res);
        return -1;
    }

Langkah 8: Keluar dari program

Panggil operasi aiot_ota_deinit untuk menghapus OTA

    aiot_ota_deinit(&ota_handle);

Apa yang harus dilakukan selanjutnya

  • Dalam contoh ini, file yang dapat dieksekusi ./output/fota-multi-file_demo dihasilkan.

    Untuk informasi lebih lanjut, lihat Siapkan Lingkungan.

  • Lihat Log.