./demos/bootstrap_posix_demo.c實現裝置的分發功能。
背景資訊
步驟一:初始化
- 添加標頭檔。
…… …… #include "aiot_bootstrap_api.h"
配置底層依賴和日誌輸出。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);
- 調用aiot_bootstrap_init,建立
Bootstrap
bootstrap_handle = aiot_bootstrap_init(); if (bootstrap_handle == NULL) { printf("aiot_bootstrap_init failed\n"); return -1; }
步驟二:配置功能
調用aiot_bootstrap_setopt,配置以下功能。
- 。重要 TLS層的安全連線類型必須為認證方式AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA。
int32_t res = STATE_SUCCESS; void *bootstrap_handle = NULL, *mqtt_handle = NULL; aiot_sysdep_network_cred_t cred; demo_info_t demo_info; /* TODO: 替換為自己裝置的productKey和deviceName */ char *product_key = "a18wP******"; char *device_name = "LightSwitch"; char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******"; …… …… memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t)); cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA認證校正MQTT服務端 */ cred.max_tls_fragment = 16384; /* 最大的分區長度為16 KB, 其它可選值還有4 KB、2 KB、1 KB、0.5 KB */ cred.sni_enabled = 1; /* TLS建連時, 支援Server Name Indicator */ cred.x509_server_cert = ali_ca_cert; /* 用來驗證MQTT服務端的RSA根憑證 */ cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用來驗證MQTT服務端的RSA根憑證長度 */ …… …… aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_HOST, (void *)host); aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PORT, (void *)&port); aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PRODUCT_KEY, (void *)product_key); aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_DEVICE_NAME, (void *)device_name); aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_NETWORK_CRED, (void *)&cred); …… ……
參數 樣本 說明 product_key a18wP****** 其中,device_secret將在裝置擷取到接入網域名稱和連接埠號碼以後,建立MQTT串連時,使用該參數。
device_name LightSwitch device_secret uwMTmVAMnGGHaAkqmeDY6cHxxB******
- 配置訊息回調。
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_RECV_HANDLER, (void *)demo_bootstrap_recv_handler); aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_USERDATA, (void *)&demo_info);
配置項 樣本值 說明 AIOT_BOOTSTRAPOPT_RECV_HANDLER demo_bootstrap_recv_handler 接收到裝置分發訊息時,調用該函數。 AIOT_BOOTSTRAPOPT_USERDATA demo_info 設定上下文。當觸發函數 demo_bootstrap_recv_handler
時,回傳userdata
,您需自行對其做類型轉換後,再使用。
- 。
void demo_bootstrap_event_handler(void *handle, const aiot_bootstrap_event_t *event, void *userdata) { switch (event->type) { case AIOT_BOOTSTRAPEVT_INVALID_RESPONSE: { printf("AIOT_BOOTSTRAPEVT_INVALID_RESPONSE\n"); } break; case AIOT_BOOTSTRAPEVT_INVALID_CMD: { printf("AIOT_BOOTSTRAPEVT_INVALID_CMD\n"); } break; default: { } break; } }
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_EVENT_HANDLER, (void *)demo_bootstrap_event_handler);
配置項 樣本值 說明 AIOT_BOOTSTRAPOPT_EVENT_HANDLER demo_bootstrap_event_handler 當裝置串連狀態發生變化時,根據該回呼函數定義的處理邏輯,執行對應的處理。
步驟三:發送請求
重要 發送裝置分發請求前,請確保已在物聯網平台執行裝置分發操作。否則,請求後返回的接入網域名稱為裝置當前的接入網域名稱和連接埠號碼。
調用aiot_bootstrap_send_request,根據上一步配置的參數,向伺服器發送HTTPS協議的請求,請求裝置分發。
關於HTTPS請求的詳細說明,請參見裝置分發的請求資料格式。
res = aiot_bootstrap_send_request(bootstrap_handle);
if (res < STATE_SUCCESS) {
printf("aiot_bootstrap_send_request failed, res: -0x%04X\n", -res);
return -1;
}
步驟四:接收應答
- 裝置請求aiot_bootstrap_recv,接收應答訊息,根據訊息回呼函數的處理邏輯,執行對應處理。
res = aiot_bootstrap_recv(bootstrap_handle); if (res < STATE_SUCCESS) { printf("aiot_bootstrap_recv failed, res: -0x%04X\n", -res); return -1; }
- 編寫回呼函數的處理邏輯。您可以參考以下內容,編寫回呼函數的處理邏輯:
報文類型 說明 AIOT_BOOTSTRAPRECV_STATUS_CODE 伺服器返回的HTTP狀態代碼,更多資訊,請參見HTTP狀態代碼。 範例程式碼未對接收的狀態代碼編寫處理邏輯,您可以根據業務需要,自行編寫處理邏輯。
AIOT_BOOTSTRAPRECV_CONNECTION_INFO 發起裝置分發後,物聯網平台返回的應答報文。 接收的訊息的類型為aiot_bootstrap_recv_t,您需將其中的host和port(即裝置接入的網域名稱和連接埠號碼)儲存至本地。
範例程式碼僅將接收的裝置分發訊息,做列印處理。
AIOT_BOOTSTRAPRECV_NOTIFY 物聯網平台下發的裝置分發通知訊息。 在物聯網平台執行裝置分發操作後,向裝置推送裝置分發訊息。具體操作,請參見物聯網平台的裝置分發。
範例程式碼僅做列印處理,您需編寫處理邏輯,將裝置斷開後,在裝置端重新發起裝置分發請求,建立串連。
void demo_bootstrap_recv_handler(void *handle, const aiot_bootstrap_recv_t *packet, void *userdata) { demo_info_t *demo_info = (demo_info_t *)userdata; switch (packet->type) { case AIOT_BOOTSTRAPRECV_STATUS_CODE: { demo_info->code = packet->data.status_code.code; } break; case AIOT_BOOTSTRAPRECV_CONNECTION_INFO: { demo_info->host = malloc(strlen(packet->data.connection_info.host) + 1); if (demo_info->host != NULL) { memset(demo_info->host, 0, strlen(packet->data.connection_info.host) + 1); /* TODO: 回調中,將裝置分發訊息內容儲存指定位置, 這些空間就會被SDK釋放 */ memcpy(demo_info->host, packet->data.connection_info.host, strlen(packet->data.connection_info.host)); demo_info->port = packet->data.connection_info.port; } } break; case AIOT_BOOTSTRAPRECV_NOTIFY: { printf("AIOT_BOOTSTRAPRECV_NOTIFY, cmd: %d\n", packet->data.notify.cmd); } default: { } break; } }
(可選)步驟五:建立MQTT串連
擷取裝置所需的接入網域名稱和連接埠號碼後,裝置與物聯網平台建立MQTT串連。MQTT接入的詳細說明,請參見MQTT接入。
MQTT串連建立後,您可以參照以下步驟,再次實現裝置分發。
- 調用aiot_bootstrap_setopt,關聯MQTT串連的控制代碼。
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_MQTT_HANDLE, (void *)mqtt_handle);
配置項 樣本 說明 AIOT_BOOTSTRAPOPT_MQTT_HANDLE mqtt_handle 當裝置接收到物聯網平台下推的裝置分發訊息,觸發該回呼函數。
- 登入物聯網平台,執行裝置分發操作。具體操作,請參見物聯網平台的裝置分發。
- 裝置端接收到下推的裝置分發訊息後,裝置下線。然後,重新參照步驟一至步驟四,擷取裝置接入網域名稱,將裝置重新接入物聯網平台。
步驟六:退出程式
調用aiot_bootstrap_deinit,銷毀Bootstrap
res = aiot_bootstrap_deinit(&bootstrap_handle);
if (res < 0) {
printf("demo_start_stop failed\n");
return -1;
}