A demonstração ./demos/cota_basic_demo.c mostra como implementar a configuração remota em um dispositivo.
Informações básicas
Para obter mais informações sobre o recurso de configuração remota, consulte Visão geral.
O recurso de configuração remota exige uma conexão MQTT. Para mais detalhes sobre conexões MQTT, consulte Conexão MQTT.
no heading
Etapa 1: Inicialização
-
Adicione o arquivo de cabeçalho.
…… …… #include "aiot_ota_api.h" …… -
Configure as dependências subjacentes e a saída de log.
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb); -
Chame aiot_ota_init para crie uma instância OTA.
ota_handle = aiot_ota_init(); if (NULL == ota_handle) { printf("aiot_ota_init failed\r\n"); aiot_mqtt_deinit(&mqtt_handle); return -2; }
Etapa 2: Configure recursos
Chame aiot_ota_setopt para defina as opções a seguir.
-
Associe o identificador da conexão MQTT.
ImportanteAntes de defina os parâmetros de configuração remota,
certifique-se de que parâmetros como as credenciais do dispositivo estejam configurados. Para mais informações, consulte
Configure parâmetros de conexão MQTT
.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle); -
Item de configuração
Exemplo
Descrição
AIOT_OTAOPT_MQTT_HANDLE
mqtt_handle
As solicitações de configuração remota utilizam uma conexão MQTT. Este item associa o identificador dessa conexão.
-
-
Defina o callback para mensagens de instrução de configuração remota.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler); -
Item de configuração
Exemplo
Descrição
AIOT_OTAOPT_MQTT_HANDLE
demo_ota_recv_handler
Invocado quando o dispositivo recebe uma instrução de configuração remota do IoT Platform.
-
Etapa 3: O dispositivo solicita ativamente mensagens de configuração
Se o dispositivo estiver offline quando o IoT Platform enviar uma instrução de configuração remota, ele poderá solicitá-la após ficar online.
Se nenhuma tarefa de dispositivo for criada no IoT Platform, a chamada da API retornará
receive task get detail reply, task_id:[$next],status:[9]
.
-
Chame aiot_mqtt_pub para enviar uma solicitação ao IoT Platform e obter informações de configuração remota.
-
{ 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; } } -
Parâmetro Valor de exemplo Descrição topic_string /sys/a18wP******5/LightSwitch/thing/config/get O tópico usado para solicitar informações de configuração remota. Para mais informações sobre tópicos, consulte O que é um tópico?.
No código de exemplo:
a18wPé a ProductKey do dispositivo.LightSwitché o DeviceName do dispositivo.
Para mais detalhes, consulte Obter credenciais do dispositivo.
payload_string {\"id\":\"123\",\"params\":{\"configScope\":\"product\",\"getType\":\"file\"}} O conteúdo da mensagem de solicitação. A mensagem de solicitação está no formato JSON e corresponde ao valor de params nos dados formatados em Alink. Para mais informações, consulte Um dispositivo solicita ativamente informações de configuração.
-
-
Após receber a solicitação, o IoT Platform retorna as informações de configuração ao dispositivo.
NotaO tamanho máximo do conteúdo de configuração remota é de 64 KB.
É possível ative a configuração remota e edite a configuração no
. Para mais informações, consulte
Edite um arquivo de configuração
.
-
Chame aiot_mqtt_recv para receber a mensagem de instrução de configuração remota.
Se o ponteiro
g_dl_handlefor nulo, o sistema apenas consultará mensagens MQTT da rede.Se o ponteiro
g_dl_handlenão for nulo, a funçãoaiot_download_recvserá chamada.
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); } } -
Ao receber a mensagem de instrução de configuração, o dispositivo aciona a função de callback
demo_ota_recv_handler.Utilize as informações a seguir para escrever a lógica de processamento da função de callback:
O IoT Platform envia instruções de configuração remota ao dispositivo pelo tópico
/sys/${ProductKey}/${DeviceName}/thing/config/push.O Link SDK analisa as instruções do IoT Platform na estrutura de dados aiot_ota_recv_t e processa automaticamente as mensagens de configuração.
O tipo de mensagem para configuração remota é AIOT_OTARECV_COTA.
Na função de callback, inicie uma solicitação HTTPS para baixe o arquivo de configuração remota. Para saber como escrever essa função, consulte Etapa 5: Baixe o arquivo de configuração remota.
Etapa 4: O dispositivo recebe informações de configuração remota enviadas pelo IoT Platform
Se o dispositivo estiver online, ele recebe imediatamente a instrução de configuração remota do IoT Platform e aciona a função de callback.
Para mais detalhes, consulte Escrever a lógica de processamento da função de callback.
Etapa 5: Baixe o arquivo de configuração remota
O dispositivo não baixa automaticamente o arquivo de configuração após receber a instrução. Chame a API do Link SDK para iniciar o download.
-
Inicialize o downloader.
Chame
para crie uma instância de
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); -
Configure os parâmetros de download.
Chame
para configure os parâmetros da tarefa de download.
/* 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; } } -
Após o envio da solicitação de download, o dispositivo recebe uma mensagem de confirmação que aciona a função de callback
demo_download_recv_handlerpara processar o download.Use as informações abaixo para desenvolver a lógica de processamento da função de callback:
A estrutura de dados da mensagem de download é aiot_download_recv_t, que atua como parâmetro de entrada da função de callback.
O campo
packet->typeda mensagem de download é AIOT_DLRECV_HTTPBODY.O código de exemplo apenas imprime os dados. Baixe o arquivo de configuração para um local específico.
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; } …… …… } -
Chame aiot_download_report_progress para relatar o progresso do download.
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); } -
Ao concluir o download, chame aiot_download_deinit para defina o identificador
g_dl_handlecomo nulo.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); } }
Etapa 6: Sair do programa
Chame aiot_ota_deinit para destruir a instância OTA.
aiot_ota_deinit(&ota_handle);
Próximos passos
-
./output/cota-basic-demo.
Para mais informações, consulte Compilar e execute.