設(shè)備證書是生活物聯(lián)網(wǎng)為設(shè)備頒發(fā)的唯一身份憑證。為了快速從下載的設(shè)備證書文件(CSV格式)中讀取每條設(shè)備證書信息,并燒寫到產(chǎn)線上的設(shè)備中,生活物聯(lián)網(wǎng)平臺提供設(shè)備證書分發(fā)工具來幫助您完成CSV文件讀取及分發(fā)工作。您可以根據(jù)本文檔改造您的產(chǎn)線,提高量產(chǎn)效率。

方案介紹

生活物聯(lián)網(wǎng)平臺提供設(shè)備證書分發(fā)工具的方案原理圖如下。

jt13

生活物聯(lián)網(wǎng)的設(shè)備身份分發(fā)工具采用Server-Client架構(gòu),Server與Client交互流程圖如下所示。

jt14
  • Server:由生活物聯(lián)網(wǎng)平臺提供,您下載后可直接使用。

    您可以使用生活物聯(lián)網(wǎng)平臺提供的NodeJS SDK(參見本文檔下方Sever端工具使用章節(jié)),來驗證Server端鏈路是否正常。

  • Client:部署在產(chǎn)線燒錄儀器或集成到產(chǎn)品固件中(兩者對比如下表所示),需要您自行開發(fā)。

    為了方便您快速集成Client,生活物聯(lián)網(wǎng)平臺提供了C SDK供您參考(參見本文檔下方使用C SDK開發(fā)Client章節(jié))。 您集成C SDK后,再自行集成燒錄設(shè)備證書的方式到Client中。

    Client部署方式 適用場景 描述 特點
    集成到設(shè)備固件中 產(chǎn)線上沒有用于將設(shè)備證書燒寫到芯片/設(shè)備的儀器。 該方案設(shè)備上電后,Client向Server申請身份信息,Client獲取到設(shè)備證書后將這些信息寫入設(shè)備的NVRAM和Flash。

    該方案您需要實現(xiàn)以下內(nèi)容:

    • 設(shè)計如何觸發(fā)Client去獲取設(shè)備證書的功能。
    • Client獲取設(shè)備證書后,需要實現(xiàn)將信息寫入NVRAM和Flash的操作。
    • 產(chǎn)線無需部署專門用于燒寫設(shè)備證書的儀器。
    • 設(shè)備需要實現(xiàn)Client的功能,因此會占用設(shè)備的部分存儲空間。
    • 可以實現(xiàn)批量進(jìn)行身份信息獲取。
    部署在產(chǎn)線燒錄儀器上 產(chǎn)線上存在將設(shè)備證書燒寫到芯片/設(shè)備的儀器,如燒錄器或編程器等。 該方案由燒錄軟件實現(xiàn)Client的功能向Server申請身份信息,取得設(shè)備證書后,通過燒錄器和編程器寫入設(shè)備的NVRAM和Flash。

    阿里云物聯(lián)網(wǎng)提供了產(chǎn)線分發(fā)App的通信協(xié)議,該方案您需要修改產(chǎn)線燒寫工具按照該通信協(xié)議從產(chǎn)線分發(fā)App獲取設(shè)備證書。

    • 設(shè)備無需實現(xiàn)Client的功能,不會為了獲取身份信息功能消耗存儲空間。
    • 您需要對燒錄器/編程器進(jìn)行軟件改造。
    • 可以根據(jù)產(chǎn)線上的生產(chǎn)設(shè)備數(shù)量、規(guī)模,配置燒錄器/編程器的數(shù)量。

Server-Client協(xié)議說明

Client與Server采用HTTP接口通訊,Client通過POST方法向Server發(fā)送請求,請求協(xié)議以JSON方式放在body里。

表 1. 請求協(xié)議格式與參數(shù)說明
字段 類型 是否必選 描述
ProductKey string 產(chǎn)品標(biāo)識(生活物聯(lián)網(wǎng)后臺新建產(chǎn)品時生成)
DeviceID string 設(shè)備ID,唯一標(biāo)識
Action Integer 操作
  • 0:請求分配設(shè)備證書
  • 1:上傳燒錄成功
  • 2:上傳燒錄失敗

請求與響應(yīng)數(shù)據(jù)示例如下。

  • Client向Server申請設(shè)備證書請求數(shù)據(jù)
    {
        "ProductKey":"a1xxxxNW",
        "DeviceID":"AAxxxx22",
        "Action":0
    }
  • Server向Client分發(fā)設(shè)備證書數(shù)據(jù)
    {
        "ProductKey":"a1xxxxNW",
        "ProductSecret":"XmDxxxx9R",
        "DeviceSecret":"NmMExxxxjE5",
        "CRC32":"B5488744",     //CRC32介紹參見下方文檔
        "DeviceName":"ZTMxxxxxkUy",
          "DeviceID":"AABxxxx22",
          "Status":"OK"
    }
  • 燒錄成功狀態(tài)更新請求
    {
        "ProductKey":"a1xxxxW",
        "DeviceID":"AAxxxx22",
        "Action":1
    }
  • 燒錄成功狀態(tài)更新返回數(shù)據(jù)
    {
        "ProductKey": "a1xxxxNW",
        "DeviceID": "AAxxxx22",
        "Status": "OK"
    }

Server分發(fā)設(shè)備證書給Client的數(shù)據(jù)中使用的校驗算法采用標(biāo)準(zhǔn)CRC32(CRC32計算工具網(wǎng)址),多項式為04C11DB7,初始值與結(jié)果異或值均為FFFFFFFF,輸入與輸出均取反。校驗payload為設(shè)備憑證(WiFi類設(shè)備為ProductKey、ProductSecret、DeviceName、DeviceSecret;藍(lán)牙類設(shè)備為ProductKey、ProductSecret、DeviceName、DeviceSecret、ProductID)。校驗結(jié)果為4字節(jié)十六進(jìn)制。

CRC32計算結(jié)果校驗工具使用方法的示例如下。

jt14
  • Java代碼參考實現(xiàn)
    import java.nio.ByteBuffer;
    import java.util.zip.CRC32;
    
    public class example {
    
    public static void main(String[] args){
    
        ///this is user supplied string
        String pk  = "a1xxxxH";
        String dn  = "8jQxxxx0WW6";
        String ds  = "aW60ImxxxxIj61ZbV";
        String ps  = "EBcjxxxxWxdF";
    
        if ( args.length >= 4) {
            pk = args[0];
            dn = args[1];
            ds = args[2];
            ps = args[3];
        }
    
        String payload = pk + dn + ds + ps;
        ByteBuffer bbuffer = ByteBuffer.allocate(payload.length());
        bbuffer.put(payload.getBytes());
    
        //your crc class
        CRC32 crc = new CRC32();
        crc.update(bbuffer.array());
        String enc = Long.toHexString(crc.getValue()).toUpperCase();
        System.out.println("payload: " + payload);
        System.out.println("length: " + Integer.toString(payload.length()));
        System.out.println("crc32: " + enc);
        }
    }
  • Python代碼參考實現(xiàn)
    import zlib
    
    pk  = "a2xxxx8HZ"
    dn  = "ouxxxxemo"
    ds  = "GD4JauYxxxxsICazhIzb"
    ps  = "4I3xxxxyF96"
    
    def Crc32Hash(input_data):
    
        crc32 = 0
        crc32 = zlib.crc32(input_data, crc32)
    
        return format(crc32 & 0xFFFFFFFF, '08X')
    
    payload = pk + dn + ds + ps
    print "payload: ", payload
    print "length: ", len(payload)
    print "crc32: ", Crc32Hash(payload)
  • 設(shè)備端參考代碼
    #define CHIP_CPU_BE
    
    #define dwPolynomial_BE            0xEDB88320UL      //CRC32 Polynomial
    #define dwPolynomial               0x04C11DB7UL      //CRC32 Polynomial
    #if defined(CHIP_CPU_BE)
    #define dwPolynomial               dwPolynomial_BE
    #else
    #define dwPolynomial               dwPolynomial_LE
    #endif
    #define CRC_INIT_VALUE             0xFFFFFFFFUL
    
    unsigned int calc_crc32(unsigned char *message) {
       int i, j;
       unsigned int byte, crc, mask;
    
       i = 0;
       crc = CRC_INIT_VALUE;
       while (message[i] != 0) {
          byte = message[i];            // Get next byte.
          crc = crc ^ byte;
          for (j = 7; j >= 0; j--) {    // Do eight times.
             mask = -(crc & 1);
             crc = (crc >> 1) ^ (dwPolynomial_BE & mask);
          }
          i = i + 1;
       }
       return ~crc;
    }

Sever端工具使用

Server端由設(shè)備證書分發(fā)和設(shè)備證書管理兩部分組成。

  1. 下載設(shè)備證書的工具
  2. 啟動設(shè)備證書分發(fā)服務(wù)。
    1. 解壓下載的ZIP文件,并雙擊server目錄下的http_server.exe,來啟動分發(fā)服務(wù)。
      出現(xiàn)以下消息時,表示分發(fā)服務(wù)啟動成功。
      Waiting for client request
      說明 當(dāng)前版本還未做成系統(tǒng)服務(wù),啟動后請您不要關(guān)閉窗口。
    2. (可選)修改端口號。
      分發(fā)服務(wù)默認(rèn)采用的端口號為8000,若需要更改端口請執(zhí)行以下命令修改(以修改成50000為例)。
      http_server.exe 50000
  3. 管理產(chǎn)品批次,并導(dǎo)入設(shè)備證書。
    1. 雙擊server目錄下的factory.exe,啟動管理工具。
    2. 單擊添加設(shè)備
      jt17
    3. 配置產(chǎn)品批次及產(chǎn)品信息,并單擊選擇設(shè)備身份文件,選擇從生活物聯(lián)網(wǎng)后臺下載的設(shè)備身份文件。
      jt18
      說明 若身份文件帶ProductSecret字段,程序會自動讀取并以身份文件中的內(nèi)容為準(zhǔn)。
    4. 單擊添加設(shè)備按鈕。
      導(dǎo)入完成之后會彈出消息提示導(dǎo)入的詳細(xì)信息。jt19
  4. 查詢產(chǎn)品信息。
    1. 單擊設(shè)備查詢,并在DeviceName輸入框中輸入待查詢的產(chǎn)品名稱。
    2. 單擊查詢

      此時顯示設(shè)備的詳細(xì)信息。

      jt20

(可選)使用NodeJS SDK驗證Server

在設(shè)備證書分發(fā)工具中提供了NodeJS SDK參考實現(xiàn),您可以使用NodeJS SDK來驗證Server獲取設(shè)備證書的鏈路是否正常。

請您根據(jù)以下步驟開發(fā)并運行示例代碼。

  1. 下載設(shè)備證書分發(fā)工具
    client\NodeJS目錄下查看NodeJS SDK的相關(guān)文件,文件說明如下。
    • test.js:是一個示例文件,該文件調(diào)用devReqCert.js獲取設(shè)備證書。
    • devReqCert.js:提供req_dev_cert()send_burn_result_by_did()兩個函數(shù)。函數(shù)說明如下。
      • req_dev_cert('ip',"pk",id,callback)

        向指定的Server申請設(shè)備證書。函數(shù)中參數(shù)說明如下。

        參數(shù) 類型 描述
        ip String Server的IP地址或者域名。
        pk String 設(shè)備希望申請的身份信息對應(yīng)的產(chǎn)品型號,該參數(shù)對應(yīng)阿里云IoT平臺上產(chǎn)品的ProductKey。
        id String 設(shè)備的唯一標(biāo)識,可以是MAC地址、SN,只要是設(shè)備唯一的即可。
        • 如果使用同樣的ID申請,Server將會返回相同的設(shè)備證書。
        • 若ID值為null,表示設(shè)備希望分配一個新的身份信息。
        callback function 當(dāng)Server返回設(shè)備證書后調(diào)用的回調(diào)函數(shù),用于保存設(shè)備證書。設(shè)備證書該函數(shù)需要由您自行實現(xiàn)。
      • send_burn_result_by_did('ip',"pk","id")

        向指定的Server發(fā)送設(shè)備身份信息燒寫結(jié)果,Server收到Client發(fā)送的燒寫結(jié)果后,將會把對應(yīng)設(shè)備的身份信息狀態(tài)從已分配修改為已燒寫。函數(shù)中參數(shù)說明如下。

        參數(shù) 類型 描述
        ip String Server的IP地址或者域名
        pk String 設(shè)備希望申請的身份信息對應(yīng)的產(chǎn)品型號,該參數(shù)對應(yīng)阿里云IoT平臺上產(chǎn)品的ProductKey
        id String 設(shè)備的唯一標(biāo)識,可以是MAC地址、SN,只要是設(shè)備唯一的即可
        • 如果使用同樣的ID申請,Server將會返回相同的設(shè)備證書
        • 若ID值為null,表示設(shè)備希望分配一個新的身份信息
  2. 開發(fā)示例代碼。

    基于文件“test.js”進(jìn)行示例代碼說明。

    var http = require('http'); // 引入對HTTP庫的依賴
    var devReq = require('./devReqCert');  //引入對devReqCert的依賴
    
    var did = null;
    
    //下面的函數(shù)handler是Client收到Server分配的設(shè)備證書后的處理函數(shù),
    //在本示例代碼中僅僅將設(shè)備的身份信息進(jìn)行打印輸出,
    //實際產(chǎn)品生產(chǎn)時需要將設(shè)備的身份信息進(jìn)行持久化保存
    function handler(devInfo)
    {
        var jsonObj = JSON.parse(devInfo);
        console.log("DevInfo:" + devInfo);
    }
    
    //下面的語句調(diào)用req_dev_cert獲取設(shè)備的身份信息,其中
    //“127.0.0.1”是Server的IP地址,本測試中Server和Client在同一臺PC上,所以使用了127.0.0.1地址
    //參數(shù)"a1RxxxxBm9"是設(shè)備希望分配身份信息對應(yīng)的ProductKey
    //null表示設(shè)備沒有唯一標(biāo)識,希望Server分配一個新的設(shè)備身份
    devReq.req_dev_cert('127.0.0.1',"a1RxxxxBm9",null, handler);
    
    //下面的代碼設(shè)置了設(shè)備的唯一標(biāo)識,并再次申請設(shè)備的唯一標(biāo)識
    did = "123456";
    devReq.req_dev_cert('127.0.0.1',"a1RxxxxBm9",did,handler);
                            
  3. 在運行的PC或Client的設(shè)備上部署NodeJS環(huán)境。
  4. 進(jìn)入產(chǎn)線分發(fā)工具的NodeJS目錄,并運行node test.js

    輸出的內(nèi)容如下所示則Server獲取設(shè)備證書鏈路正常。其中DeviceName、ProductKey、ProductSecret、DeviceSecret是阿里云IoT平臺為設(shè)備分配的設(shè)備證書,DeviceID是設(shè)備申請設(shè)備身份時傳入的設(shè)備標(biāo)識。

    jt14

使用C SDK開發(fā)Client

設(shè)備獲取身份信息的功能,可采用以下兩種實現(xiàn)方式。

  • 產(chǎn)線上將設(shè)備的某個GPIO作為輸入接口,將其拉高或者拉低,當(dāng)設(shè)備上電運行時發(fā)現(xiàn)該GPIO為高或低時,自動連接某個固定的WiFi AP,然后從Server(Server的IP地址需要固定)去申請設(shè)備證書。
  • 設(shè)備上電后檢查是否有設(shè)備身份,如沒有設(shè)備身份信息,則自動連接到一個固定的產(chǎn)線AP(AP的SSID和密碼由您自行定義)。此時請參照設(shè)備證書分發(fā)工具提供的C-SDK(調(diào)用get_triple)去申請設(shè)備身份。

請您根據(jù)以下步驟基于示例代碼開發(fā)Client。

  1. 下載設(shè)備證書分發(fā)工具
    client\C-SDK目錄下查看C SDK的相關(guān)文件,文件說明如下。
    • triple_burn.c:用來存放SDK代碼。
    • triple_burn.h:頭文件,包含send_req()parse_data()兩個函數(shù)(說明如下)。
      • char* send_req(act, pk, did, const server_ip)

        向指定的Server申請設(shè)備證書,或發(fā)送設(shè)備證書燒寫結(jié)果設(shè)備證書。其中參數(shù)說明如下。

        參數(shù) 類型 描述
        act Int
        • 0:Client向Server請求設(shè)備身份
        • 1:Client告知Server設(shè)備身份寫入成功
        pk char * 設(shè)備希望申請的身份信息對應(yīng)的產(chǎn)品型號,該參數(shù)對應(yīng)阿里云IoT平臺上產(chǎn)品的ProductKey
        did char * 設(shè)備的唯一標(biāo)識,可以是MAC地址、SN等唯一的設(shè)備標(biāo)識

        特殊情況說明:

        • 使用同樣的ID申請,Server將返回相同的設(shè)備證書
        • 設(shè)備不具備唯一的標(biāo)識,可傳入空字符串,但請謹(jǐn)慎操作,可能會造成設(shè)備證書浪費
        server_ip char * Server服務(wù)所在設(shè)備的IP地址

        Server返回的設(shè)備身份,格式為JSON。若為NULL表示申請身份失敗。

      • int parse_data(const data, pk, dn, ps, ds, did)

        該函數(shù)用于解析從Server返回的JSON字符串,并獲取其中的ProductKey、ProductSecret、DeviceName、DeviceSecret、DeviceID(如果您還需在Server處為每個設(shè)備增加其它的配置信息,可自行修改本函數(shù))。

        參數(shù) 類型 描述
        data char * 函數(shù)send_req()從Server獲取到的設(shè)備證書。
        pk char * 設(shè)備的產(chǎn)品型號,該參數(shù)對應(yīng)阿里云IoT平臺上產(chǎn)品的ProductKey。
        dn char * 設(shè)備的名稱,該參數(shù)對應(yīng)阿里云IoT平臺上設(shè)備的DeviceName。
        ps char * 該參數(shù)對應(yīng)阿里云IoT平臺上設(shè)備的ProductSecret。
        ds char * 該參數(shù)對應(yīng)阿里云IoT平臺上設(shè)備的DeviceSecret。
        did char * 設(shè)備的唯一標(biāo)識,可以是MAC地址、SN等唯一的設(shè)備標(biāo)識。

        特殊情況說明:

        • 使用同樣的ID申請,Server將返回相同的設(shè)備證書。
        • 設(shè)備不具備唯一的標(biāo)識,可傳入空字符串,但請謹(jǐn)慎操作,可能會造成設(shè)備證書浪費。
        server_ip char * Server服務(wù)所在設(shè)備的IP地址。

        調(diào)用該函數(shù)的返回值說明如下。

        • 0:解析成功
        • 非0:無效數(shù)據(jù)
  2. 開發(fā)get_triple()函數(shù)。

    通過C SDK去獲取某個已集成生活物聯(lián)網(wǎng)SDK的設(shè)備證書為示例,請您根據(jù)以下步驟開發(fā)示例代碼。

    1. 確保設(shè)備已經(jīng)通過DHCP正確地獲取了IP地址。
    2. 調(diào)用HAL_Wifi_Get_IP()獲取設(shè)備的IP地址。
    3. 調(diào)用send_req()獲取設(shè)備證書。
      若未獲取到數(shù)據(jù),會自動再請求一次(若仍然未獲取到數(shù)據(jù),后續(xù)業(yè)務(wù)邏輯您需根據(jù)業(yè)務(wù)自行實現(xiàn))。
    4. 調(diào)用parse_data()解析數(shù)據(jù)。
      數(shù)據(jù)解析成功,將獲得設(shè)備的ProductKey、ProductSecret、DeviceName,DeviceSecret。

      示例中僅對設(shè)備證書進(jìn)行打印輸出(以下代碼中LOG中所示),您開發(fā)時需要將這些信息存儲到Flash/NVRAM中。

      
      static void get_triple(char* server_ip, char* productKey, char* deviceid){
          char ip_addr[16] = {0};
          char pk[PRODUCT_KEY_LEN] = {0};
          char dn[DEVICE_NAME_LEN] = {0};
          char ds[DEVICE_SECRET_LEN] = {0};
          char ps[PRODUCT_SECRET_LEN] = {0};
          char did[PRODUCT_SECRET_LEN] = {0};
      
          HAL_Wifi_Get_IP(ip_addr, 0);
          if (strlen(ip_addr) > 5){
              LOG("wifi_service_event ip=%s", ip_addr);
              char *response_payload = send_req(0, productKey, deviceid, server_ip);
              if (strlen(response_payload) == 0){
                  if (response_payload != NULL)
                      HAL_Free(response_payload);
                  response_payload = send_req(0, productKey, deviceid, server_ip);
              }
              if( response_payload != NULL && 0 == parse_data(response_payload, pk, dn, ps, ds, did)){
                  HAL_Free(response_payload);
                  LOG("triple:pk=%s dn=%s ds=%s ps=%s did=%s", pk,dn,ds,ps,did);
                  // write pk,dn,ds,ps to falsh
      
                  // send write success to server
                  HAL_Free(send_req(1, productKey, did, server_ip));
              } else {
                  if (response_payload != NULL)
                      HAL_Free(response_payload);
              }
          }
    5. 再次調(diào)用send_req(),告知Server已成功保存設(shè)備證書。
  3. 集成Client SDK示例代碼。
    以下集成基于已發(fā)布的生活物聯(lián)網(wǎng)平臺SDK。獲取生活物聯(lián)網(wǎng)平臺SDK,請參見獲取SDK

    以下基于living_platform為例開發(fā)。若您基于其他應(yīng)用開發(fā),需調(diào)整相應(yīng)的路徑。

    1. Product/example/living_platfrom/living_platfrom.mk中,新增triple_burn.c文件。
    2. app_entry.c文件中增加include triple_burn.h
      #if defined(OTA_ENABLED) && defined(BUILD_AOS)
      #include "ota_service.h"
      #endif
      
      #include "triple_burn.h"  //triple_burn.h為頭文件
      
      #include <aos/network.h>
    3. get_triple放在living_platform應(yīng)用的app_entry.c文件中。
    4. 參照以下示例代碼,實現(xiàn)在handle_linkkey_cmd()中調(diào)用get_triple()來獲取設(shè)備證書。
      更多代碼可以參見client\C-SDK\app_entry.c文件。
      static void handle_linkkey_cmd(char *pwbuf, int blen, int argc, char **argv)
      {
          if (argc == 1)
          {
              int len = 0;
              char product_key[PRODUCT_KEY_LEN + 1] = {0};
              char product_secret[PRODUCT_SECRET_LEN + 1] = {0};
              char device_name[DEVICE_NAME_LEN + 1] = {0};
              char device_secret[DEVICE_SECRET_LEN + 1] = { 0 };
      
              len = PRODUCT_KEY_LEN+1;
              aos_kv_get("linkkit_product_key", product_key, &len);
      
              len = PRODUCT_SECRET_LEN+1;
              aos_kv_get("linkkit_product_secret", product_secret, &len);
      
              len = DEVICE_NAME_LEN+1;
              aos_kv_get("linkkit_device_name", device_name, &len);
      
              len = DEVICE_SECRET_LEN+1;
              aos_kv_get("linkkit_device_secret", device_secret, &len);
      
              aos_cli_printf("Product Key=%s.\r\n", product_key);
              aos_cli_printf("Device Name=%s.\r\n", device_name);
              aos_cli_printf("Device Secret=%s.\r\n", device_secret);
              aos_cli_printf("Product Secret=%s.\r\n", product_secret);
      
          }
          else if (argc == 5)
          {
              aos_kv_set("linkkit_product_key", argv[1], strlen(argv[1]) + 1, 1);
              aos_kv_set("linkkit_device_name", argv[2], strlen(argv[2]) + 1, 1);
              aos_kv_set("linkkit_device_secret", argv[3], strlen(argv[3]) + 1, 1);
              aos_kv_set("linkkit_product_secret", argv[4], strlen(argv[4]) + 1, 1);
      
              aos_cli_printf("Done");
      
          }
          else if (argc == 4){
              get_triple(argv[1], argv[2], argv[3]);
          }
          else if (argc == 3){
              get_triple(argv[1], argv[2], "");
          }
          else
          {
              aos_cli_printf("Error: %d\r\n", __LINE__);
              return;
          }
      }
    5. 配置設(shè)備批量配網(wǎng)能力。
      該能力可以讓沒有WiFi熱點信息的WiFi設(shè)備,自動連接到廠測路由器,詳細(xì)操作請參見SDK新增功能介紹
    6. 編譯固件并燒錄到設(shè)備。
  4. 調(diào)試示例代碼。
    設(shè)備燒寫包含以上代碼的固件后,在串口終端輸入以下命令進(jìn)行測試。
    • 攜帶DeviceID申請設(shè)備證書
      linkkey ServerIP productKey DID
      //ServerIP是實際環(huán)境中Server的IP地址,productKey是產(chǎn)品的ProductKey的值
      //DID是設(shè)備的唯一標(biāo)識,唯一標(biāo)識可以是設(shè)備MAC地址、序列號等可以唯一標(biāo)識設(shè)備的值
    • 不攜帶DeviceID申請設(shè)備證書(該情況請謹(jǐn)慎操作,可能會造成設(shè)備證書浪費)
      linkkey ServerIP productKey
      //ServerIP在運行時需要輸入Server在實際環(huán)境中的IP地址,productKey是您產(chǎn)品的ProductKey的值

    若設(shè)備成功從Server取到數(shù)據(jù),會得到類似以下的日志。

    resp={"CRC32":3041429316,"ProductKey":"a1xxxxNW",
    "DeviceName":"ZTMxxxxxTUy",
    "DeviceSecret":"NmMzxxxxjE5",
    "ProductSecret":"Xmxxxxb9R","Status":"OK"}.