{"id":353,"date":"2021-06-28T03:14:49","date_gmt":"2021-06-27T19:14:49","guid":{"rendered":"https:\/\/www.iotot.com\/?p=353"},"modified":"2022-05-22T11:23:39","modified_gmt":"2022-05-22T03:23:39","slug":"linksdk%e5%9c%a8linux%e7%b3%bb%e7%bb%9f%e4%b8%ad%e4%bd%bf%e7%94%a8ota%e5%8d%87%e7%ba%a7","status":"publish","type":"post","link":"https:\/\/blog.iotot.com\/?p=353","title":{"rendered":"LINKSDK\u5728linux\u7cfb\u7edf\u4e2d\u4f7f\u7528OTA\u5347\u7ea7"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\">\/*\r\n * \u8fd9\u4e2a\u4f8b\u7a0b\u9002\u7528\u4e8e{{EJS0}}\u8fd9\u7c7b\u652f\u6301pthread\u7684POSIX\u8bbe\u5907, \u5b83\u6f14\u793a\u4e86\u7528SDK\u914d\u7f6eMQTT\u53c2\u6570\u5e76\u5efa\u7acb\u8fde\u63a5, \u4e4b\u540e\u521b\u5efa3\u4e2a\u7ebf\u7a0b\r\n *\r\n * + \u4e00\u4e2a\u7ebf\u7a0b\u7528\u4e8e\u4fdd\u6d3b\u957f\u8fde\u63a5\r\n * + \u4e00\u4e2a\u7ebf\u7a0b\u7528\u4e8e\u63a5\u6536\u6d88\u606f, \u5e76\u5728\u6709\u6d88\u606f\u5230\u8fbe\u65f6\u8fdb\u5165\u9ed8\u8ba4\u7684\u6570\u636e\u56de\u8c03, \u5728\u8fde\u63a5\u72b6\u6001\u53d8\u5316\u65f6\u8fdb\u5165\u4e8b\u4ef6\u56de\u8c03\r\n * + \u4e00\u4e2a\u7ebf\u7a0b\u7528\u4e8e\u4ece\u7f51\u7edc\u4e0aHTTP\u4e0b\u8f7d\u5f85\u5347\u7ea7\u7684\u56fa\u4ef6, \u8fd9\u4e2a\u7ebf\u7a0b\u7531\u63a5\u6536\u6d88\u606f\u7ebf\u7a0b\u5f97\u5230OTA\u5347\u7ea7\u7684MQTT\u6d88\u606f\u540e\u542f\u52a8\r\n *\r\n * \u9700\u8981\u7528\u6237\u5173\u6ce8\u6216\u4fee\u6539\u7684\u90e8\u5206, \u5df2\u7528 {{EJS1}} \u5728\u6ce8\u91ca\u4e2d\u6807\u660e\r\n *\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;pthread.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;sys\/types.h&gt;\r\n#include &lt;sys\/stat.h&gt;\r\n#include &lt;fcntl.h&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\n#include &quot;aiot_state_api.h&quot;\r\n#include &quot;aiot_sysdep_api.h&quot;\r\n#include &quot;aiot_ota_api.h&quot;\r\n#include &quot;aiot_mqtt_api.h&quot;\r\n\r\n#include &quot;app.h&quot;\r\n#include &quot;fun.h&quot;\r\n\r\nvoid       *ota_handle = NULL;\r\nchar       *cur_version = NULL;\r\n\r\nint ota_file_size = 0;\r\n\r\n    FILE * fp;\r\n\r\n\/* TODO: \u66ff\u6362\u4e3a\u81ea\u5df1\u8bbe\u5907\u7684\u4e09\u5143\u7ec4 *\/\r\n\/\/char *product_key       = &quot;a1mj7GHuxu2&quot;;\r\n\/\/char *device_name       = &quot;C-AZ-01&quot;;\r\n\/\/char *device_secret     = &quot;4e937154aff09efe513cf67d9c0680fe&quot;;\r\n\r\n#define  VERSTR &quot;1.0.6&quot;\r\n\r\nchar product_key&#091;50];\r\nchar device_name&#091;50];\r\nchar device_secret&#091;100];\r\n\/* \u4f4d\u4e8eportfiles\/aiot_port\u6587\u4ef6\u5939\u4e0b\u7684\u7cfb\u7edf\u9002\u914d\u51fd\u6570\u96c6\u5408 *\/\r\nextern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;\r\n\r\n\/* \u4f4d\u4e8eexternal\/ali_ca_cert.c\u4e2d\u7684\u670d\u52a1\u5668\u8bc1\u4e66 *\/\r\nextern const char *ali_ca_cert;\r\n\r\nstatic pthread_t g_mqtt_process_thread; \/* \u7528\u4e8eMQTT\u7684\u957f\u8fde\u63a5\u4fdd\u6d3b\u7ebf\u7a0b *\/\r\nstatic pthread_t g_mqtt_recv_thread;    \/* \u7528\u4e8eMQTT\u7684\u5faa\u73af\u6536\u6d88\u606f\u7ebf\u7a0b *\/\r\nstatic pthread_t g_download_thread;     \/* \u7528\u4e8eHTTP\u7684\u56fa\u4ef6\u4e0b\u8f7d\u7ebf\u7a0b *\/\r\nstatic pthread_t g_apprun_thread;     \/* \u7528\u4e8eHTTP\u7684\u56fa\u4ef6\u4e0b\u8f7d\u7ebf\u7a0b *\/\r\n\r\nint32_t     res = STATE_SUCCESS;\r\nvoid       *mqtt_handle = NULL;\r\n\r\n\/* TODO: \u5982\u679c\u8981\u5173\u95ed\u65e5\u5fd7, \u5c31\u628a\u8fd9\u4e2a\u51fd\u6570\u5b9e\u73b0\u4e3a\u7a7a, \u5982\u679c\u8981\u51cf\u5c11\u65e5\u5fd7, \u53ef\u6839\u636ecode\u9009\u62e9\u4e0d\u6253\u5370\r\n *\r\n * \u4f8b\u5982: &#091;1578463098.611]&#091;LK-0309] pub: \/ota\/device\/upgrade\/a13FN5TplKq\/ota_demo\r\n *\r\n * \u4e0a\u9762\u8fd9\u6761\u65e5\u5fd7\u7684code\u5c31\u662f0309(\u5341\u516d\u8fdb\u5236), code\u503c\u7684\u5b9a\u4e49\u89c1core\/aiot_state_api.h\r\n *\r\n *\/\r\n\r\n\/* \u65e5\u5fd7\u56de\u8c03\u51fd\u6570, SDK\u7684\u65e5\u5fd7\u4f1a\u4ece\u8fd9\u91cc\u8f93\u51fa *\/\r\nint32_t demo_state_logcb(int32_t code, char *message)\r\n{\r\n    \/* \u4e0b\u8f7d\u56fa\u4ef6\u7684\u65f6\u5019\u4f1a\u6709\u5927\u91cf\u7684HTTP\u6536\u5305\u65e5\u5fd7, \u901a\u8fc7code\u7b5b\u9009\u51fa\u6765\u5173\u95ed *\/\r\n    if (STATE_HTTP_LOG_RECV_CONTENT != code) {\r\n        printf(&quot;%s&quot;, message);\r\n    }\r\n    return 0;\r\n}\r\n\r\n\/* \u4e0b\u8f7d\u6536\u5305\u56de\u8c03, \u7528\u6237\u8c03\u7528 aiot_download_recv() \u540e, SDK\u6536\u5230\u6570\u636e\u4f1a\u8fdb\u5165\u8fd9\u4e2a\u51fd\u6570, \u628a\u4e0b\u8f7d\u5230\u7684\u6570\u636e\u4ea4\u7ed9\u7528\u6237 *\/\r\n\/* TODO: \u4e00\u822c\u6765\u8bf4, \u8bbe\u5907\u5347\u7ea7\u65f6, \u4f1a\u5728\u8fd9\u4e2a\u56de\u8c03\u4e2d, \u628a\u4e0b\u8f7d\u5230\u7684\u6570\u636e\u5199\u5230Flash\u4e0a *\/\r\nvoid demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)\r\n{\r\n    uint32_t data_buffer_len = 0;\r\n    uint32_t last_percent = 0;\r\n    int32_t  percent = 0;\r\n\r\n    int fd;\r\n\tint wr_ret;\r\n\r\n\r\n    \/* \u76ee\u524d\u53ea\u652f\u6301 packet-&gt;type \u4e3a AIOT_DLRECV_HTTPBODY \u7684\u60c5\u51b5 *\/\r\n    if (!packet || AIOT_DLRECV_HTTPBODY != packet-&gt;type) {\r\n        return;\r\n    }\r\n    percent = packet-&gt;data.percent;\r\n\r\n    \/* userdata\u53ef\u4ee5\u5b58\u653e demo_download_recv_handler() \u7684\u4e0d\u540c\u6b21\u8fdb\u5165\u4e4b\u95f4, \u9700\u8981\u5171\u4eab\u7684\u6570\u636e *\/\r\n    \/* \u8fd9\u91cc\u7528\u6765\u5b58\u653e\u4e0a\u4e00\u6b21\u8fdb\u5165\u672c\u56de\u8c03\u51fd\u6570\u65f6, \u4e0b\u8f7d\u7684\u56fa\u4ef6\u8fdb\u5ea6\u767e\u5206\u6bd4 *\/\r\n    if (userdata) {\r\n        last_percent = *((uint32_t *)(userdata));\r\n    }\r\n\r\n    data_buffer_len = packet-&gt;data.len;\r\n\r\n    \/* \u5982\u679c percent \u4e3a\u8d1f\u6570, \u8bf4\u660e\u53d1\u751f\u4e86\u6536\u5305\u5f02\u5e38\u6216\u8005digest\u6821\u9a8c\u9519\u8bef *\/\r\n    if (percent &lt; 0) {\r\n        printf(&quot;exception: percent = %drn&quot;, percent);\r\n        if (userdata) {\r\n            free(userdata);\r\n        }\r\n        return;\r\n    }\r\n\r\n    \/*\r\n     * TODO: \u4e0b\u8f7d\u4e00\u6bb5\u56fa\u4ef6\u6210\u529f, \u8fd9\u4e2a\u65f6\u5019, \u7528\u6237\u5e94\u8be5\u5c06\r\n     *       \u8d77\u59cb\u5730\u5740\u4e3a packet-&gt;data.buffer, \u957f\u5ea6\u4e3a packet-&gt;data.len \u7684\u5185\u5b58, \u4fdd\u5b58\u5230flash\u4e0a\r\n     *\r\n     *       \u5982\u679c\u70e7\u5199flash\u5931\u8d25, \u8fd8\u5e94\u8be5\u8c03\u7528 aiot_download_report_progress(handle, -4) \u5c06\u5931\u8d25\u4e0a\u62a5\u7ed9\u4e91\u5e73\u53f0\r\n     *       \u5907\u6ce8:\u534f\u8bae\u4e2d, \u4e0e\u4e91\u5e73\u53f0\u5546\u5b9a\u7684\u9519\u8bef\u7801\u5728 aiot_ota_protocol_errcode_t \u7c7b\u578b\u4e2d, \u4f8b\u5982\r\n     *           -1: \u8868\u793a\u5347\u7ea7\u5931\u8d25\r\n     *           -2: \u8868\u793a\u4e0b\u8f7d\u5931\u8d25\r\n     *           -3: \u8868\u793a\u6821\u9a8c\u5931\u8d25\r\n     *           -4: \u8868\u793a\u70e7\u5199\u5931\u8d25\r\n     *\r\n     *       \u8be6\u60c5\u53ef\u89c1 https:\/\/help.aliyun.com\/document_detail\/85700.html\r\n     *\/\r\n\r\n    \/* percent \u5165\u53c2\u7684\u503c\u4e3a 100 \u65f6, \u8bf4\u660eSDK\u5df2\u7ecf\u4e0b\u8f7d\u56fa\u4ef6\u5185\u5bb9\u5168\u90e8\u5b8c\u6210 *\/\r\n    if (percent == 100) {\r\n        \/\/fd = open(&quot;\/home\/root\/ftp\/Apprun&quot;, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH | O_SYNC | BINARY);\r\n\r\n        \/\/lseek(fd, 0, SEEK_SET);\r\n        \/\/wr_ret = fwrite(fd, packet-&gt;data.buffer, packet-&gt;data.len);\r\n\r\n        \r\n        \/\/fsync(fd);\r\n        \/\/close(fd);\/\/\u5173\u95ed\u6587\u4ef6\r\n        \/\/system(&quot;reboot&quot;);\r\n        \/\/system(&quot;reboot&quot;);\/\/reboot\r\n        \/*\r\n         * TODO: \u8fd9\u4e2a\u65f6\u5019, \u4e00\u822c\u7528\u6237\u5c31\u5e94\u8be5\u5b8c\u6210\u6240\u6709\u7684\u56fa\u4ef6\u70e7\u5f55, \u4fdd\u5b58\u5f53\u524d\u5de5\u4f5c, \u91cd\u542f\u8bbe\u5907, \u5207\u6362\u5230\u65b0\u7684\u56fa\u4ef6\u4e0a\u542f\u52a8\u4e86\r\n                 \u5e76\u4e14, \u65b0\u7684\u56fa\u4ef6\u5fc5\u987b\u8981\u4ee5\r\n\r\n                 aiot_ota_report_version(ota_handle, new_version);\r\n\r\n                 \u8fd9\u6837\u7684\u64cd\u4f5c, \u5c06\u5347\u7ea7\u540e\u7684\u65b0\u7248\u672c\u53f7(\u6bd4\u59821.0.0\u5347\u52301.1.0, \u5219new_version\u7684\u503c\u662f&quot;1.1.0&quot;)\u4e0a\u62a5\u7ed9\u4e91\u5e73\u53f0\r\n                 \u4e91\u5e73\u53f0\u6536\u5230\u4e86\u65b0\u7684\u7248\u672c\u53f7\u4e0a\u62a5\u540e, \u624d\u4f1a\u5224\u5b9a\u5347\u7ea7\u6210\u529f, \u5426\u5219\u4f1a\u8ba4\u4e3a\u672c\u6b21\u5347\u7ea7\u5931\u8d25\u4e86\r\n                 \u5982\u679c\u4e0b\u8f7d\u6210\u529f\u540e\u5347\u7ea7\u5931\u8d25, \u8fd8\u5e94\u8be5\u8c03\u7528 aiot_download_report_progress(handle, -1) \u5c06\u5931\u8d25\u4e0a\u62a5\u7ed9\u4e91\u5e73\u53f0\r\n         *\/\r\n    }\r\n\r\n    \/* \u7b80\u5316\u8f93\u51fa, \u53ea\u6709\u8ddd\u79bb\u4e0a\u6b21\u7684\u4e0b\u8f7d\u8fdb\u5ea6\u589e\u52a05%\u4ee5\u4e0a\u65f6, \u624d\u4f1a\u6253\u5370\u8fdb\u5ea6, \u5e76\u5411\u670d\u52a1\u5668\u4e0a\u62a5\u8fdb\u5ea6 *\/\r\n    if (percent - last_percent &gt;= 5 || percent == 100) {\r\n        printf(&quot;download %03d%% done, +%d bytesrn&quot;, percent, data_buffer_len);\r\n        aiot_download_report_progress(handle, percent);\r\n\r\n\r\n\r\n        if (userdata) {\r\n            *((uint32_t *)(userdata)) = percent;\r\n        }\r\n        if (percent == 100 &amp;&amp; userdata) {\r\n            free(userdata);\r\n        }\r\n    }\r\n        \/\/add\r\n        fseek( fp, ota_file_size, SEEK_SET );\r\n        fwrite(packet-&gt;data.buffer, packet-&gt;data.len, 1, fp );\r\n        ota_file_size +=  packet-&gt;data.len;\r\n}\r\n\r\n\/* \u6267\u884caiot_download_recv\u7684\u7ebf\u7a0b, \u5b9e\u73b0\u56fa\u4ef6\u5185\u5bb9\u7684\u8bf7\u6c42\u548c\u63a5\u6536 *\/\r\nvoid *demo_ota_download_thread(void *dl_handle)\r\n{\r\n    int32_t     ret = 0;\r\n\r\n    printf(&quot;starting download thread in 2 seconds ......rn&quot;);\r\n    sleep(2);\r\n    system(&quot;rm -rf \/home\/root\/ftp\/Apprun_ota.tar&quot;);\r\n    fp = fopen(&quot;\/home\/root\/ftp\/Apprun_ota.tar&quot;,&quot;wb+&quot;);\r\n    \r\n    \/* \u5411\u56fa\u4ef6\u670d\u52a1\u5668\u8bf7\u6c42\u4e0b\u8f7d *\/\r\n    \/*\r\n     * TODO: \u4e0b\u9762\u8fd9\u6837\u7684\u5199\u6cd5, \u5c31\u662f\u4ee51\u4e2a\u8bf7\u6c42, \u83b7\u53d6\u5168\u90e8\u7684\u56fa\u4ef6\u5185\u5bb9\r\n     *       \u8bbe\u5907\u8d44\u6e90\u6bd4\u8f83\u5c11, \u6216\u8005\u7f51\u7edc\u8f83\u5dee\u65f6, \u4e5f\u53ef\u4ee5\u5206\u6bb5\u4e0b\u8f7d, \u9700\u8981\u7ec4\u5408\r\n     *\r\n     *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_START, ...);\r\n     *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_END, ...);\r\n     *       aiot_download_send_request(dl_handle);\r\n     *\r\n     *       \u5b9e\u73b0, \u8fd9\u79cd\u60c5\u51b5\u4e0b, \u9700\u8981\u628a\u4ee5\u4e0a\u7ec4\u5408\u8bed\u53e5\u653e\u7f6e\u5230\u5faa\u73af\u4e2d, \u591a\u6b21 send_request \u548c recv\r\n     *\r\n     *\/\r\n    aiot_download_send_request(dl_handle);\r\n    while (1) {\r\n        \/* \u4ece\u7f51\u7edc\u6536\u53d6\u670d\u52a1\u5668\u56de\u5e94\u7684\u56fa\u4ef6\u5185\u5bb9 *\/\r\n        ret = aiot_download_recv(dl_handle);\r\n\r\n        \/* \u56fa\u4ef6\u5168\u90e8\u4e0b\u8f7d\u5b8c\u65f6, aiot_download_recv() \u7684\u8fd4\u56de\u503c\u4f1a\u7b49\u4e8e STATE_DOWNLOAD_FINISHED, \u5426\u5219\u662f\u5f53\u6b21\u83b7\u53d6\u7684\u5b57\u8282\u6570 *\/\r\n        if (STATE_DOWNLOAD_FINISHED == ret) {\r\n            printf(&quot;download completedrn&quot;);\r\n            fclose(fp);\r\n            system(&quot;rm -rf \/home\/root\/ftp\/Apprun&quot;);\r\n            system(&quot;tar -xvf \/home\/root\/ftp\/Apprun_ota.tar&quot;);\r\n            \/\/system(&quot;cp \/home\/root\/ftp\/Apprun_ota \/home\/root\/ftp\/Apprun&quot;);\r\n            system(&quot;chmod 777 \/home\/root\/ftp\/Apprun&quot;);\r\n            printf(&quot;ota_file_size=  %drn&quot;, ota_file_size);\r\n            \r\n            break;\r\n        }\r\n        if (STATE_DOWNLOAD_RENEWAL_REQUEST_SENT == ret) {\r\n            printf(&quot;download renewal request has been sent successfullyrn&quot;);\r\n            \r\n            continue;\r\n        }\r\n        if (ret &lt;= STATE_SUCCESS) {\r\n            printf(&quot;download failed, error code is %d, try to send renewal requestrn&quot;, ret);\r\n            continue;\r\n        }\r\n    }\r\n\r\n    \/* \u4e0b\u8f7d\u6240\u6709\u56fa\u4ef6\u5185\u5bb9\u5b8c\u6210, \u9500\u6bc1\u4e0b\u8f7d\u4f1a\u8bdd, \u7ebf\u7a0b\u81ea\u884c\u9000\u51fa *\/\r\n    ret = aiot_download_deinit(&amp;dl_handle);\r\n    printf(&quot;download thread exitrn&quot;);\r\n    if(STATE_SUCCESS == ret){\r\n        \r\n\r\n        \r\n    }\r\n    return NULL;\r\n}\r\n\r\n\/* \u7528\u6237\u901a\u8fc7 aiot_ota_setopt() \u6ce8\u518c\u7684OTA\u6d88\u606f\u5904\u7406\u56de\u8c03, \u5982\u679cSDK\u6536\u5230\u4e86OTA\u76f8\u5173\u7684MQTT\u6d88\u606f, \u4f1a\u81ea\u52a8\u8bc6\u522b, \u8c03\u7528\u8fd9\u4e2a\u56de\u8c03\u51fd\u6570 *\/\r\nvoid demo_ota_recv_handler(void *ota_handle, aiot_ota_recv_t *ota_msg, void *userdata)\r\n{\r\n    switch (ota_msg-&gt;type) {\r\n        case AIOT_OTARECV_FOTA: {\r\n            uint32_t res = 0;\r\n            uint16_t port = 443;\r\n            uint32_t max_buffer_len = (8 * 1024);\r\n            aiot_sysdep_network_cred_t cred;\r\n            void *dl_handle = NULL;\r\n            void *last_percent = NULL;\r\n\r\n            if (NULL == ota_msg-&gt;task_desc) {\r\n                break;\r\n            }\r\n\r\n            dl_handle = aiot_download_init();\r\n            if (NULL == dl_handle) {\r\n                break;\r\n            }\r\n            printf(&quot;OTA target firmware version: %s, size: %u Bytes rn&quot;, ota_msg-&gt;task_desc-&gt;version,\r\n                   ota_msg-&gt;task_desc-&gt;size_total);\r\n\r\n            if (NULL != ota_msg-&gt;task_desc-&gt;extra_data) {\r\n                printf(&quot;extra data: %srn&quot;, ota_msg-&gt;task_desc-&gt;extra_data);\r\n            }\r\n\r\n            memset(&amp;cred, 0, sizeof(aiot_sysdep_network_cred_t));\r\n            cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;\r\n            cred.max_tls_fragment = 16384;\r\n            cred.x509_server_cert = ali_ca_cert;\r\n            cred.x509_server_cert_len = strlen(ali_ca_cert);\r\n\r\n            \/* \u8bbe\u7f6e\u4e0b\u8f7d\u65f6\u4e3aTLS\u4e0b\u8f7d *\/\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_CRED, (void *)(&amp;cred));\r\n            \/* \u8bbe\u7f6e\u4e0b\u8f7d\u65f6\u8bbf\u95ee\u7684\u670d\u52a1\u5668\u7aef\u53e3\u53f7 *\/\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_PORT, (void *)(&amp;port));\r\n            \/* \u8bbe\u7f6e\u4e0b\u8f7d\u7684\u4efb\u52a1\u4fe1\u606f, \u901a\u8fc7\u8f93\u5165\u53c2\u6570 ota_msg \u4e2d\u7684 task_desc \u6210\u5458\u5f97\u5230, \u5185\u542b\u4e0b\u8f7d\u5730\u5740, \u56fa\u4ef6\u5927\u5c0f, \u56fa\u4ef6\u7b7e\u540d\u7b49 *\/\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_TASK_DESC, (void *)(ota_msg-&gt;task_desc));\r\n            \/* \u8bbe\u7f6e\u4e0b\u8f7d\u5185\u5bb9\u5230\u8fbe\u65f6, SDK\u5c06\u8c03\u7528\u7684\u56de\u8c03\u51fd\u6570 *\/\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_RECV_HANDLER, (void *)(demo_download_recv_handler));\r\n            \/* \u8bbe\u7f6e\u5355\u6b21\u4e0b\u8f7d\u6700\u5927\u7684buffer\u957f\u5ea6, \u6bcf\u5f53\u8fd9\u4e2a\u957f\u5ea6\u7684\u5185\u5b58\u8bfb\u6ee1\u4e86\u540e\u4f1a\u901a\u77e5\u7528\u6237 *\/\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_BODY_BUFFER_MAX_LEN, (void *)(&amp;max_buffer_len));\r\n            \/* \u8bbe\u7f6e AIOT_DLOPT_RECV_HANDLER \u7684\u4e0d\u540c\u6b21\u8c03\u7528\u4e4b\u95f4\u5171\u4eab\u7684\u6570\u636e, \u6bd4\u5982\u4f8b\u7a0b\u628a\u8fdb\u5ea6\u5b58\u5728\u8fd9\u91cc *\/\r\n            last_percent = malloc(sizeof(uint32_t));\r\n            if (NULL == last_percent) {\r\n                aiot_download_deinit(&amp;dl_handle);\r\n                break;\r\n            }\r\n            memset(last_percent, 0, sizeof(uint32_t));\r\n            aiot_download_setopt(dl_handle, AIOT_DLOPT_USERDATA, (void *)last_percent);\r\n\r\n            \/* \u542f\u52a8\u4e13\u7528\u7684\u4e0b\u8f7d\u7ebf\u7a0b, \u53bb\u5b8c\u6210\u56fa\u4ef6\u5185\u5bb9\u7684\u4e0b\u8f7d *\/\r\n            res = pthread_create(&amp;g_download_thread, NULL, demo_ota_download_thread, dl_handle);\r\n            if (res != 0) {\r\n                printf(&quot;pthread_create demo_ota_download_thread failed: %drn&quot;, res);\r\n                aiot_download_deinit(&amp;dl_handle);\r\n                free(last_percent);\r\n            } else {\r\n                \/* \u4e0b\u8f7d\u7ebf\u7a0b\u88ab\u8bbe\u7f6e\u4e3a detach \u7c7b\u578b, \u56fa\u4ef6\u5185\u5bb9\u83b7\u53d6\u5b8c\u6bd5\u540e\u53ef\u81ea\u4e3b\u9000\u51fa *\/\r\n                pthread_detach(g_download_thread);\r\n            }\r\n            break;\r\n        }\r\n\r\n        default:\r\n            break;\r\n    }\r\n}\r\n\r\n\/* MQTT\u4e8b\u4ef6\u56de\u8c03\u51fd\u6570, \u5f53\u7f51\u7edc\u8fde\u63a5\/\u91cd\u8fde\/\u65ad\u5f00\u65f6\u88ab\u89e6\u53d1, \u4e8b\u4ef6\u5b9a\u4e49\u89c1core\/aiot_mqtt_api.h *\/\r\nvoid demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata)\r\n{\r\n    switch (event-&gt;type) {\r\n        \/* SDK\u56e0\u4e3a\u7528\u6237\u8c03\u7528\u4e86aiot_mqtt_connect()\u63a5\u53e3, \u4e0emqtt\u670d\u52a1\u5668\u5efa\u7acb\u8fde\u63a5\u5df2\u6210\u529f *\/\r\n        case AIOT_MQTTEVT_CONNECT: {\r\n            printf(&quot;AIOT_MQTTEVT_CONNECTrn&quot;);\r\n            \/* TODO: \u5904\u7406SDK\u5efa\u8fde\u6210\u529f, \u4e0d\u53ef\u4ee5\u5728\u8fd9\u91cc\u8c03\u7528\u8017\u65f6\u8f83\u957f\u7684\u963b\u585e\u51fd\u6570 *\/\r\n        }\r\n        break;\r\n\r\n        \/* SDK\u56e0\u4e3a\u7f51\u7edc\u72b6\u51b5\u88ab\u52a8\u65ad\u8fde\u540e, \u81ea\u52a8\u53d1\u8d77\u91cd\u8fde\u5df2\u6210\u529f *\/\r\n        case AIOT_MQTTEVT_RECONNECT: {\r\n            printf(&quot;AIOT_MQTTEVT_RECONNECTrn&quot;);\r\n            \/* TODO: \u5904\u7406SDK\u91cd\u8fde\u6210\u529f, \u4e0d\u53ef\u4ee5\u5728\u8fd9\u91cc\u8c03\u7528\u8017\u65f6\u8f83\u957f\u7684\u963b\u585e\u51fd\u6570 *\/\r\n        }\r\n        break;\r\n\r\n        \/* SDK\u56e0\u4e3a\u7f51\u7edc\u7684\u72b6\u51b5\u800c\u88ab\u52a8\u65ad\u5f00\u4e86\u8fde\u63a5, network\u662f\u5e95\u5c42\u8bfb\u5199\u5931\u8d25, heartbeat\u662f\u6ca1\u6709\u6309\u9884\u671f\u5f97\u5230\u670d\u52a1\u7aef\u5fc3\u8df3\u5e94\u7b54 *\/\r\n        case AIOT_MQTTEVT_DISCONNECT: {\r\n            char *cause = (event-&gt;data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? (&quot;network disconnect&quot;) :\r\n                          (&quot;heartbeat disconnect&quot;);\r\n            printf(&quot;AIOT_MQTTEVT_DISCONNECT: %srn&quot;, cause);\r\n            \/* TODO: \u5904\u7406SDK\u88ab\u52a8\u65ad\u8fde, \u4e0d\u53ef\u4ee5\u5728\u8fd9\u91cc\u8c03\u7528\u8017\u65f6\u8f83\u957f\u7684\u963b\u585e\u51fd\u6570 *\/\r\n        }\r\n        break;\r\n\r\n        default: {\r\n\r\n        }\r\n    }\r\n}\r\n\r\n\/* MQTT\u9ed8\u8ba4\u6d88\u606f\u5904\u7406\u56de\u8c03, \u5f53SDK\u4ece\u670d\u52a1\u5668\u6536\u5230MQTT\u6d88\u606f\u65f6, \u4e14\u65e0\u5bf9\u5e94\u7528\u6237\u56de\u8c03\u5904\u7406\u65f6\u88ab\u8c03\u7528 *\/\r\nvoid demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)\r\n{\r\n    switch (packet-&gt;type) {\r\n        case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: {\r\n            printf(&quot;heartbeat responsern&quot;);\r\n            \/* TODO: \u5904\u7406\u670d\u52a1\u5668\u5bf9\u5fc3\u8df3\u7684\u56de\u5e94, \u4e00\u822c\u4e0d\u5904\u7406 *\/\r\n        }\r\n        break;\r\n\r\n        case AIOT_MQTTRECV_SUB_ACK: {\r\n            printf(&quot;suback, res: -0x%04X, packet id: %d, max qos: %drn&quot;,\r\n                   -packet-&gt;data.sub_ack.res, packet-&gt;data.sub_ack.packet_id, packet-&gt;data.sub_ack.max_qos);\r\n            \/* TODO: \u5904\u7406\u670d\u52a1\u5668\u5bf9\u8ba2\u9605\u8bf7\u6c42\u7684\u56de\u5e94, \u4e00\u822c\u4e0d\u5904\u7406 *\/\r\n        }\r\n        break;\r\n\r\n        case AIOT_MQTTRECV_PUB: {\r\n            printf(&quot;pub, qos: %d, topic: %.*srn&quot;, packet-&gt;data.pub.qos, packet-&gt;data.pub.topic_len, packet-&gt;data.pub.topic);\r\n            printf(&quot;pub, payload: %.*srn&quot;, packet-&gt;data.pub.payload_len, packet-&gt;data.pub.payload);\r\n            \/* TODO: \u5904\u7406\u670d\u52a1\u5668\u4e0b\u53d1\u7684\u4e1a\u52a1\u62a5\u6587 *\/\r\n        }\r\n        break;\r\n\r\n        case AIOT_MQTTRECV_PUB_ACK: {\r\n            printf(&quot;puback, packet id: %drn&quot;, packet-&gt;data.pub_ack.packet_id);\r\n            \/* TODO: \u5904\u7406\u670d\u52a1\u5668\u5bf9QoS1\u4e0a\u62a5\u6d88\u606f\u7684\u56de\u5e94, \u4e00\u822c\u4e0d\u5904\u7406 *\/\r\n        }\r\n        break;\r\n\r\n        default: {\r\n\r\n        }\r\n    }\r\n}\r\n\r\n\/* \u6267\u884caiot_mqtt_process\u7684\u7ebf\u7a0b, \u5305\u542b\u5fc3\u8df3\u53d1\u9001\u548cQoS1\u6d88\u606f\u91cd\u53d1 *\/\r\nvoid *demo_mqtt_process_thread(void *args)\r\n{\r\n    while (1) {\r\n        aiot_mqtt_process(args);\r\n        sleep(1);\r\n    }\r\n    return NULL;\r\n}\r\n\r\n\/* \u6267\u884caiot_mqtt_recv\u7684\u7ebf\u7a0b, \u5305\u542b\u7f51\u7edc\u81ea\u52a8\u91cd\u8fde\u548c\u4ece\u670d\u52a1\u5668\u6536\u53d6MQTT\u6d88\u606f *\/\r\nvoid *demo_mqtt_recv_thread(void *args)\r\n{\r\n    int32_t res = STATE_SUCCESS;\r\n\r\n    while (1) {\r\n        res = aiot_mqtt_recv(args);\r\n        if (res &lt; STATE_SUCCESS) {\r\n            sleep(1);\r\n        }\r\n    }\r\n    return NULL;\r\n}\r\nvoid *app_run_thread(void *args)\r\n{\r\n    while (1) {\r\n        app_main();\r\n        usleep(500*1000);\r\n    }\r\n    return NULL;\r\n}\r\nvoid mqtt_send_info(void)\r\n\r\n    {\r\n\r\n    } \r\nint sdk_test(int argc, char *argv&#091;])\r\n{\r\n\r\n    int8_t      public_instance =\r\n                1;  \/* \u7528\u516c\u5171\u5b9e\u4f8b, \u8be5\u53c2\u6570\u8981\u8bbe\u7f6e\u4e3a1. \u82e5\u7528\u72ec\u4eab\u5b9e\u4f8b, \u8981\u5c06\u8be5\u53c2\u6570\u8bbe\u7f6e\u4e3a0 *\/\r\n    char       *url = &quot;iot-as-mqtt.cn-shanghai.aliyuncs.com&quot;; \/* \u963f\u91cc\u4e91\u5e73\u53f0\u4e0a\u6d77\u7ad9\u70b9\u7684\u57df\u540d\u540e\u7f00 *\/\r\n    char        host&#091;100] = {0}; \/* \u7528\u8fd9\u4e2a\u6570\u7ec4\u62fc\u63a5\u8bbe\u5907\u8fde\u63a5\u7684\u4e91\u5e73\u53f0\u7ad9\u70b9\u5168\u5730\u5740, \u89c4\u5219\u662f ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com *\/\r\n    uint16_t    port = 443;      \/* \u65e0\u8bba\u8bbe\u5907\u662f\u5426\u4f7f\u7528TLS\u8fde\u63a5\u963f\u91cc\u4e91\u5e73\u53f0, \u76ee\u7684\u7aef\u53e3\u90fd\u662f443 *\/\r\n    aiot_sysdep_network_cred_t cred; \/* \u5b89\u5168\u51ed\u636e\u7ed3\u6784\u4f53, \u5982\u679c\u8981\u7528TLS, \u8fd9\u4e2a\u7ed3\u6784\u4f53\u4e2d\u914d\u7f6eCA\u8bc1\u4e66\u7b49\u53c2\u6570 *\/\r\n\r\n\r\n    \/\/init config\r\n    GetProfileString(&quot;conf.ini&quot;, &quot;MQTT&quot;, &quot;product_key&quot;, product_key);\r\n    GetProfileString(&quot;conf.ini&quot;, &quot;MQTT&quot;, &quot;device_name&quot;, device_name);\r\n    GetProfileString(&quot;conf.ini&quot;, &quot;MQTT&quot;, &quot;device_secret&quot;, device_secret);\r\n\r\n    res = pthread_create(&amp;g_apprun_thread, NULL, app_run_thread, NULL);\r\n    if (res != 0) {\r\n        printf(&quot;pthread_create app_run_thread failed: %drn&quot;, res);\r\n        return -1;\r\n    }\r\n\r\n    char *sub_topic = &quot;\/a1mj7GHuxu2\/C-AZ-01\/user\/setreg&quot;;\r\n\r\n    \/* \u914d\u7f6eSDK\u7684\u5e95\u5c42\u4f9d\u8d56 *\/\r\n    aiot_sysdep_set_portfile(&amp;g_aiot_sysdep_portfile);\r\n\r\n    \/* \u914d\u7f6eSDK\u7684\u65e5\u5fd7\u8f93\u51fa *\/\r\n    aiot_state_set_logcb(demo_state_logcb);\r\n\r\n    \/* \u521b\u5efaSDK\u7684\u5b89\u5168\u51ed\u636e, \u7528\u4e8e\u5efa\u7acbTLS\u8fde\u63a5 *\/\r\n    memset(&amp;cred, 0, sizeof(aiot_sysdep_network_cred_t));\r\n    cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;  \/* \u4f7f\u7528RSA\u8bc1\u4e66\u6821\u9a8cMQTT\u670d\u52a1\u7aef *\/\r\n    cred.max_tls_fragment = 16384; \/* \u6700\u5927\u7684\u5206\u7247\u957f\u5ea6\u4e3a16K, \u5176\u5b83\u53ef\u9009\u503c\u8fd8\u67094K, 2K, 1K, 0.5K *\/\r\n    cred.sni_enabled = 1;                               \/* TLS\u5efa\u8fde\u65f6, \u652f\u6301Server Name Indicator *\/\r\n    cred.x509_server_cert = ali_ca_cert;                 \/* \u7528\u6765\u9a8c\u8bc1MQTT\u670d\u52a1\u7aef\u7684RSA\u6839\u8bc1\u4e66 *\/\r\n    cred.x509_server_cert_len = strlen(ali_ca_cert);     \/* \u7528\u6765\u9a8c\u8bc1MQTT\u670d\u52a1\u7aef\u7684RSA\u6839\u8bc1\u4e66\u957f\u5ea6 *\/\r\n\r\n    \/* \u521b\u5efa1\u4e2aMQTT\u5ba2\u6237\u7aef\u5b9e\u4f8b\u5e76\u5185\u90e8\u521d\u59cb\u5316\u9ed8\u8ba4\u53c2\u6570 *\/\r\n    mqtt_handle = aiot_mqtt_init();\r\n    if (NULL == mqtt_handle) {\r\n        printf(&quot;aiot_mqtt_init failedrn&quot;);\r\n        return -1;\r\n    }\r\n\r\n    if (1 == public_instance) {\r\n        snprintf(host, 100, &quot;%s.%s&quot;, product_key, url);\r\n    } else {\r\n        snprintf(host, 100, &quot;%s&quot;, url);\r\n    }\r\n    \/* \u914d\u7f6eMQTT\u670d\u52a1\u5668\u5730\u5740 *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)host);\r\n    \/* \u914d\u7f6eMQTT\u670d\u52a1\u5668\u7aef\u53e3 *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&amp;port);\r\n    \/* \u914d\u7f6e\u8bbe\u5907productKey *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);\r\n    \/* \u914d\u7f6e\u8bbe\u5907deviceName *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);\r\n    \/* \u914d\u7f6e\u8bbe\u5907deviceSecret *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);\r\n    \/* \u914d\u7f6e\u7f51\u7edc\u8fde\u63a5\u7684\u5b89\u5168\u51ed\u636e, \u4e0a\u9762\u5df2\u7ecf\u521b\u5efa\u597d\u4e86 *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&amp;cred);\r\n    \/* \u914d\u7f6eMQTT\u9ed8\u8ba4\u6d88\u606f\u63a5\u6536\u56de\u8c03\u51fd\u6570 *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);\r\n    \/* \u914d\u7f6eMQTT\u4e8b\u4ef6\u56de\u8c03\u51fd\u6570 *\/\r\n    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);\r\n\r\n    \/* \u4e0eMQTT\u4f8b\u7a0b\u4e0d\u540c\u7684\u662f, \u8fd9\u91cc\u9700\u8981\u589e\u52a0\u521b\u5efaOTA\u4f1a\u8bdd\u5b9e\u4f8b\u7684\u8bed\u53e5 *\/\r\n    ota_handle = aiot_ota_init();\r\n    if (NULL == ota_handle) {\r\n        printf(&quot;aiot_ota_init failedrn&quot;);\r\n        aiot_mqtt_deinit(&amp;mqtt_handle);\r\n        return -2;\r\n    }\r\n\r\n    \/* \u7528\u4ee5\u4e0b\u8bed\u53e5, \u628aOTA\u4f1a\u8bdd\u548cMQTT\u4f1a\u8bdd\u5173\u8054\u8d77\u6765 *\/\r\n    aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);\r\n    \/* \u7528\u4ee5\u4e0b\u8bed\u53e5, \u8bbe\u7f6eOTA\u4f1a\u8bdd\u7684\u6570\u636e\u63a5\u6536\u56de\u8c03, SDK\u6536\u5230OTA\u76f8\u5173\u63a8\u9001\u65f6, \u4f1a\u8fdb\u5165\u8fd9\u4e2a\u56de\u8c03\u51fd\u6570 *\/\r\n    aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler);\r\n\r\n    \/* \u4e0e\u670d\u52a1\u5668\u5efa\u7acbMQTT\u8fde\u63a5 *\/\r\n    res = aiot_mqtt_connect(mqtt_handle);\r\n    if (res &lt; STATE_SUCCESS) {\r\n        \/* \u5c1d\u8bd5\u5efa\u7acb\u8fde\u63a5\u5931\u8d25, \u9500\u6bc1MQTT\u5b9e\u4f8b, \u56de\u6536\u8d44\u6e90 *\/\r\n        aiot_mqtt_deinit(&amp;mqtt_handle);\r\n        aiot_ota_deinit(&amp;ota_handle);\r\n        printf(&quot;aiot_mqtt_connect failed: -0x%04Xrn&quot;, -res);\r\n    }\r\n\r\n    \/*   TODO: \u975e\u5e38\u91cd\u8981!!!\r\n     *\r\n     *   cur_version \u8981\u6839\u636e\u7528\u6237\u5b9e\u9645\u60c5\u51b5, \u6539\u6210\u4ece\u8bbe\u5907\u7684\u914d\u7f6e\u533a\u83b7\u53d6, \u8981\u53cd\u6620\u771f\u5b9e\u7684\u7248\u672c\u53f7, \u800c\u4e0d\u80fd\u50cf\u793a\u4f8b\u8fd9\u6837\u5199\u4e3a\u56fa\u5b9a\u503c\r\n     *\r\n     *   1. \u5982\u679c\u8bbe\u5907\u4ece\u672a\u4e0a\u62a5\u8fc7\u7248\u672c\u53f7, \u5728\u63a7\u5236\u53f0\u7f51\u9875\u5c06\u65e0\u6cd5\u90e8\u7f72\u5347\u7ea7\u4efb\u52a1\r\n     *   2. \u5982\u679c\u8bbe\u5907\u5347\u7ea7\u5b8c\u6210\u540e, \u4e0a\u62a5\u7684\u4e0d\u662f\u65b0\u7684\u7248\u672c\u53f7, \u5728\u63a7\u5236\u53f0\u7f51\u9875\u5c06\u4f1a\u663e\u793a\u5347\u7ea7\u5931\u8d25\r\n     *\r\n     *\/\r\n\r\n    \/* \u6f14\u793aMQTT\u8fde\u63a5\u5efa\u7acb\u8d77\u6765\u4e4b\u540e, \u5c31\u53ef\u4ee5\u4e0a\u62a5\u5f53\u524d\u8bbe\u5907\u7684\u7248\u672c\u53f7\u4e86 *\/\r\n    cur_version = VERSTR;\r\n    res = aiot_ota_report_version(ota_handle, cur_version);\r\n    if (res &lt; STATE_SUCCESS) {\r\n        printf(&quot;aiot_ota_report_version failed: -0x%04Xrn&quot;, -res);\r\n    }\r\n\r\n    \/* \u521b\u5efa\u4e00\u4e2a\u5355\u72ec\u7684\u7ebf\u7a0b, \u4e13\u7528\u4e8e\u6267\u884caiot_mqtt_process, \u5b83\u4f1a\u81ea\u52a8\u53d1\u9001\u5fc3\u8df3\u4fdd\u6d3b, \u4ee5\u53ca\u91cd\u53d1QoS1\u7684\u672a\u5e94\u7b54\u62a5\u6587 *\/\r\n    res = pthread_create(&amp;g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle);\r\n    if (res != 0) {\r\n        printf(&quot;pthread_create demo_mqtt_process_thread failed: %drn&quot;, res);\r\n        return -1;\r\n    }\r\n\r\n    \/* \u521b\u5efa\u4e00\u4e2a\u5355\u72ec\u7684\u7ebf\u7a0b\u7528\u4e8e\u6267\u884caiot_mqtt_recv, \u5b83\u4f1a\u5faa\u73af\u6536\u53d6\u670d\u52a1\u5668\u4e0b\u53d1\u7684MQTT\u6d88\u606f, \u5e76\u5728\u65ad\u7ebf\u65f6\u81ea\u52a8\u91cd\u8fde *\/\r\n    res = pthread_create(&amp;g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle);\r\n    if (res != 0) {\r\n        printf(&quot;pthread_create demo_mqtt_recv_thread failed: %drn&quot;, res);\r\n        return -1;\r\n    }\r\n\r\n\r\n    res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL);\r\n    if (res &lt; 0) {\r\n        printf(&quot;aiot_mqtt_sub failed, res: -0x%04Xn&quot;, -res);\r\n    }\r\n\r\n    \/* \u4e3b\u5faa\u73af\u8fdb\u5165\u4f11\u7720 *\/\r\n    while (1) {\r\n        sleep(30);\r\n        mqtt_send_info();\r\n\r\n        \r\n    }\r\n\r\n    \/* \u65ad\u5f00MQTT\u8fde\u63a5, \u4e00\u822c\u4e0d\u4f1a\u8fd0\u884c\u5230\u8fd9\u91cc *\/\r\n    res = aiot_mqtt_disconnect(mqtt_handle);\r\n    if (res &lt; STATE_SUCCESS) {\r\n        aiot_mqtt_deinit(&amp;mqtt_handle);\r\n        aiot_ota_deinit(&amp;ota_handle);\r\n        printf(&quot;aiot_mqtt_disconnect failed: -0x%04Xrn&quot;, -res);\r\n        return -1;\r\n    }\r\n\r\n    \/* \u9500\u6bc1MQTT\u5b9e\u4f8b, \u4e00\u822c\u4e0d\u4f1a\u8fd0\u884c\u5230\u8fd9\u91cc *\/\r\n    res = aiot_mqtt_deinit(&amp;mqtt_handle);\r\n    if (res &lt; STATE_SUCCESS) {\r\n        printf(&quot;aiot_mqtt_deinit failed: -0x%04Xrn&quot;, -res);\r\n        aiot_ota_deinit(&amp;ota_handle);\r\n        return -1;\r\n    }\r\n\r\n    \/* \u9500\u6bc1OTA\u5b9e\u4f8b, \u4e00\u822c\u4e0d\u4f1a\u8fd0\u884c\u5230\u8fd9\u91cc *\/\r\n    aiot_ota_deinit(&amp;ota_handle);\r\n    return 0;\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[53,37],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/posts\/353"}],"collection":[{"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=353"}],"version-history":[{"count":2,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/posts\/353\/revisions"}],"predecessor-version":[{"id":839,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=\/wp\/v2\/posts\/353\/revisions\/839"}],"wp:attachment":[{"href":"https:\/\/blog.iotot.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.iotot.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}