All Products
Search
Document Center

IoT Platform:Usage example

Last Updated:Jun 16, 2026

The ./demos/cota_basic_demo.c demo shows how to implement remote configuration for a device.

Background information

  • For more information about the remote configuration feature, see Overview.
  • The remote configuration feature requires an MQTT connection. For more information about MQTT connections, see MQTT connection.

Step 1: Initialization

  1. Add the header file.
    ……
    ……
    #include "aiot_ota_api.h"
    ……

  2. Configure underlying dependencies and log output.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Call aiot_ota_init to create an OTA instance.
        ota_handle = aiot_ota_init();
        if (NULL == ota_handle) {
            printf("aiot_ota_init failed\r\n");
            aiot_mqtt_deinit(&mqtt_handle);
            return -2;
        }

Step 2: Configure features

Call aiot_ota_setopt to configure the following options.

  1. Associate the MQTT connection handle.
    Important Before you set remote configuration parameters, ensure that parameters such as device credentials are configured. For more information, see Configure MQTT connection parameters.
    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);
    • Configuration item Example Description
      AIOT_OTAOPT_MQTT_HANDLE mqtt_handle Remote configuration requests use an MQTT connection. This item associates the MQTT connection handle.



  2. Set the callback for remote configuration instruction messages.
    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler);
    • Configuration item Example Description
      AIOT_OTAOPT_MQTT_HANDLE demo_ota_recv_handler Invoked when the device receives a remote configuration instruction from IoT Platform.

Step 3: A device actively requests configuration messages

If a device is offline when IoT Platform sends a remote configuration instruction, the device can request it after going online.

Note If no device task is created in IoT Platform, the API call returns receive task get detail reply, task_id:[$next],status:[9].
  1. Call aiot_mqtt_pub to send a request to IoT Platform to obtain remote configuration information.
    •     {
              char *topic_string = "/sys/a18wP******/LightSwitch/thing/config/get";
              char *payload_string = "{\"id\":\"123\",\"params\":{\"configScope\":\"product\",\"getType\":\"file\"}}";
      
              res = aiot_mqtt_pub(mqtt_handle, topic_string, (uint8_t *)payload_string, strlen(payload_string), 0);
              if (res < STATE_SUCCESS) {
                  printf("aiot_mqtt_pub failed: -0x%04X\r\n", -res);
                  /* If the connection fails, destroy the MQTT instance and release resources. */
                  goto exit;
              }
          }
    • Parameter Example value Description
      topic_string /sys/a18wP******5/LightSwitch/thing/config/get The topic used to request remote configuration information.

      For more information about topics, see What is a topic?.

      In the sample code:

      • a18wP****** is the ProductKey of the device.

      • LightSwitch is the DeviceName of the device.

      For more information, see Obtain device credentials.

      payload_string {\"id\":\"123\",\"params\":{\"configScope\":\"product\",\"getType\":\"file\"}} The content of the request message.

      The request message is in JSON format. It is the value of params in the Alink-formatted data. For more information, see A device actively requests configuration information.

  2. After IoT Platform receives the request, it returns the configuration information to the device.
    Note The maximum size of the remote configuration content is 64 KB.
    You can enable remote configuration and edit the configuration in the IoT Platform console. For more information, see Edit a configuration file.
  3. Call aiot_mqtt_recv to receive the remote configuration instruction message.
    • If the g_dl_handle pointer is null, the system only polls for MQTT messages from the network.
    • If the g_dl_handle pointer is not null, the aiot_download_recv function is called.
    while (1) {
            aiot_mqtt_process(mqtt_handle);
            res = aiot_mqtt_recv(mqtt_handle);
    
            if (res == STATE_SYS_DEPEND_NWK_CLOSED) {
                sleep(1);
            }
            if (NULL != g_dl_handle) {
                /* Before the remote configuration is received, change the MQTT message receiving timeout period to 100 ms to reduce the interval between two remote configuration downloads. */
                int32_t ret = aiot_download_recv(g_dl_handle);
                timeout_ms = 100;
    
                if (STATE_DOWNLOAD_FINISHED == ret) {
                    aiot_download_deinit(&g_dl_handle);
                    /* After the remote configuration is received, change the MQTT message receiving timeout period back to the default value of 5000 ms. */
                    timeout_ms = 5000;
                }
                aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_TIMEOUT_MS, (void *)&timeout_ms);
            }
        }
  4. After the device receives the configuration instruction message, the demo_ota_recv_handler callback function is triggered.
    Use the following information to write the processing logic for the callback function:
    • IoT Platform sends remote configuration instructions to the device over the /sys/${ProductKey}/${DeviceName}/thing/config/push topic.
    • The Link SDK parses instructions from the IoT Platform into an aiot_ota_recv_t data structure and automatically parses configuration messages.
    • The message type for remote configuration is AIOT_OTARECV_COTA.
    • In the callback function, you can initiate an HTTPS request to download the remote configuration file. For information about how to write the callback function, see Step 5: Download the remote configuration file.

Step 4: A device receives remote configuration information pushed by IoT Platform

If the device is online, it immediately receives the remote configuration instruction from IoT Platform and triggers the callback function.

For more information, see Write the processing logic for the callback function.

Step 5: Download the remote configuration file

Important The device does not automatically download the configuration file after receiving the configuration instruction. You must call the Link SDK API to start the download.
  1. Initialize the downloader.
    Call aiot_download_init to create a download
                uint32_t res = 0;
                uint16_t port = 443;
                uint32_t max_buffer_len = 2048;
                aiot_sysdep_network_cred_t cred;
                void *dl_handle = aiot_download_init();
    
                if (NULL == dl_handle || NULL == ota_msg->task_desc) {
                    return;
                }
    
                printf("configId: %s, configSize: %u Bytes\r\n", ota_msg->task_desc->version,
                       ota_msg->task_desc->size_total);
    
                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. Configure download parameters.
    Call aiot_download_setopt to configure parameters for the download task.
                /* Set the download method to TLS download. */
                if ((STATE_SUCCESS != aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_CRED, (void *)(&cred))) ||
                    /* Set the server port for the download. */
                    (STATE_SUCCESS != aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_PORT, (void *)(&port))) ||
                    /* Set the information about the download task. This information is obtained from the task_desc member of the ota_msg input parameter. It includes the download URL, and the size and version number of the remote configuration. */
                    (STATE_SUCCESS != 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. */
                    (STATE_SUCCESS != aiot_download_setopt(dl_handle, AIOT_DLOPT_RECV_HANDLER, (void *)(demo_download_recv_handler))) ||
                    /* Set the maximum buffer length for a single download. The user is notified each time the buffer is full. */
                    (STATE_SUCCESS != aiot_download_setopt(dl_handle, AIOT_DLOPT_BODY_BUFFER_MAX_LEN, (void *)(&max_buffer_len))) ||
                    /* Send an HTTP GET request to the HTTP server. */
                    (STATE_SUCCESS != aiot_download_send_request(dl_handle))) {
                    if (res != STATE_SUCCESS) {
                        aiot_download_deinit(&dl_handle);
                        break;
                    }
                }



  3. After a download request is sent, the device receives an acknowledgement message, which triggers the demo_download_recv_handler callback function to process the download.
    Use the following information to write the processing logic for the callback function:
    • The data structure of the download message is aiot_download_recv_t. This is an input parameter of the callback function.
    • The packet->type of the download message is AIOT_DLRECV_HTTPBODY.
    • The sample code only prints the data. You must download the configuration file to a specified location.
    void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
    {
        /* Currently, only the case where packet->type is AIOT_DLRECV_HTTPBODY is supported. */
        if (!packet || AIOT_DLRECV_HTTPBODY != packet->type) {
            return;
        }
        int32_t percent = packet->data.percent;
        uint8_t *src_buffer = packet->data.buffer;
        uint32_t src_buffer_len = packet->data.len;
    
        /* If percent is a negative number, a packet reception exception or a digest verification error occurred. */
        if (percent < 0) {
            /* A packet reception exception or a digest verification error occurred. */
            printf("exception happend, percent is %d\r\n", percent);
            return;
        }
    ……
    ……
    }
  4. Call aiot_download_report_progress to report the download progress.
    void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
    {
        /* Currently, only the case where packet->type is AIOT_DLRECV_HTTPBODY is supported. */
        if (!packet || AIOT_DLRECV_HTTPBODY != packet->type) {
            return;
    ……
    ……
        aiot_download_report_progress(handle, percent);
        printf("config len is %d, config content is %.*s\r\n", src_buffer_len, src_buffer_len, (char *)src_buffer);
    }
  5. After the download is complete, call aiot_download_deinit to set the g_dl_handle handle to null.
    while (1) {
            aiot_mqtt_process(mqtt_handle);
            res = aiot_mqtt_recv(mqtt_handle);
    
            if (res == STATE_SYS_DEPEND_NWK_CLOSED) {
                sleep(1);
            }
            if (NULL != g_dl_handle) {
                /* Before the remote configuration is received, change the MQTT message receiving timeout period to 100 ms to reduce the interval between two remote configuration downloads. */
                int32_t ret = aiot_download_recv(g_dl_handle);
                timeout_ms = 100;
    
                if (STATE_DOWNLOAD_FINISHED == ret) {
                    aiot_download_deinit(&g_dl_handle);
                    /* After the remote configuration is received, change the MQTT message receiving timeout period back to the default value of 5000 ms. */
                    timeout_ms = 5000;
                }
                aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_TIMEOUT_MS, (void *)&timeout_ms);
            }
        }

Step 6: Exit the program

Call aiot_ota_deinit to destroy the OTA instance.

    aiot_ota_deinit(&ota_handle);

What to do next