ota_mqtt_sample.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. /*
  2. * Tencent is pleased to support the open source community by making IoT Hub
  3. available.
  4. * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
  5. * Licensed under the MIT License (the "License"); you may not use this file
  6. except in
  7. * compliance with the License. You may obtain a copy of the License at
  8. * http://opensource.org/licenses/MIT
  9. * Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is
  11. * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  12. KIND,
  13. * either express or implied. See the License for the specific language
  14. governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #define bool _Bool
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "ql_fs.h"
  23. #include "ql_api_fota.h"
  24. #include "ql_api_osi.h"
  25. #include "ql_api_datacall.h"
  26. #include "ql_power.h"
  27. #include "lite-utils.h"
  28. #include "qcloud_iot_export.h"
  29. #include "qcloud_iot_import.h"
  30. #include "ql_log.h"
  31. #define PROFILE_IDX 1
  32. #ifdef DEBUG_DEV_INFO_USED
  33. extern int device_info_copy(void *pdst, void *psrc, uint8_t max_len);
  34. #endif
  35. #ifdef DEBUG_DEV_INFO_USED
  36. #define PRODUCT_ID "KSS57PUDXP"
  37. #define DEVICE_NAME "Smart_light_01"
  38. #define DEVICE_SECRET "0TJoksp0+vkWMr1qSAR7ow=="
  39. #define REGION "china"
  40. #define DEVICE_CERT "./certsSmart_light_01_cert.crt"
  41. #define DEVICE_PRIVATE "./certsSmart_light_01_private.key"
  42. #else
  43. #define DEVICE_INFO_JSON_DOC "UFS:device_info.json"
  44. #endif
  45. #define FW_FILE_PATH_FORMAT "UFS:EC200U_FIRMWARE.bin"
  46. #define FW_FILE_INFO_PATH_FORMAT "UFS:EC200U_FIRMWARE.json"
  47. #define FW_RUNNING_VERSION "1.0.0"
  48. #define KEY_VER "version"
  49. #define KEY_SIZE "downloaded_size"
  50. #define FW_VERSION_MAX_LEN 32
  51. #define FW_FILE_PATH_MAX_LEN 128
  52. #define OTA_BUF_LEN 5000
  53. #define FW_INFO_FILE_DATA_LEN 128
  54. typedef struct OTAContextData {
  55. void *ota_handle;
  56. void *mqtt_client;
  57. char fw_file_path[FW_FILE_PATH_MAX_LEN];
  58. char fw_info_file_path[FW_FILE_PATH_MAX_LEN];
  59. // remote_version means version for the FW in the cloud and to be downloaded
  60. char remote_version[FW_VERSION_MAX_LEN];
  61. uint32_t fw_file_size;
  62. // for resuming download
  63. /* local_version means downloading but not running */
  64. char local_version[FW_VERSION_MAX_LEN];
  65. int downloaded_size;
  66. // to make sure report is acked
  67. bool report_pub_ack;
  68. int report_packet_id;
  69. } OTAContextData;
  70. static DeviceInfo sg_devInfo;
  71. static void _event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
  72. {
  73. uintptr_t packet_id = (uintptr_t)msg->msg;
  74. OTAContextData *ota_ctx = (OTAContextData *)handle_context;
  75. switch (msg->event_type) {
  76. case MQTT_EVENT_UNDEF:
  77. Log_i("undefined event occur.");
  78. break;
  79. case MQTT_EVENT_DISCONNECT:
  80. Log_i("MQTT disconnect.");
  81. break;
  82. case MQTT_EVENT_RECONNECT:
  83. Log_i("MQTT reconnect.");
  84. break;
  85. case MQTT_EVENT_SUBCRIBE_SUCCESS:
  86. Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
  87. break;
  88. case MQTT_EVENT_SUBCRIBE_TIMEOUT:
  89. Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
  90. break;
  91. case MQTT_EVENT_SUBCRIBE_NACK:
  92. Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
  93. break;
  94. case MQTT_EVENT_PUBLISH_SUCCESS:
  95. Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
  96. if (ota_ctx->report_packet_id == packet_id)
  97. ota_ctx->report_pub_ack = true;
  98. break;
  99. case MQTT_EVENT_PUBLISH_TIMEOUT:
  100. Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
  101. break;
  102. case MQTT_EVENT_PUBLISH_NACK:
  103. Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
  104. break;
  105. default:
  106. Log_i("Should NOT arrive here.");
  107. break;
  108. }
  109. }
  110. static int _setup_connect_init_params(MQTTInitParams *initParams, void *ota_ctx, DeviceInfo *device_info)
  111. {
  112. initParams->region = device_info->region;
  113. initParams->product_id = device_info->product_id;
  114. initParams->device_name = device_info->device_name;
  115. #ifdef AUTH_MODE_CERT
  116. // char certs_dir[16] = "certs";
  117. // char current_path[128];
  118. // char *cwd = getcwd(current_path, sizeof(current_path));
  119. //
  120. // if (cwd == NULL) {
  121. // Log_e("getcwd return NULL");
  122. // return QCLOUD_ERR_FAILURE;
  123. // }
  124. //#ifdef WIN32
  125. // HAL_Snprintf(initParams->cert_file, FILE_PATH_MAX_LEN, "%s\\%s\\%s", current_path, certs_dir,
  126. // device_info->dev_cert_file_name);
  127. // HAL_Snprintf(initParams->key_file, FILE_PATH_MAX_LEN, "%s\\%s\\%s", current_path, certs_dir,
  128. // device_info->dev_key_file_name);
  129. //#else
  130. // HAL_Snprintf(initParams->cert_file, FILE_PATH_MAX_LEN, "%s/%s/%s", current_path, certs_dir,
  131. // device_info->dev_cert_file_name);
  132. // HAL_Snprintf(initParams->key_file, FILE_PATH_MAX_LEN, "%s/%s/%s", current_path, certs_dir,
  133. // device_info->dev_key_file_name);
  134. //#endif
  135. sprintf(initParams->cert_file, "%s", device_info->dev_cert_file_name);
  136. sprintf(initParams->key_file, "%s", device_info->dev_key_file_name);
  137. #else
  138. initParams->device_secret = device_info->device_secret;
  139. #endif
  140. initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
  141. initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
  142. initParams->auto_connect_enable = 1;
  143. initParams->event_handle.h_fp = _event_handler;
  144. initParams->event_handle.context = ota_ctx;
  145. return QCLOUD_RET_SUCCESS;
  146. }
  147. static void _wait_for_pub_ack(OTAContextData *ota_ctx, int packet_id)
  148. {
  149. int wait_cnt = 10;
  150. ota_ctx->report_pub_ack = false;
  151. ota_ctx->report_packet_id = packet_id;
  152. while (!ota_ctx->report_pub_ack) {
  153. HAL_SleepMs(500);
  154. IOT_MQTT_Yield(ota_ctx->mqtt_client, 500);
  155. if (wait_cnt-- == 0) {
  156. Log_e("wait report pub ack timeout!");
  157. break;
  158. }
  159. }
  160. ota_ctx->report_pub_ack = false;
  161. return;
  162. }
  163. /**********************************************************************************
  164. * OTA file operations START
  165. * these are platform-dependant functions
  166. * POSIX FILE is used in this sample code
  167. **********************************************************************************/
  168. // calculate left MD5 for resuming download from break point
  169. static int _cal_exist_fw_md5(OTAContextData *ota_ctx)
  170. {
  171. char buff[OTA_BUF_LEN];
  172. size_t rlen, total_read = 0, actual_rlen = 0;
  173. int ret = QCLOUD_RET_SUCCESS;
  174. int eof = 0;
  175. ret = IOT_OTA_ResetClientMD5(ota_ctx->ota_handle);
  176. if (ret) {
  177. Log_e("reset MD5 failed: %d", ret);
  178. return QCLOUD_ERR_FAILURE;
  179. }
  180. QFILE fp = ql_fopen(ota_ctx->fw_file_path, "ab+");
  181. if (fp<0) {
  182. Log_e("open file %s failed", ota_ctx->fw_file_path);
  183. return QCLOUD_ERR_FAILURE;
  184. }
  185. // rewind(fp);
  186. size_t size = ota_ctx->downloaded_size;
  187. while ((size > 0) && (!eof)) {
  188. rlen = (size > OTA_BUF_LEN) ? OTA_BUF_LEN : size;
  189. actual_rlen = ql_fread(buff, 1, rlen, fp);
  190. if (actual_rlen < 0) {
  191. Log_e("read data len not expected");
  192. ret = QCLOUD_ERR_FAILURE;
  193. break;
  194. } else if (actual_rlen < rlen) {
  195. Log_e("read end of file");
  196. eof = 1;
  197. }
  198. IOT_OTA_UpdateClientMd5(ota_ctx->ota_handle, buff, actual_rlen);
  199. size -= actual_rlen;
  200. total_read += actual_rlen;
  201. }
  202. ql_fclose(fp);
  203. Log_d("total read: %d", total_read);
  204. return ret;
  205. }
  206. /* update local firmware info for resuming download from break point */
  207. static int _update_local_fw_info(OTAContextData *ota_ctx)
  208. {
  209. QFILE fp;
  210. int wlen;
  211. int ret = QCLOUD_RET_SUCCESS;
  212. char data_buf[FW_INFO_FILE_DATA_LEN];
  213. memset(data_buf, 0, sizeof(data_buf));
  214. HAL_Snprintf(data_buf, sizeof(data_buf), "{\"%s\":\"%s\", \"%s\":%d}", KEY_VER, ota_ctx->remote_version, KEY_SIZE,
  215. ota_ctx->downloaded_size);
  216. fp = ql_fopen(ota_ctx->fw_info_file_path, "w");
  217. if (fp<0) {
  218. Log_e("open file %s failed", ota_ctx->fw_info_file_path);
  219. ret = QCLOUD_ERR_FAILURE;
  220. goto exit;
  221. }
  222. wlen = ql_fwrite(data_buf, 1, strlen(data_buf), fp);
  223. if (wlen != strlen(data_buf)) {
  224. Log_e("save version to file err");
  225. ret = QCLOUD_ERR_FAILURE;
  226. }
  227. exit:
  228. if (fp>=0) {
  229. ql_fclose(fp);
  230. }
  231. return ret;
  232. }
  233. static int _get_local_fw_info(char *file_name, char *local_version)
  234. {
  235. int len;
  236. int rlen;
  237. char json_doc[FW_INFO_FILE_DATA_LEN] = {0};
  238. QFILE fp = ql_fopen(file_name, "r");
  239. if (fp<0) {
  240. Log_e("open file %s failed", file_name);
  241. return 0;
  242. }
  243. ql_fseek(fp, 0L, SEEK_END);
  244. len = ql_ftell(fp);
  245. if (len > FW_INFO_FILE_DATA_LEN) {
  246. Log_e("%s is too big, pls check", file_name);
  247. ql_fclose(fp);
  248. return 0;
  249. }
  250. ql_frewind(fp);
  251. rlen = ql_fread(json_doc, 1, len, fp);
  252. if (len != rlen) {
  253. Log_e("read data len (%d) less than needed (%d), %s", rlen, len, json_doc);
  254. ql_fclose(fp);
  255. return 0;
  256. }
  257. char *version = LITE_json_value_of(KEY_VER, json_doc);
  258. char *size = LITE_json_value_of(KEY_SIZE, json_doc);
  259. if ((NULL == version) || (NULL == size)) {
  260. if (version)
  261. HAL_Free(version);
  262. if (size)
  263. HAL_Free(size);
  264. ql_fclose(fp);
  265. return 0;
  266. }
  267. int local_size = atoi(size);
  268. HAL_Free(size);
  269. if (local_size <= 0) {
  270. Log_w("local info offset invalid: %d", local_size);
  271. HAL_Free(version);
  272. local_size = 0;
  273. }
  274. strncpy(local_version, version, FW_VERSION_MAX_LEN);
  275. HAL_Free(version);
  276. ql_fclose(fp);
  277. return local_size;
  278. }
  279. /* get local firmware offset for resuming download from break point */
  280. static int _update_fw_downloaded_size(OTAContextData *ota_ctx)
  281. {
  282. int local_size = _get_local_fw_info(ota_ctx->fw_info_file_path, ota_ctx->local_version);
  283. if (local_size == 0) {
  284. ota_ctx->downloaded_size = 0;
  285. return 0;
  286. }
  287. if ((0 != strcmp(ota_ctx->local_version, ota_ctx->remote_version)) ||
  288. (ota_ctx->downloaded_size > ota_ctx->fw_file_size)) {
  289. ota_ctx->downloaded_size = 0;
  290. return 0;
  291. }
  292. ota_ctx->downloaded_size = local_size;
  293. Log_i("calc MD5 for resuming download from offset: %d", ota_ctx->downloaded_size);
  294. int ret = _cal_exist_fw_md5(ota_ctx);
  295. if (ret) {
  296. Log_e("regen OTA MD5 error: %d", ret);
  297. ql_remove(ota_ctx->fw_info_file_path);
  298. ota_ctx->downloaded_size = 0;
  299. return 0;
  300. }
  301. Log_d("local MD5 update done!");
  302. return local_size;
  303. }
  304. static int _delete_fw_info_file(char *file_name)
  305. {
  306. return ql_remove(file_name);
  307. }
  308. static int _save_fw_data_to_file(char *file_name, uint32_t offset, char *buf, int len)
  309. {
  310. QFILE fp;
  311. if (offset > 0) {
  312. fp = ql_fopen(file_name, "ab+");
  313. if(fp<0)
  314. {
  315. Log_e("open file failed");
  316. return QCLOUD_ERR_FAILURE;
  317. }
  318. } else {
  319. fp = ql_fopen(file_name, "wb+");
  320. if(fp<0)
  321. {
  322. Log_e("open file failed");
  323. return QCLOUD_ERR_FAILURE;
  324. }
  325. }
  326. ql_fseek(fp, offset, SEEK_SET);
  327. if (len != ql_fwrite(buf, 1, len, fp)) {
  328. Log_e("write data to file failed");
  329. ql_fclose(fp);
  330. return QCLOUD_ERR_FAILURE;
  331. }
  332. //ql_fsync(fp);
  333. ql_fclose(fp);
  334. return 0;
  335. }
  336. static char *_get_local_fw_running_version()
  337. {
  338. // asuming the version is inside the code and binary
  339. // you can also get from a meta file
  340. Log_i("FW running version: %s", FW_RUNNING_VERSION);
  341. return FW_RUNNING_VERSION;
  342. }
  343. /**********************************************************************************
  344. * OTA file operations END
  345. **********************************************************************************/
  346. // main OTA cycle
  347. bool process_ota(OTAContextData *ota_ctx)
  348. {
  349. bool download_finished = false;
  350. bool upgrade_fetch_success = true;
  351. char buf_ota[OTA_BUF_LEN];
  352. int rc;
  353. void *h_ota = ota_ctx->ota_handle;
  354. /* Must report version first */
  355. if (0 > IOT_OTA_ReportVersion(h_ota, _get_local_fw_running_version())) {
  356. Log_e("report OTA version failed");
  357. return false;
  358. }
  359. do {
  360. IOT_MQTT_Yield(ota_ctx->mqtt_client, 200);
  361. Log_i("wait for ota upgrade command...");
  362. // recv the upgrade cmd
  363. if (IOT_OTA_IsFetching(h_ota)) {
  364. IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &ota_ctx->fw_file_size, 4);
  365. IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, ota_ctx->remote_version, FW_VERSION_MAX_LEN);
  366. HAL_Snprintf(ota_ctx->fw_file_path, FW_FILE_PATH_MAX_LEN, FW_FILE_PATH_FORMAT, ota_ctx->remote_version);
  367. HAL_Snprintf(ota_ctx->fw_info_file_path, FW_FILE_PATH_MAX_LEN, FW_FILE_INFO_PATH_FORMAT, ota_ctx->remote_version);
  368. /* check if pre-downloading finished or not */
  369. /* if local FW downloaded size (ota_ctx->downloaded_size) is not zero, it
  370. * will do resuming download */
  371. _update_fw_downloaded_size(ota_ctx);
  372. /*set offset and start http connect*/
  373. rc = IOT_OTA_StartDownload(h_ota, ota_ctx->downloaded_size, ota_ctx->fw_file_size);
  374. if (QCLOUD_RET_SUCCESS != rc) {
  375. Log_e("OTA download start err,rc:%d", rc);
  376. upgrade_fetch_success = false;
  377. break;
  378. }
  379. // download and save the fw
  380. do {
  381. int len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
  382. if (len > 0) {
  383. rc = _save_fw_data_to_file(ota_ctx->fw_file_path, ota_ctx->downloaded_size, buf_ota, len);
  384. if (rc) {
  385. Log_e("write data to file failed");
  386. upgrade_fetch_success = false;
  387. break;
  388. }
  389. } else if (len < 0) {
  390. Log_e("download fail rc=%d", len);
  391. upgrade_fetch_success = false;
  392. break;
  393. }
  394. /* get OTA information and update local info */
  395. IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &ota_ctx->downloaded_size, 4);
  396. rc = _update_local_fw_info(ota_ctx);
  397. if (QCLOUD_RET_SUCCESS != rc) {
  398. Log_e("update local fw info err,rc:%d", rc);
  399. }
  400. // quit ota process as something wrong with mqtt
  401. rc = IOT_MQTT_Yield(ota_ctx->mqtt_client, 100);
  402. if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED) {
  403. Log_e("MQTT error: %d", rc);
  404. return false;
  405. }
  406. } while (!IOT_OTA_IsFetchFinish(h_ota));
  407. /* Must check MD5 match or not */
  408. if (upgrade_fetch_success) {
  409. // download is finished, delete the fw info file
  410. _delete_fw_info_file(ota_ctx->fw_info_file_path);
  411. uint32_t firmware_valid;
  412. IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
  413. if (0 == firmware_valid) {
  414. Log_e("The firmware is invalid");
  415. upgrade_fetch_success = false;
  416. } else {
  417. Log_i("The firmware is valid");
  418. upgrade_fetch_success = true;
  419. }
  420. }
  421. download_finished = true;
  422. }
  423. if (!download_finished)
  424. HAL_SleepMs(1000);
  425. } while (!download_finished);
  426. // do some post-download stuff for your need
  427. // report result
  428. int packet_id;
  429. if (upgrade_fetch_success)
  430. packet_id = IOT_OTA_ReportUpgradeSuccess(h_ota, NULL);
  431. else
  432. packet_id = IOT_OTA_ReportUpgradeFail(h_ota, NULL);
  433. _wait_for_pub_ack(ota_ctx, packet_id);
  434. return upgrade_fetch_success;
  435. }
  436. //static int push_fw_to_fotaPkg_area(char * fw_file_path)
  437. //{
  438. // qlFotaImgProcCtxPtr ctx = NULL;
  439. // QFILE fp = NULL;
  440. // char * file_read_buf = NULL;
  441. // #define FILE_READ_BUF_LEN 1024
  442. // int ret = 0;
  443. // int file_size = 0;
  444. // int file_read_total_len = 0;
  445. // int result = 0;
  446. //
  447. // ctx = ql_fota_init();
  448. // if(!ctx)
  449. // {
  450. // Log_e("*** fota init fail ***");
  451. // goto exit;
  452. // }
  453. //
  454. // Log_d("fota init successfully");
  455. //
  456. // fp = ql_fopen(fw_file_path, "r");
  457. // if(fp<0)
  458. // {
  459. // Log_e("*** fw file open failed ***");
  460. // goto exit;
  461. // }
  462. //
  463. // file_read_buf = malloc(FILE_READ_BUF_LEN);
  464. // if(!file_read_buf)
  465. // {
  466. // Log_e("*** heap memory is not enough ***");
  467. // goto exit;
  468. // }
  469. //
  470. // file_size = ql_fsize(fp);
  471. // if(file_size <= 0)
  472. // {
  473. // Log_e("*** fw file is empty or corrupted ***");
  474. // goto exit;
  475. // }
  476. //
  477. // Log_d("will read fw file and write image to flash");
  478. //
  479. // while((ret = ql_fread(file_read_buf, FILE_READ_BUF_LEN, 1, fp)) > 0)
  480. // {
  481. // file_read_total_len += ret;
  482. //
  483. // ret = ql_fota_image_write(ctx, (void *)file_read_buf, ret);
  484. // if(ret)
  485. // {
  486. // Log_e("*** fw image write fail ***");
  487. // goto exit;
  488. // }
  489. //
  490. // Log_i("fw image write progress: %d%%", file_read_total_len*100/file_size);
  491. // }
  492. //
  493. // if(ret < 0)
  494. // {
  495. // Log_e("*** fw file read fail ***");
  496. // goto exit;
  497. // }
  498. //
  499. // if(file_read_total_len)
  500. // {
  501. // ret = ql_fota_image_flush(ctx);
  502. // if(ret)
  503. // {
  504. // Log_e("*** fw image flush fail ***");
  505. // goto exit;
  506. // }
  507. //
  508. // Log_d("fw image write done, verifing ...");
  509. //
  510. // ret = ql_fota_image_verify(ctx);
  511. // if(ret)
  512. // {
  513. // Log_e("*** fw image verify fail ***");
  514. // goto exit;
  515. // }
  516. //
  517. // Log_d("fw image verify ok !!!");
  518. //
  519. // result = 1;
  520. // }
  521. //
  522. //exit:
  523. // if(ctx) ql_fota_deinit(ctx);
  524. // if(fp>=0) ql_fclose(fp);
  525. // if(file_read_buf) free(file_read_buf);
  526. // return result;
  527. //}
  528. static int datacall_satrt(void)
  529. {
  530. int ret = 0;
  531. int i = 0;
  532. ql_data_call_info_s info;
  533. char ip4_addr_str[16] = {0};
  534. uint8_t nSim = 0;
  535. ql_rtos_task_sleep_s(10);
  536. Log_e("wait for network register done");
  537. while ((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10)
  538. {
  539. i++;
  540. ql_rtos_task_sleep_s(1);
  541. }
  542. if (ret == 0)
  543. {
  544. i = 0;
  545. Log_e("====network registered!!!!====");
  546. }
  547. else
  548. {
  549. Log_e("====network register failure!!!!!====");
  550. goto exit;
  551. }
  552. ql_set_data_call_asyn_mode(nSim, PROFILE_IDX, 0);
  553. Log_e("===start data call====");
  554. ret = ql_start_data_call(nSim, PROFILE_IDX, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
  555. Log_e("===data call result:%d", ret);
  556. if (ret != 0)
  557. {
  558. Log_e("====data call failure!!!!=====");
  559. }
  560. memset(&info, 0x00, sizeof(ql_data_call_info_s));
  561. ret = ql_get_data_call_info(nSim, PROFILE_IDX, &info);
  562. if (ret != 0)
  563. {
  564. Log_e("ql_get_data_call_info ret: %d", ret);
  565. ql_stop_data_call(nSim, PROFILE_IDX);
  566. goto exit;
  567. }
  568. Log_i("info.profile_idx: %d", info.profile_idx);
  569. Log_i("info.ip_version: %d", info.ip_version);
  570. Log_i("info.v4.state: %d", info.v4.state);
  571. //Log_i("info.v4.reconnect: %d", info.v4.reconnect);
  572. inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  573. Log_i("info.v4.addr.ip: %s", ip4_addr_str);
  574. inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  575. Log_i("info.v4.addr.pri_dns: %s", ip4_addr_str);
  576. inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  577. Log_i("info.v4.addr.sec_dns: %s", ip4_addr_str);
  578. return 0;
  579. exit:
  580. return -1;
  581. }
  582. void ota_mqtt_sample(void *param)
  583. {
  584. int rc, result = 0;
  585. OTAContextData *ota_ctx = NULL;
  586. void * mqtt_client = NULL;
  587. void * h_ota = NULL;
  588. IOT_Log_Set_Level(eLOG_DEBUG);
  589. ota_ctx = (OTAContextData *)HAL_Malloc(sizeof(OTAContextData));
  590. if (ota_ctx == NULL) {
  591. Log_e("malloc failed");
  592. goto exit;
  593. }
  594. memset(ota_ctx, 0, sizeof(OTAContextData));
  595. /*执行拨号操作,设备联网*/
  596. if(datacall_satrt() != 0)
  597. {
  598. goto exit;
  599. }
  600. #ifdef DEBUG_DEV_INFO_USED
  601. DeviceInfo devInfo =
  602. {
  603. .product_id = PRODUCT_ID,
  604. .device_name = DEVICE_NAME,
  605. .client_id = ""PRODUCT_ID"_"DEVICE_NAME"",
  606. .region = REGION,
  607. .dev_type = eCOMMON_DEV,
  608. };
  609. #ifndef AUTH_MODE_CERT
  610. device_info_copy(devInfo.device_secret, DEVICE_SECRET,MAX_SIZE_OF_DEVICE_SECRET); // set dev cert file name,
  611. #else
  612. device_info_copy(devInfo.dev_cert_file_name, DEVICE_CERT,MAX_SIZE_OF_DEVICE_CERT_FILE_NAME); // set dev cert file name
  613. device_info_copy(devInfo.dev_key_file_name, DEVICE_PRIVATE,MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME); // set dev cert file name
  614. #endif
  615. HAL_SetDevInfo(&devInfo);
  616. rc = HAL_GetDevInfo((void *)&sg_devInfo);
  617. #else
  618. rc = HAL_GetDevInfoFromFile(DEVICE_INFO_JSON_DOC, (void *)&sg_devInfo);
  619. #endif
  620. if (QCLOUD_RET_SUCCESS != rc) {
  621. Log_e("get device info failed: %d", rc);
  622. goto exit;
  623. }
  624. // setup MQTT init params
  625. MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
  626. rc = _setup_connect_init_params(&init_params, ota_ctx, &sg_devInfo);
  627. if (rc != QCLOUD_RET_SUCCESS) {
  628. Log_e("init params err,rc=%d", rc);
  629. ql_rtos_task_delete(NULL);
  630. }
  631. // create MQTT mqtt_client and connect to server
  632. mqtt_client = IOT_MQTT_Construct(&init_params);
  633. if (mqtt_client != NULL) {
  634. Log_i("Cloud Device Construct Success");
  635. } else {
  636. Log_e("Cloud Device Construct Failed");
  637. ql_rtos_task_delete(NULL);
  638. }
  639. // init OTA handle
  640. h_ota = IOT_OTA_Init(init_params.profile_idx, sg_devInfo.product_id, sg_devInfo.device_name, mqtt_client);
  641. if (NULL == h_ota) {
  642. Log_e("initialize OTA failed");
  643. goto exit;
  644. }
  645. ota_ctx->ota_handle = h_ota;
  646. ota_ctx->mqtt_client = mqtt_client;
  647. bool ota_success;
  648. do {
  649. // mqtt should be ready first
  650. rc = IOT_MQTT_Yield(mqtt_client, 500);
  651. if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
  652. HAL_SleepMs(1000);
  653. continue;
  654. } else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED) {
  655. Log_e("exit with error: %d", rc);
  656. break;
  657. }
  658. // OTA process
  659. ota_success = process_ota(ota_ctx);
  660. if (!ota_success) {
  661. Log_e("OTA failed! Do it again");
  662. HAL_SleepMs(2000);
  663. }
  664. } while (!ota_success);
  665. //result = push_fw_to_fotaPkg_area(ota_ctx->fw_file_path);
  666. exit:
  667. if (NULL != ota_ctx)
  668. {
  669. HAL_Free(ota_ctx);
  670. }
  671. if (NULL != h_ota)
  672. {
  673. IOT_OTA_Destroy(h_ota);
  674. }
  675. if(NULL != mqtt_client)
  676. {
  677. IOT_MQTT_Destroy(&mqtt_client);
  678. }
  679. if(result)
  680. {
  681. Log_d("will restart to update ...");
  682. ql_power_reset(RESET_NORMAL);
  683. }
  684. ql_rtos_task_delete(NULL);
  685. }
  686. //static void ql_nw_status_callback(int profile_idx, int nw_status)
  687. //{
  688. // Log_i("profile(%d) status: %d", profile_idx, nw_status);
  689. //}
  690. //static int datacall_satrt(void)
  691. //{
  692. // struct ql_data_call_info info = {0};
  693. // char ip4_addr_str[16] = {0};
  694. //
  695. // Log_d("wait for network register done");
  696. //
  697. // if(ql_network_register_wait(120) != 0)
  698. // {
  699. // Log_e("*** network register fail ***");
  700. // return -1;
  701. // }
  702. // else
  703. // {
  704. // Log_d("doing network activating ...");
  705. //
  706. // ql_wan_start(ql_nw_status_callback);
  707. // ql_set_auto_connect(PROFILE_IDX, TRUE);
  708. // if(ql_start_data_call(PROFILE_IDX, 0, "3gnet.mnc001.mcc460.gprs", NULL, NULL, 0) == 0)
  709. // {
  710. // ql_get_data_call_info(PROFILE_IDX, 0, &info);
  711. //
  712. // Log_i("info.profile_idx: %d", info.profile_idx);
  713. // Log_i("info.ip_version: %d", info.ip_version);
  714. // Log_i("info.v4.state: %d", info.v4.state);
  715. // Log_i("info.v4.reconnect: %d", info.v4.reconnect);
  716. //
  717. // inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  718. // Log_i("info.v4.addr.ip: %s", ip4_addr_str);
  719. //
  720. // inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  721. // Log_i("info.v4.addr.pri_dns: %s", ip4_addr_str);
  722. //
  723. // inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  724. // Log_i("info.v4.addr.sec_dns: %s", ip4_addr_str);
  725. //
  726. // return 0;
  727. // }
  728. //
  729. // Log_e("*** network activated fail ***");
  730. // return -1;
  731. // }
  732. //}
  733. //int ota_mqtt_sample_start(void)
  734. //{
  735. // ql_task_t ota_mqtt_sample_task = NULL;
  736. //
  737. // if(datacall_satrt() == 0)
  738. // return ql_rtos_task_create(&ota_mqtt_sample_task, 12*1024, 100, "ota_mqtt_sample", main_entry, NULL);
  739. //
  740. // return -1;
  741. //}
  742. int ota_mqtt_sample_start(void)
  743. {
  744. int err = 0;
  745. int count = 0;
  746. ql_task_t ota_mqtt_sample_task = NULL;
  747. /* 主循环进入休眠 */
  748. while (count < 10)
  749. {
  750. count++;
  751. ql_rtos_task_sleep_s(1);
  752. Log_e("ql_qcloud_sdk_ota_mqtt_sample_start_init -0x%04X\n", err);
  753. }
  754. err = ql_rtos_task_create(&ota_mqtt_sample_task, 10*1024, APP_PRIORITY_NORMAL, "ota_mqtt", ota_mqtt_sample, NULL, 5);
  755. if (err != QL_OSI_SUCCESS)
  756. {
  757. return -1;
  758. }
  759. return 0;
  760. }