ota_mqtt-example.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. * Copyright (c) 2006-2018 RT-Thread Development Team. All rights reserved.
  3. * License-Identifier: Apache-2.0
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  6. * not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <stdarg.h>
  22. #include "iot_import.h"
  23. #include "iot_export.h"
  24. #include "exports/iot_export_ota.h"
  25. #include <rtthread.h>
  26. #if defined(MQTT_ID2_AUTH) && defined(TEST_ID2_DAILY)
  27. #define PRODUCT_KEY "OvNmiEYRDSY"
  28. #define DEVICE_NAME "sh_online_sample_mqtt"
  29. #define DEVICE_SECRET "v9mqGzepKEphLhXmAoiaUIR2HZ7XwTky"
  30. #elif defined(TEST_OTA_PRE)
  31. #define PRODUCT_KEY "6RcIOUafDOm"
  32. #define DEVICE_NAME "sh_pre_sample_mqtt"
  33. #define DEVICE_SECRET "R0OTtD46DSalSpGW7SFzFDIA6fksTC2c"
  34. #elif defined(TEST_MQTT_DAILY)
  35. #define PRODUCT_KEY "fR9zCD4oT72"
  36. #define DEVICE_NAME "ota_test"
  37. #define DEVICE_SECRET "67szT5tQNMIu3sbrd3UwLhs7M73wTHXQ"
  38. #else
  39. #ifdef PKG_USING_ALI_IOTKIT_PRODUCT_KEY
  40. #define PRODUCT_KEY PKG_USING_ALI_IOTKIT_PRODUCT_KEY
  41. #else
  42. #define PRODUCT_KEY "a1dSQSGZ77X"
  43. #endif
  44. #ifdef PKG_USING_ALI_IOTKIT_DEVICE_NAME
  45. #define DEVICE_NAME PKG_USING_ALI_IOTKIT_DEVICE_NAME
  46. #else
  47. #define DEVICE_NAME "z1QKew7MvTmPllgQkDLt"
  48. #endif
  49. #ifdef PKG_USING_ALI_IOTKIT_DEVICE_SECRET
  50. #define DEVICE_SECRET PKG_USING_ALI_IOTKIT_DEVICE_SECRET
  51. #else
  52. #define DEVICE_SECRET "cP7Ml9XYCNL3zMBwPYHXPCa5TPlmMMJt"
  53. #endif
  54. #endif
  55. static char g_product_key[PRODUCT_KEY_LEN + 1];
  56. static char g_device_name[DEVICE_NAME_LEN + 1];
  57. static char g_device_secret[DEVICE_SECRET_LEN + 1];
  58. static char g_ota_version[64] = "iotx_ver_1.0.0";
  59. /* These are pre-defined topics */
  60. #define TOPIC_UPDATE "/"PRODUCT_KEY"/"DEVICE_NAME"/update"
  61. #define TOPIC_ERROR "/"PRODUCT_KEY"/"DEVICE_NAME"/update/error"
  62. #define TOPIC_GET "/"PRODUCT_KEY"/"DEVICE_NAME"/get"
  63. #define TOPIC_DATA "/"PRODUCT_KEY"/"DEVICE_NAME"/data"
  64. #define OTA_MQTT_MSGLEN (2048)
  65. #define EXAMPLE_TRACE(fmt, ...) \
  66. do { \
  67. HAL_Printf("%s|%03d :: ", __func__, __LINE__); \
  68. HAL_Printf(fmt, ##__VA_ARGS__); \
  69. HAL_Printf("%s", "\r\n"); \
  70. } while(0)
  71. static int user_argc;
  72. static uint8_t is_running = 0;
  73. static char* rt_strlwr(char *str)
  74. {
  75. if(str == NULL)
  76. return NULL;
  77. char *p = str;
  78. while (*p != '\0')
  79. {
  80. if(*p >= 'A' && *p <= 'Z')
  81. *p = (*p) + 0x20;
  82. p++;
  83. }
  84. return str;
  85. }
  86. static void event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
  87. {
  88. uintptr_t packet_id = (uintptr_t)msg->msg;
  89. iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
  90. switch (msg->event_type) {
  91. case IOTX_MQTT_EVENT_UNDEF:
  92. EXAMPLE_TRACE("undefined event occur.");
  93. break;
  94. case IOTX_MQTT_EVENT_DISCONNECT:
  95. EXAMPLE_TRACE("MQTT disconnect.");
  96. break;
  97. case IOTX_MQTT_EVENT_RECONNECT:
  98. EXAMPLE_TRACE("MQTT reconnect.");
  99. break;
  100. case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
  101. EXAMPLE_TRACE("subscribe success, packet-id=%u", (unsigned int)packet_id);
  102. break;
  103. case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
  104. EXAMPLE_TRACE("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
  105. break;
  106. case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
  107. EXAMPLE_TRACE("subscribe nack, packet-id=%u", (unsigned int)packet_id);
  108. break;
  109. case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS:
  110. EXAMPLE_TRACE("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
  111. break;
  112. case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
  113. EXAMPLE_TRACE("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
  114. break;
  115. case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK:
  116. EXAMPLE_TRACE("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
  117. break;
  118. case IOTX_MQTT_EVENT_PUBLISH_SUCCESS:
  119. EXAMPLE_TRACE("publish success, packet-id=%u", (unsigned int)packet_id);
  120. break;
  121. case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT:
  122. EXAMPLE_TRACE("publish timeout, packet-id=%u", (unsigned int)packet_id);
  123. break;
  124. case IOTX_MQTT_EVENT_PUBLISH_NACK:
  125. EXAMPLE_TRACE("publish nack, packet-id=%u", (unsigned int)packet_id);
  126. break;
  127. case IOTX_MQTT_EVENT_PUBLISH_RECVEIVED:
  128. EXAMPLE_TRACE("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
  129. topic_info->topic_len,
  130. topic_info->ptopic,
  131. topic_info->payload_len,
  132. topic_info->payload);
  133. break;
  134. default:
  135. EXAMPLE_TRACE("Should NOT arrive here.");
  136. break;
  137. }
  138. }
  139. static int mqtt_client(void)
  140. {
  141. #define OTA_BUF_LEN (5000)
  142. int rc = 0;
  143. void *pclient = NULL, *h_ota = NULL;
  144. iotx_conn_info_pt pconn_info;
  145. iotx_mqtt_param_t mqtt_params;
  146. char *msg_buf = NULL, *msg_readbuf = NULL;
  147. char buf_ota[OTA_BUF_LEN];
  148. if (NULL == (msg_buf = (char *)HAL_Malloc(OTA_MQTT_MSGLEN))) {
  149. EXAMPLE_TRACE("not enough memory");
  150. rc = -1;
  151. goto do_exit;
  152. }
  153. if (NULL == (msg_readbuf = (char *)HAL_Malloc(OTA_MQTT_MSGLEN))) {
  154. EXAMPLE_TRACE("not enough memory");
  155. rc = -1;
  156. goto do_exit;
  157. }
  158. /**< get device info*/
  159. HAL_GetProductKey(g_product_key);
  160. HAL_GetDeviceName(g_device_name);
  161. HAL_GetDeviceSecret(g_device_secret);
  162. /**< end*/
  163. /* Device AUTH */
  164. if (0 != IOT_SetupConnInfo(g_product_key, g_device_name, g_device_secret, (void **)&pconn_info)) {
  165. EXAMPLE_TRACE("AUTH request failed!");
  166. rc = -1;
  167. goto do_exit;
  168. }
  169. /* Initialize MQTT parameter */
  170. memset(&mqtt_params, 0x0, sizeof(mqtt_params));
  171. mqtt_params.port = pconn_info->port;
  172. mqtt_params.host = pconn_info->host_name;
  173. mqtt_params.client_id = pconn_info->client_id;
  174. mqtt_params.username = pconn_info->username;
  175. mqtt_params.password = pconn_info->password;
  176. mqtt_params.pub_key = pconn_info->pub_key;
  177. mqtt_params.request_timeout_ms = 2000;
  178. mqtt_params.clean_session = 0;
  179. mqtt_params.keepalive_interval_ms = 60000;
  180. mqtt_params.pread_buf = msg_readbuf;
  181. mqtt_params.read_buf_size = OTA_MQTT_MSGLEN;
  182. mqtt_params.pwrite_buf = msg_buf;
  183. mqtt_params.write_buf_size = OTA_MQTT_MSGLEN;
  184. mqtt_params.handle_event.h_fp = event_handle;
  185. mqtt_params.handle_event.pcontext = NULL;
  186. /* Convert uppercase letters in host to lowercase */
  187. EXAMPLE_TRACE("host: %s", rt_strlwr((char*)mqtt_params.host));
  188. /* Construct a MQTT client with specify parameter */
  189. pclient = IOT_MQTT_Construct(&mqtt_params);
  190. if (NULL == pclient) {
  191. EXAMPLE_TRACE("MQTT construct failed");
  192. rc = -1;
  193. goto do_exit;
  194. }
  195. h_ota = IOT_OTA_Init(PRODUCT_KEY, DEVICE_NAME, pclient);
  196. if (NULL == h_ota) {
  197. rc = -1;
  198. EXAMPLE_TRACE("initialize OTA failed");
  199. goto do_exit;
  200. }
  201. if (0 != IOT_OTA_ReportVersion(h_ota, g_ota_version)) {
  202. rc = -1;
  203. EXAMPLE_TRACE("report OTA version failed");
  204. goto do_exit;
  205. }
  206. HAL_SleepMs(1000);
  207. do {
  208. uint32_t firmware_valid;
  209. EXAMPLE_TRACE("wait ota upgrade command....");
  210. /* handle the MQTT packet received from TCP or SSL connection */
  211. IOT_MQTT_Yield(pclient, 200);
  212. if (IOT_OTA_IsFetching(h_ota)) {
  213. uint32_t last_percent = 0, percent = 0;
  214. char version[128], md5sum[33];
  215. uint32_t len, size_downloaded, size_file;
  216. do {
  217. len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
  218. if (len > 0) {
  219. EXAMPLE_TRACE("Here write OTA data to file....");
  220. } else {
  221. IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_FAILED, NULL);
  222. EXAMPLE_TRACE("ota fetch fail");
  223. HAL_SleepMs(2000);
  224. }
  225. /* get OTA information */
  226. IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4);
  227. IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4);
  228. IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
  229. IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
  230. last_percent = percent;
  231. percent = (size_downloaded * 100) / size_file;
  232. if (percent - last_percent > 0) {
  233. IOT_OTA_ReportProgress(h_ota, percent, NULL);
  234. IOT_OTA_ReportProgress(h_ota, percent, "hello");
  235. }
  236. IOT_MQTT_Yield(pclient, 100);
  237. } while (!IOT_OTA_IsFetchFinish(h_ota));
  238. IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
  239. if (0 == firmware_valid) {
  240. EXAMPLE_TRACE("The firmware is invalid! Download firmware failed.");
  241. goto do_exit;
  242. } else {
  243. EXAMPLE_TRACE("The firmware is valid! Download firmware successfully.");
  244. snprintf(g_ota_version, sizeof(g_ota_version), "%s", version);
  245. EXAMPLE_TRACE("OTA FW version: %s", g_ota_version);
  246. goto do_exit;
  247. }
  248. }
  249. HAL_SleepMs(2000);
  250. } while (is_running);
  251. do_exit:
  252. if (NULL != h_ota) {
  253. IOT_OTA_Deinit(h_ota);
  254. }
  255. if (NULL != pclient) {
  256. IOT_MQTT_Destroy(&pclient);
  257. }
  258. if (NULL != msg_buf) {
  259. HAL_Free(msg_buf);
  260. }
  261. if (NULL != msg_readbuf) {
  262. HAL_Free(msg_readbuf);
  263. }
  264. /**< end*/
  265. IOT_DumpMemoryStats(IOT_LOG_DEBUG);
  266. IOT_CloseLog();
  267. is_running = 0;
  268. EXAMPLE_TRACE("out of sample!");
  269. return rc;
  270. }
  271. static int ali_ota_main(int argc, char **argv)
  272. {
  273. rt_thread_t tid;
  274. IOT_OpenLog("mqtt");
  275. IOT_SetLogLevel(IOT_LOG_DEBUG);
  276. user_argc = argc;
  277. if (2 == user_argc)
  278. {
  279. if (!strcmp("start", argv[1]))
  280. {
  281. if (1 == is_running)
  282. {
  283. HAL_Printf("OTA test is already running! Please stop running first by using the \"ali_ota_test stop\" command\n");
  284. return 0;
  285. }
  286. is_running = 1;
  287. }
  288. else if (!strcmp("stop", argv[1]))
  289. {
  290. if (0 == is_running)
  291. {
  292. HAL_Printf("OTA test is already stopped!\n");
  293. return 0;
  294. }
  295. is_running = 0;
  296. return 0;
  297. }
  298. else
  299. {
  300. HAL_Printf("Input param error! Example: ali_ota_test start/stop\n");
  301. return 0;
  302. }
  303. }
  304. else
  305. {
  306. HAL_Printf("Input param error! Example: ali_ota_test start/stop\n");
  307. return 0;
  308. }
  309. #ifdef IOTX_PRJ_VERSION
  310. HAL_Printf("iotkit-embedded sdk version: %s\n", IOTX_PRJ_VERSION);
  311. #endif
  312. /**< set device info*/
  313. HAL_SetProductKey(PRODUCT_KEY);
  314. HAL_SetDeviceName(DEVICE_NAME);
  315. HAL_SetDeviceSecret(DEVICE_SECRET);
  316. tid = rt_thread_create("ali-ota",
  317. (void*)mqtt_client, NULL,
  318. 12 * 1024, RT_THREAD_PRIORITY_MAX / 2 - 1, 10);
  319. if (tid != RT_NULL)
  320. rt_thread_startup(tid);
  321. return 0;
  322. }
  323. #ifdef RT_USING_FINSH
  324. #include <finsh.h>
  325. MSH_CMD_EXPORT_ALIAS(ali_ota_main, ali_ota_test, Example: ali_ota_test);
  326. #endif