mqtt-example.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Copyright (c) 2014-2016 Alibaba Group. 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. #if defined(MQTT_ID2_AUTH) && defined(ON_DAILY)
  25. #define PRODUCT_KEY "9rx2yMNV5l0"
  26. #define DEVICE_NAME "sh_online_sample_mqtt"
  27. #define DEVICE_SECRET "v9mqGzepKEphLhXmAoiaUIR2HZ7XwTky"
  28. #elif defined(ON_DAILY)
  29. #define PRODUCT_KEY "gsYfsxQJgeD"
  30. #define DEVICE_NAME "DailyEnvDN"
  31. #define DEVICE_SECRET "y1vzFkEgcuXnvkAfm627pwarx4HRNikX"
  32. #elif defined(MQTT_ID2_AUTH)
  33. #define PRODUCT_KEY "micKUvuzOps"
  34. #define DEVICE_NAME "00AAAAAABBBBBB4B645F5800"
  35. #define DEVICE_SECRET "v9mqGzepKEphLhXmAoiaUIR2HZ7XwTky"
  36. #else
  37. #define PRODUCT_KEY "yfTuLfBJTiL"
  38. #define DEVICE_NAME "TestDeviceForDemo"
  39. #define DEVICE_SECRET "fSCl9Ns5YPnYN8Ocg0VEel1kXFnRlV6c"
  40. #endif
  41. char __product_key[PRODUCT_KEY_LEN + 1];
  42. char __device_name[DEVICE_NAME_LEN + 1];
  43. char __device_secret[DEVICE_SECRET_LEN + 1];
  44. /* These are pre-defined topics */
  45. #define TOPIC_UPDATE "/"PRODUCT_KEY"/"DEVICE_NAME"/update"
  46. #define TOPIC_ERROR "/"PRODUCT_KEY"/"DEVICE_NAME"/update/error"
  47. #define TOPIC_GET "/"PRODUCT_KEY"/"DEVICE_NAME"/get"
  48. #define TOPIC_DATA "/"PRODUCT_KEY"/"DEVICE_NAME"/data"
  49. /* These are pre-defined topics format*/
  50. #define TOPIC_UPDATE_FMT "/%s/%s/update"
  51. #define TOPIC_ERROR_FMT "/%s/%s/update/error"
  52. #define TOPIC_GET_FMT "/%s/%s/get"
  53. #define TOPIC_DATA_FMT "/%s/%s/data"
  54. #define MQTT_MSGLEN (1024)
  55. #define EXAMPLE_TRACE(fmt, ...) \
  56. do { \
  57. HAL_Printf("%s|%03d :: ", __func__, __LINE__); \
  58. HAL_Printf(fmt, ##__VA_ARGS__); \
  59. HAL_Printf("%s", "\r\n"); \
  60. } while(0)
  61. static int user_argc;
  62. static char **user_argv;
  63. void event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
  64. {
  65. uintptr_t packet_id = (uintptr_t)msg->msg;
  66. iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
  67. switch (msg->event_type) {
  68. case IOTX_MQTT_EVENT_UNDEF:
  69. EXAMPLE_TRACE("undefined event occur.");
  70. break;
  71. case IOTX_MQTT_EVENT_DISCONNECT:
  72. EXAMPLE_TRACE("MQTT disconnect.");
  73. break;
  74. case IOTX_MQTT_EVENT_RECONNECT:
  75. EXAMPLE_TRACE("MQTT reconnect.");
  76. break;
  77. case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
  78. EXAMPLE_TRACE("subscribe success, packet-id=%u", (unsigned int)packet_id);
  79. break;
  80. case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
  81. EXAMPLE_TRACE("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
  82. break;
  83. case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
  84. EXAMPLE_TRACE("subscribe nack, packet-id=%u", (unsigned int)packet_id);
  85. break;
  86. case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS:
  87. EXAMPLE_TRACE("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
  88. break;
  89. case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
  90. EXAMPLE_TRACE("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
  91. break;
  92. case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK:
  93. EXAMPLE_TRACE("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
  94. break;
  95. case IOTX_MQTT_EVENT_PUBLISH_SUCCESS:
  96. EXAMPLE_TRACE("publish success, packet-id=%u", (unsigned int)packet_id);
  97. break;
  98. case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT:
  99. EXAMPLE_TRACE("publish timeout, packet-id=%u", (unsigned int)packet_id);
  100. break;
  101. case IOTX_MQTT_EVENT_PUBLISH_NACK:
  102. EXAMPLE_TRACE("publish nack, packet-id=%u", (unsigned int)packet_id);
  103. break;
  104. case IOTX_MQTT_EVENT_PUBLISH_RECVEIVED:
  105. EXAMPLE_TRACE("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
  106. topic_info->topic_len,
  107. topic_info->ptopic,
  108. topic_info->payload_len,
  109. topic_info->payload);
  110. break;
  111. case IOTX_MQTT_EVENT_BUFFER_OVERFLOW:
  112. EXAMPLE_TRACE("buffer overflow, %s", msg->msg);
  113. break;
  114. default:
  115. EXAMPLE_TRACE("Should NOT arrive here.");
  116. break;
  117. }
  118. }
  119. static void _demo_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
  120. {
  121. iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
  122. /* print topic name and topic message */
  123. EXAMPLE_TRACE("----");
  124. EXAMPLE_TRACE("packetId: %d", ptopic_info->packet_id);
  125. EXAMPLE_TRACE("Topic: '%.*s' (Length: %d)",
  126. ptopic_info->topic_len,
  127. ptopic_info->ptopic,
  128. ptopic_info->topic_len);
  129. EXAMPLE_TRACE("Payload: '%.*s' (Length: %d)",
  130. ptopic_info->payload_len,
  131. ptopic_info->payload,
  132. ptopic_info->payload_len);
  133. EXAMPLE_TRACE("----");
  134. }
  135. #ifndef MQTT_ID2_AUTH
  136. int mqtt_client(void)
  137. {
  138. int rc = 0, msg_len, cnt = 0;
  139. void *pclient;
  140. iotx_conn_info_pt pconn_info;
  141. iotx_mqtt_param_t mqtt_params;
  142. iotx_mqtt_topic_info_t topic_msg;
  143. char msg_pub[128];
  144. char *msg_buf = NULL, *msg_readbuf = NULL;
  145. if (NULL == (msg_buf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
  146. EXAMPLE_TRACE("not enough memory");
  147. rc = -1;
  148. goto do_exit;
  149. }
  150. if (NULL == (msg_readbuf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
  151. EXAMPLE_TRACE("not enough memory");
  152. rc = -1;
  153. goto do_exit;
  154. }
  155. HAL_GetProductKey(__product_key);
  156. HAL_GetDeviceName(__device_name);
  157. HAL_GetDeviceSecret(__device_secret);
  158. /* Device AUTH */
  159. if (0 != IOT_SetupConnInfo(__product_key, __device_name, __device_secret, (void **)&pconn_info)) {
  160. EXAMPLE_TRACE("AUTH request failed!");
  161. rc = -1;
  162. goto do_exit;
  163. }
  164. /* Initialize MQTT parameter */
  165. memset(&mqtt_params, 0x0, sizeof(mqtt_params));
  166. mqtt_params.port = pconn_info->port;
  167. mqtt_params.host = pconn_info->host_name;
  168. mqtt_params.client_id = pconn_info->client_id;
  169. mqtt_params.username = pconn_info->username;
  170. mqtt_params.password = pconn_info->password;
  171. mqtt_params.pub_key = pconn_info->pub_key;
  172. mqtt_params.request_timeout_ms = 2000;
  173. mqtt_params.clean_session = 0;
  174. mqtt_params.keepalive_interval_ms = 60000;
  175. mqtt_params.pread_buf = msg_readbuf;
  176. mqtt_params.read_buf_size = MQTT_MSGLEN;
  177. mqtt_params.pwrite_buf = msg_buf;
  178. mqtt_params.write_buf_size = MQTT_MSGLEN;
  179. mqtt_params.handle_event.h_fp = event_handle;
  180. mqtt_params.handle_event.pcontext = NULL;
  181. /* Construct a MQTT client with specify parameter */
  182. pclient = IOT_MQTT_Construct(&mqtt_params);
  183. if (NULL == pclient) {
  184. EXAMPLE_TRACE("MQTT construct failed");
  185. rc = -1;
  186. goto do_exit;
  187. }
  188. /* Initialize topic information */
  189. memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
  190. strcpy(msg_pub, "update: hello! start!");
  191. topic_msg.qos = IOTX_MQTT_QOS1;
  192. topic_msg.retain = 0;
  193. topic_msg.dup = 0;
  194. topic_msg.payload = (void *)msg_pub;
  195. topic_msg.payload_len = strlen(msg_pub);
  196. rc = IOT_MQTT_Publish(pclient, TOPIC_UPDATE, &topic_msg);
  197. if (rc < 0) {
  198. IOT_MQTT_Destroy(&pclient);
  199. EXAMPLE_TRACE("error occur when publish");
  200. rc = -1;
  201. goto do_exit;
  202. }
  203. EXAMPLE_TRACE("\n publish message: \n topic: %s\n payload: \%s\n rc = %d", TOPIC_UPDATE, topic_msg.payload, rc);
  204. /* Subscribe the specific topic */
  205. rc = IOT_MQTT_Subscribe(pclient, TOPIC_DATA, IOTX_MQTT_QOS1, _demo_message_arrive, NULL);
  206. if (rc < 0) {
  207. IOT_MQTT_Destroy(&pclient);
  208. EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc);
  209. rc = -1;
  210. goto do_exit;
  211. }
  212. /* Initialize topic information */
  213. memset(msg_pub, 0x0, 128);
  214. strcpy(msg_pub, "data: hello! start!");
  215. memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
  216. topic_msg.qos = IOTX_MQTT_QOS1;
  217. topic_msg.retain = 0;
  218. topic_msg.dup = 0;
  219. topic_msg.payload = (void *)msg_pub;
  220. topic_msg.payload_len = strlen(msg_pub);
  221. rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg);
  222. EXAMPLE_TRACE("\n publish message: \n topic: %s\n payload: \%s\n rc = %d", TOPIC_DATA, topic_msg.payload, rc);
  223. IOT_MQTT_Yield(pclient, 200);
  224. do {
  225. /* Generate topic message */
  226. cnt++;
  227. msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt);
  228. if (msg_len < 0) {
  229. EXAMPLE_TRACE("Error occur! Exit program");
  230. rc = -1;
  231. break;
  232. }
  233. topic_msg.payload = (void *)msg_pub;
  234. topic_msg.payload_len = msg_len;
  235. rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg);
  236. if (rc < 0) {
  237. EXAMPLE_TRACE("error occur when publish");
  238. rc = -1;
  239. break;
  240. }
  241. #ifdef MQTT_ID2_CRYPTO
  242. EXAMPLE_TRACE("packet-id=%u, publish topic msg='0x%02x%02x%02x%02x'...",
  243. (uint32_t)rc,
  244. msg_pub[0], msg_pub[1], msg_pub[2], msg_pub[3]
  245. );
  246. #else
  247. EXAMPLE_TRACE("packet-id=%u, publish topic msg=%s", (uint32_t)rc, msg_pub);
  248. #endif
  249. /* handle the MQTT packet received from TCP or SSL connection */
  250. IOT_MQTT_Yield(pclient, 200);
  251. /* infinite loop if running with 'loop' argument */
  252. if (user_argc >= 2 && !strcmp("loop", user_argv[1])) {
  253. HAL_SleepMs(2000);
  254. cnt = 0;
  255. }
  256. } while (cnt < 1);
  257. IOT_MQTT_Yield(pclient, 200);
  258. IOT_MQTT_Unsubscribe(pclient, TOPIC_DATA);
  259. IOT_MQTT_Yield(pclient, 200);
  260. IOT_MQTT_Destroy(&pclient);
  261. do_exit:
  262. if (NULL != msg_buf) {
  263. HAL_Free(msg_buf);
  264. }
  265. if (NULL != msg_readbuf) {
  266. HAL_Free(msg_readbuf);
  267. }
  268. return rc;
  269. }
  270. #endif /* MQTT_ID2_AUTH */
  271. #ifdef MQTT_ID2_AUTH
  272. #include "tfs.h"
  273. char __device_id2[TFS_ID2_LEN + 1];
  274. int mqtt_client_secure()
  275. {
  276. int rc = 0, msg_len, cnt = 0;
  277. void *pclient;
  278. iotx_conn_info_pt pconn_info;
  279. iotx_mqtt_param_t mqtt_params;
  280. iotx_mqtt_topic_info_t topic_msg;
  281. char msg_pub[128];
  282. char *msg_buf = NULL, *msg_readbuf = NULL;
  283. char topic_update[IOTX_URI_MAX_LEN] = {0};
  284. char topic_error[IOTX_URI_MAX_LEN] = {0};
  285. char topic_get[IOTX_URI_MAX_LEN] = {0};
  286. char topic_data[IOTX_URI_MAX_LEN] = {0};
  287. if (NULL == (msg_buf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
  288. EXAMPLE_TRACE("not enough memory");
  289. rc = -1;
  290. goto do_exit;
  291. }
  292. if (NULL == (msg_readbuf = (char *)HAL_Malloc(MQTT_MSGLEN))) {
  293. EXAMPLE_TRACE("not enough memory");
  294. rc = -1;
  295. goto do_exit;
  296. }
  297. HAL_GetProductKey(__product_key);
  298. HAL_GetID2(__device_id2);
  299. /* Device AUTH */
  300. rc = IOT_SetupConnInfoSecure(__product_key, __device_id2, __device_id2, (void **)&pconn_info);
  301. if (rc != 0) {
  302. EXAMPLE_TRACE("AUTH request failed!");
  303. goto do_exit;
  304. }
  305. HAL_Snprintf(topic_update,IOTX_URI_MAX_LEN,TOPIC_UPDATE_FMT,__product_key,__device_id2);
  306. HAL_Snprintf(topic_error,IOTX_URI_MAX_LEN,TOPIC_ERROR_FMT,__product_key,__device_id2);
  307. HAL_Snprintf(topic_get,IOTX_URI_MAX_LEN,TOPIC_GET_FMT,__product_key,__device_id2);
  308. HAL_Snprintf(topic_data,IOTX_URI_MAX_LEN,TOPIC_DATA_FMT,__product_key,__device_id2);
  309. /* Initialize MQTT parameter */
  310. memset(&mqtt_params, 0x0, sizeof(mqtt_params));
  311. mqtt_params.port = pconn_info->port;
  312. mqtt_params.host = pconn_info->host_name;
  313. mqtt_params.client_id = pconn_info->client_id;
  314. mqtt_params.username = pconn_info->username;
  315. mqtt_params.password = pconn_info->password;
  316. mqtt_params.pub_key = pconn_info->pub_key;
  317. mqtt_params.request_timeout_ms = 2000;
  318. mqtt_params.clean_session = 0;
  319. mqtt_params.keepalive_interval_ms = 60000;
  320. mqtt_params.pread_buf = msg_readbuf;
  321. mqtt_params.read_buf_size = MQTT_MSGLEN;
  322. mqtt_params.pwrite_buf = msg_buf;
  323. mqtt_params.write_buf_size = MQTT_MSGLEN;
  324. mqtt_params.handle_event.h_fp = event_handle;
  325. mqtt_params.handle_event.pcontext = NULL;
  326. /* Construct a MQTT client with specify parameter */
  327. pclient = IOT_MQTT_ConstructSecure(&mqtt_params);
  328. if (NULL == pclient) {
  329. EXAMPLE_TRACE("MQTT construct failed");
  330. rc = -1;
  331. goto do_exit;
  332. }
  333. /* Subscribe the specific topic */
  334. rc = IOT_MQTT_Subscribe(pclient, topic_data, IOTX_MQTT_QOS1, _demo_message_arrive, NULL);
  335. if (rc < 0) {
  336. IOT_MQTT_Destroy(&pclient);
  337. EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc);
  338. rc = -1;
  339. goto do_exit;
  340. }
  341. HAL_SleepMs(1000);
  342. /* Initialize topic information */
  343. memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
  344. strcpy(msg_pub, "message: hello! start!");
  345. topic_msg.qos = IOTX_MQTT_QOS1;
  346. topic_msg.retain = 0;
  347. topic_msg.dup = 0;
  348. topic_msg.payload = (void *)msg_pub;
  349. topic_msg.payload_len = strlen(msg_pub);
  350. rc = IOT_MQTT_Publish(pclient, topic_data, &topic_msg);
  351. EXAMPLE_TRACE("rc = IOT_MQTT_Publish() = %d", rc);
  352. do {
  353. /* Generate topic message */
  354. cnt++;
  355. msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt);
  356. if (msg_len < 0) {
  357. EXAMPLE_TRACE("Error occur! Exit program");
  358. rc = -1;
  359. break;
  360. }
  361. topic_msg.payload = (void *)msg_pub;
  362. topic_msg.payload_len = msg_len;
  363. rc = IOT_MQTT_Publish(pclient, topic_data, &topic_msg);
  364. if (rc < 0) {
  365. EXAMPLE_TRACE("error occur when publish");
  366. rc = -1;
  367. break;
  368. }
  369. EXAMPLE_TRACE("packet-id=%u, publish topic msg='0x%02x%02x%02x%02x'...",
  370. (uint32_t)rc,
  371. msg_pub[0], msg_pub[1], msg_pub[2], msg_pub[3]
  372. );
  373. /* handle the MQTT packet received from TCP or SSL connection */
  374. IOT_MQTT_Yield(pclient, 200);
  375. /* infinite loop if running with 'loop' argument */
  376. if (user_argc >= 2 && !strcmp("loop", user_argv[1])) {
  377. HAL_SleepMs(2000);
  378. cnt = 0;
  379. }
  380. } while (cnt < 1);
  381. IOT_MQTT_Unsubscribe(pclient, TOPIC_DATA);
  382. HAL_SleepMs(200);
  383. IOT_MQTT_Destroy(&pclient);
  384. do_exit:
  385. if (NULL != msg_buf) {
  386. HAL_Free(msg_buf);
  387. }
  388. if (NULL != msg_readbuf) {
  389. HAL_Free(msg_readbuf);
  390. }
  391. return rc;
  392. }
  393. #endif /* MQTT_ID2_AUTH*/
  394. int main(int argc, char **argv)
  395. {
  396. IOT_OpenLog("mqtt");
  397. IOT_SetLogLevel(IOT_LOG_DEBUG);
  398. user_argc = argc;
  399. user_argv = argv;
  400. HAL_SetProductKey(PRODUCT_KEY);
  401. HAL_SetDeviceName(DEVICE_NAME);
  402. HAL_SetDeviceSecret(DEVICE_SECRET);
  403. #ifndef MQTT_ID2_AUTH
  404. mqtt_client();
  405. #else
  406. mqtt_client_secure();
  407. #endif
  408. IOT_DumpMemoryStats(IOT_LOG_DEBUG);
  409. IOT_CloseLog();
  410. EXAMPLE_TRACE("out of sample!");
  411. return 0;
  412. }