裝置認證分為一機一密和一型一密兩種方式,本文介紹這兩種方式的使用情境。
認證方式
一機一密:在裝置上燒寫裝置的ProductKey、DeviceName、DeviceSecret,然後適配相應的HAL並調用SDK提供的函數串連物聯網平台。這種方式要求對裝置的產線工具進行一定的修改,需要對每個裝置燒寫不同的DeviceName和DeviceSecret。
一型一密:裝置上燒寫裝置的ProductKey、ProductSecret,每個裝置需要具備自己的唯一標識並將該標識預先上傳到阿里雲物聯網平台,然後調用SDK提供的函數串連雲端。這種方式每個裝置上燒寫的資訊是固定的ProductKey和ProductSecret。
擷取Link SDK
不同版本的Link SDK下載,請參見SDK擷取。
一機一密編程
需要根據不用版本的Link SDK設定裝置認證資訊。- 在Link SDK v3.0.1中,需要實現下文認證資訊的配置:
- HAL_GetProductKey
- HAL_GetDeviceName
- HAL_GetDeviceSecret
- 在Link SDK v3.1.0/v3.2.0中,通過IOT_Ioctl設定認證資訊:
- IOT_Ioctl(IOTX_IOCTL_SET_PRODUCT_KEY, g_product_key)
- IOT_Ioctl(IOTX_IOCTL_SET_DEVICE_NAME, g_device_name)
- IOT_Ioctl(IOTX_IOCTL_SET_DEVICE_SECRET, g_device_secret)
以Link SDK v3.0.1版本為例,IOT_MQTT_Construct()會調用HAL_GetProductKey()等三個HAL函數去擷取裝置的身份資訊,樣本檔案參考
src\mqtt\examples\mqtt_example.c
,代碼如下:int main(int argc, char *argv[])
{
void *pclient = NULL;
int res = 0;
int loop_cnt = 0;
iotx_mqtt_param_t mqtt_params;
memset(&mqtt_params, 0x0, sizeof(mqtt_params));
mqtt_params.handle_event.h_fp = example_event_handle;
pclient = IOT_MQTT_Construct(&mqtt_params);
if (NULL == pclient) {
EXAMPLE_TRACE("MQTT construct failed");
return -1;
}
...
}
一型一密編程
一型一密認證方法使用的流程示意圖:
實現流程簡述:
- 裝置使用ProductKey、ProductSecret和DeviceName到阿里雲物聯網平台擷取該裝置對應的DeviceSecret。
- 物聯網平台的動態註冊服務將尋找該裝置的DeviceName是否在該ProductKey對應的裝置列表,如果該裝置在列表中則返回該裝置的DeviceSecret。
- 裝置收到DeviceSecret之後,將使用一機一密的方式計算MQTT串連參數以及簽名。
- 裝置使用計算出來的MQTT串連參數串連物聯網平台。
重要
- 您需要將擷取的DeviceSecret持久化到裝置,以備後續使用。若擷取的DeviceSecret丟失可能導致裝置無法上線等嚴重後果,物聯網平台不接受已啟用裝置重複的動態註冊請求。
- 使用一型一密功能,您必須對每個裝置進行預註冊,即在阿里雲物聯網平台的控制台上傳每個裝置的DeviceName,並且在控制台上開啟對應產品的動態註冊功能。
實現流程簡述步驟中涉及的API如下:
- 第1步和第2步對應使用者介面:
IOT_Dynamic_Register()
。 - 第3步對應使用者介面:
IOT_Sign_MQTT()
。 - 第4步對應使用者介面:
IOT_MQTT_Construct()
。
說明
- 當裝置擷取到DeviceSecret之後再次調用
IOT_Dynamic_Register()
將會返回失敗,因此使用者編程時擷取到DeviceSecret之後需要將其儲存到裝置本地的儲存介質中。 - 您的程式在調用
IOT_Dynamic_Register()
之前應該先調用HAL_GetDeviceSecret()
查看裝置是否已經擷取到了DeviceSecret,如果已經擷取到,則無需再次調用IOT_Dynamic_Register()
。 - 詳細參數內容,請參見功能API介面。
案例說明
以Link SDK v3.0.1版本為例,一型一密功能的案常式序參考src/dynamic_register/examples/dynreg_example.c
檔案。
下文對其進行逐段講解:
- 使用一型一密功能,需要包含其標頭檔
dynreg_api.h
:#include <stdio.h> #include <string.h> #include "infra_types.h" #include "infra_defs.h" #include "dynreg_api.h"
- 準備輸入參數
region
和出入參結構體meta
:iotx_http_region_types_t region = IOTX_HTTP_REGION_SHANGHAI; HAL_Printf("dynreg example\n"); memset(&meta,0,sizeof(iotx_dev_meta_info_t)); HAL_GetProductKey(meta.product_key); HAL_GetProductSecret(meta.product_secret); HAL_GetDeviceName(meta.device_name);
說明- 入參
region = IOTX_CLOUD_REGION_SHANGHAI
表示用華東2(上海)作為示範串連網站的情境,您可根據自身需要替換為您的使用網站,詳細資料,請參見地區和可用性區域。 - 入參
meta
表示從本地擷取的ProductKey、ProductSecret和DeviceName。
- 入參
- 調用一型一密的
IOT_Dynamic_Register()
介面擷取DeviceSecret,此介面是一型一密功能點唯一提供的使用者介面,若執行成功,在參數meta
中將填上從物聯網平台成功擷取到的DeviceSecret。res = IOT_Dynamic_Register(region, &meta); if (res < 0) { HAL_Printf("IOT_Dynamic_Register failed\n"); return -1; } HAL_Printf("\nDevice Secret: %s\n\n", meta.device_secret);
功能API介面
IOT_Dynamic_Register
- 原型:
int32_t IOT_Dynamic_Register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta);
- 介面說明:根據輸入參數中指定的網站地區,以及ProductKey和ProductSecret,請求物聯網平台為DeviceName指定的裝置申請DeviceSecret。
- 參數說明:
參數 資料類型 方向 說明 region iotx_http_region_types_t 輸入 裝置將要工作的地區,例如華東2(上海)、亞太地區東北1(東京)、美國西部1(矽谷)、亞太地區東南1(新加坡)等,完整內容,請參見地區和可用性區域。 meta iotx_dev_meta_info_t * 輸入輸出 輸入的時候帶入裝置的ProductKey、ProductSecret和DeviceName,輸出的時候返回從物聯網平台擷取到的DeviceSecret。 - 返回結果:
返回結果 說明 =0 請求成功。 <0 請求失敗。
IOT_MQTT_Construct
- 原型:
void *IOT_MQTT_Construct(iotx_mqtt_param_t *pInitParams);
- 介面說明:初始化MQTT建連參數,建立MQTT串連。
- 參數說明:
參數 資料類型 方向 說明 pInitParams iotx_mqtt_param_t * 輸入 MQTT建連參數。 - 返回結果:
返回結果 說明 非Null 物件 請求成功。 NULL(Null 物件) 請求失敗。
IOT_Sign_MQTT
- 原型:
int32_t IOT_Sign_MQTT(iotx_mqtt_region_types_t region, iotx_dev_meta_info_t *meta, iotx_sign_mqtt_t *signout)
- 介面說明:計算MQTT簽名。
- 參數說明:
參數 資料類型 方向 說明 region iotx_http_region_types_t 輸入 裝置所屬的地區。 meta iotx_dev_meta_info_t * 輸入 簽名所需的資訊,存放裝置的標識字串,包括ProductKey、DeviceName等。 signout iotx_sign_mqtt_t * 輸出 簽名結果,包括username、password、clientid、hostname等。 - 返回結果:
返回結果 說明 =0 請求成功。 <0 請求失敗。