raw_data_sample.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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. #include <signal.h>
  19. #include <stdbool.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "ql_api_osi.h"
  24. #include "ql_api_datacall.h"
  25. #include "qcloud_iot_export.h"
  26. #include "qcloud_iot_import.h"
  27. #include "utils_getopt.h"
  28. #define MAGIC_HEAD_NUM 0x55aa
  29. #define PROFILE_IDX 1
  30. typedef struct _sTestData_ {
  31. uint8_t m_power_switch;
  32. uint8_t m_color;
  33. uint8_t m_brightness;
  34. } sTestData;
  35. typedef struct _sRawDataFrame_ {
  36. uint16_t magic_head;
  37. uint8_t msg_type;
  38. uint8_t res_byte;
  39. uint32_t clientId;
  40. sTestData data;
  41. } sRawDataFrame;
  42. typedef enum {
  43. eMSG_REPORT = 0x01,
  44. eMSG_CONTROL = 0x20,
  45. eMSG_DEFAULT = 0xFF,
  46. } eMsgType;
  47. static uint32_t sg_client_id = 0;
  48. static bool sg_loop_test = true;
  49. #ifdef AUTH_MODE_CERT
  50. static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
  51. static char sg_key_file[PATH_MAX + 1]; // full path of device key file
  52. #endif
  53. static DeviceInfo sg_devInfo;
  54. static int sg_sub_packet_id = -1;
  55. // user's log print callback
  56. static bool log_handler(const char *message)
  57. {
  58. // return true if print success
  59. return false;
  60. }
  61. // MQTT event callback
  62. static void _mqtt_event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
  63. {
  64. MQTTMessage *mqtt_messge = (MQTTMessage *)msg->msg;
  65. uintptr_t packet_id = (uintptr_t)msg->msg;
  66. switch (msg->event_type) {
  67. case MQTT_EVENT_UNDEF:
  68. Log_i("undefined event occur.");
  69. break;
  70. case MQTT_EVENT_DISCONNECT:
  71. Log_i("MQTT disconnect.");
  72. break;
  73. case MQTT_EVENT_RECONNECT:
  74. Log_i("MQTT reconnect.");
  75. break;
  76. case MQTT_EVENT_PUBLISH_RECVEIVED:
  77. Log_i(
  78. "topic message arrived but without any related handle: topic=%.*s, "
  79. "topic_msg=%.*s",
  80. mqtt_messge->topic_len, mqtt_messge->ptopic, mqtt_messge->payload_len, mqtt_messge->payload);
  81. break;
  82. case MQTT_EVENT_SUBCRIBE_SUCCESS:
  83. Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
  84. sg_sub_packet_id = packet_id;
  85. break;
  86. case MQTT_EVENT_SUBCRIBE_TIMEOUT:
  87. Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
  88. sg_sub_packet_id = packet_id;
  89. break;
  90. case MQTT_EVENT_SUBCRIBE_NACK:
  91. Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
  92. sg_sub_packet_id = packet_id;
  93. break;
  94. case MQTT_EVENT_UNSUBCRIBE_SUCCESS:
  95. Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
  96. break;
  97. case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
  98. Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
  99. break;
  100. case MQTT_EVENT_UNSUBCRIBE_NACK:
  101. Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
  102. break;
  103. case MQTT_EVENT_PUBLISH_SUCCESS:
  104. Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
  105. break;
  106. case MQTT_EVENT_PUBLISH_TIMEOUT:
  107. Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
  108. break;
  109. case MQTT_EVENT_PUBLISH_NACK:
  110. Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
  111. break;
  112. default:
  113. Log_i("Should NOT arrive here.");
  114. break;
  115. }
  116. }
  117. // Setup MQTT construct parameters
  118. static int _setup_connect_init_params(MQTTInitParams *initParams)
  119. {
  120. int ret;
  121. ret = HAL_GetDevInfo((void *)&sg_devInfo);
  122. if (QCLOUD_RET_SUCCESS != ret) {
  123. return ret;
  124. }
  125. initParams->region = sg_devInfo.region;
  126. initParams->device_name = sg_devInfo.device_name;
  127. initParams->product_id = sg_devInfo.product_id;
  128. #ifdef AUTH_MODE_CERT
  129. // char certs_dir[PATH_MAX + 1] = "certs";
  130. // char current_path[PATH_MAX + 1];
  131. // char *cwd = getcwd(current_path, sizeof(current_path));
  132. //
  133. // if (cwd == NULL) {
  134. // Log_e("getcwd return NULL");
  135. // return QCLOUD_ERR_FAILURE;
  136. // }
  137. //
  138. //#ifdef WIN32
  139. // sprintf(sg_cert_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
  140. // sprintf(sg_key_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
  141. //#else
  142. // sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
  143. // sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
  144. //#endif
  145. sprintf(sg_cert_file, "%s", sg_devInfo.dev_cert_file_name);
  146. sprintf(sg_key_file, "%s", sg_devInfo.dev_key_file_name);
  147. initParams->cert_file = sg_cert_file;
  148. initParams->key_file = sg_key_file;
  149. #else
  150. initParams->device_secret = sg_devInfo.device_secret;
  151. #endif
  152. initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
  153. initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
  154. initParams->auto_connect_enable = 1;
  155. initParams->event_handle.h_fp = _mqtt_event_handler;
  156. initParams->event_handle.context = NULL;
  157. return QCLOUD_RET_SUCCESS;
  158. }
  159. static void HexDump(uint8_t *pData, uint16_t len)
  160. {
  161. int i;
  162. for (i = 0; i < len; i++) {
  163. if (i % 32 == 0) {
  164. HAL_Printf("\n");
  165. }
  166. HAL_Printf(" %02X", pData[i]);
  167. }
  168. HAL_Printf("\n");
  169. }
  170. // publish raw data msg
  171. static int _publish_raw_data_msg(void *client, QoS qos)
  172. {
  173. sRawDataFrame raw_data;
  174. memset((char *)&raw_data, 0, sizeof(sRawDataFrame));
  175. raw_data.magic_head = MAGIC_HEAD_NUM;
  176. raw_data.msg_type = eMSG_REPORT;
  177. raw_data.clientId = sg_client_id++;
  178. srand((unsigned)HAL_GetTimeMs());
  179. raw_data.data.m_power_switch = 1;
  180. raw_data.data.m_color = rand() % 3;
  181. raw_data.data.m_brightness = rand() % 100;
  182. char topicName[128] = {0};
  183. sprintf(topicName, "$thing/up/raw/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name);
  184. PublishParams pub_params = DEFAULT_PUB_PARAMS;
  185. pub_params.qos = qos;
  186. pub_params.payload = &raw_data;
  187. pub_params.payload_len = sizeof(raw_data);
  188. Log_d("raw_data published dump:");
  189. HexDump((uint8_t *)&raw_data, sizeof(raw_data));
  190. return IOT_MQTT_Publish(client, topicName, &pub_params);
  191. }
  192. // callback when MQTT msg arrives
  193. static void on_raw_data_message_callback(void *pClient, MQTTMessage *message, void *userData)
  194. {
  195. if (message == NULL) {
  196. return;
  197. }
  198. Log_i("Receive Message With topicName:%.*s, payloadlen:%d", (int)message->topic_len, message->ptopic,
  199. (int)message->payload_len);
  200. Log_d("raw_data reveived dump:");
  201. HexDump((uint8_t *)message->payload, (int)message->payload_len);
  202. }
  203. // subscrib MQTT topic
  204. static int _subscribe_raw_data_topic(void *client, QoS qos)
  205. {
  206. static char topic_name[128] = {0};
  207. int size = HAL_Snprintf(topic_name, sizeof(topic_name), "$thing/down/raw/%s/%s", sg_devInfo.product_id,
  208. sg_devInfo.device_name);
  209. if (size < 0 || size > sizeof(topic_name) - 1) {
  210. Log_e("topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_name));
  211. return QCLOUD_ERR_FAILURE;
  212. }
  213. SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
  214. sub_params.qos = qos;
  215. sub_params.on_message_handler = on_raw_data_message_callback;
  216. return IOT_MQTT_Subscribe(client, topic_name, &sub_params);
  217. }
  218. //static int parse_arguments(int argc, char **argv)
  219. //{
  220. // int c;
  221. // while ((c = utils_getopt(argc, argv, "c:l")) != EOF) switch (c) {
  222. // case 'c':
  223. // if (HAL_SetDevInfoFile(utils_optarg))
  224. // return -1;
  225. // break;
  226. //
  227. // case 'l':
  228. // sg_loop_test = true;
  229. // break;
  230. //
  231. // default:
  232. // HAL_Printf(
  233. // "usage: %s [options]\n"
  234. // " [-c <config file for DeviceInfo>] \n"
  235. // " [-l ] loop test or not\n",
  236. // argv[0]);
  237. // return -1;
  238. // }
  239. // return 0;
  240. //}
  241. static int datacall_satrt(void)
  242. {
  243. int ret = 0;
  244. int i = 0;
  245. ql_data_call_info_s info;
  246. char ip4_addr_str[16] = {0};
  247. uint8_t nSim = 0;
  248. ql_rtos_task_sleep_s(10);
  249. Log_e("wait for network register done");
  250. while ((ret = ql_network_register_wait(nSim, 120)) != 0 && i < 10)
  251. {
  252. i++;
  253. ql_rtos_task_sleep_s(1);
  254. }
  255. if (ret == 0)
  256. {
  257. i = 0;
  258. Log_e("====network registered!!!!====");
  259. }
  260. else
  261. {
  262. Log_e("====network register failure!!!!!====");
  263. goto exit;
  264. }
  265. ql_set_data_call_asyn_mode(nSim, PROFILE_IDX, 0);
  266. Log_e("===start data call====");
  267. ret = ql_start_data_call(nSim, PROFILE_IDX, QL_PDP_TYPE_IP, "uninet", NULL, NULL, 0);
  268. Log_e("===data call result:%d", ret);
  269. if (ret != 0)
  270. {
  271. Log_e("====data call failure!!!!=====");
  272. }
  273. memset(&info, 0x00, sizeof(ql_data_call_info_s));
  274. ret = ql_get_data_call_info(nSim, PROFILE_IDX, &info);
  275. if (ret != 0)
  276. {
  277. Log_e("ql_get_data_call_info ret: %d", ret);
  278. ql_stop_data_call(nSim, PROFILE_IDX);
  279. goto exit;
  280. }
  281. Log_i("info.profile_idx: %d", info.profile_idx);
  282. Log_i("info.ip_version: %d", info.ip_version);
  283. Log_i("info.v4.state: %d", info.v4.state);
  284. //Log_i("info.v4.reconnect: %d", info.v4.reconnect);
  285. inet_ntop(AF_INET, &info.v4.addr.ip, ip4_addr_str, sizeof(ip4_addr_str));
  286. Log_i("info.v4.addr.ip: %s", ip4_addr_str);
  287. inet_ntop(AF_INET, &info.v4.addr.pri_dns, ip4_addr_str, sizeof(ip4_addr_str));
  288. Log_i("info.v4.addr.pri_dns: %s", ip4_addr_str);
  289. inet_ntop(AF_INET, &info.v4.addr.sec_dns, ip4_addr_str, sizeof(ip4_addr_str));
  290. Log_i("info.v4.addr.sec_dns: %s", ip4_addr_str);
  291. return 0;
  292. exit:
  293. return -1;
  294. }
  295. void raw_data_sample(void *arg)
  296. {
  297. int rc;
  298. void *client=NULL;
  299. // init log level
  300. IOT_Log_Set_Level(eLOG_DEBUG);
  301. IOT_Log_Set_MessageHandler(log_handler);
  302. /*执行拨号操作,设备联网*/
  303. if(datacall_satrt() != 0)
  304. {
  305. goto exit;
  306. }
  307. // parse arguments for device info file and loop test;
  308. // rc = parse_arguments(argc, argv);
  309. // if (rc != QCLOUD_RET_SUCCESS) {
  310. // Log_e("parse arguments error, rc = %d", rc);
  311. // return rc;
  312. // }
  313. // init connection
  314. MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
  315. rc = _setup_connect_init_params(&init_params);
  316. if (rc != QCLOUD_RET_SUCCESS) {
  317. Log_e("init params error, rc = %d", rc);
  318. goto exit;
  319. }
  320. // create MQTT client and connect with server
  321. client = IOT_MQTT_Construct(&init_params);
  322. if (client != NULL) {
  323. Log_i("Cloud Device Construct Success");
  324. } else {
  325. rc = IOT_MQTT_GetErrCode();
  326. Log_e("MQTT Construct failed, rc = %d", rc);
  327. goto exit;
  328. }
  329. #ifdef SYSTEM_COMM
  330. long time = 0;
  331. // get system timestamp from server
  332. rc = IOT_Get_Sys_Resource(client, eRESOURCE_TIME, &sg_devInfo, &time);
  333. if (QCLOUD_RET_SUCCESS == rc) {
  334. Log_i("system time is %ld", time);
  335. } else {
  336. Log_e("get system time failed!");
  337. }
  338. #endif
  339. // subscribe normal topics here
  340. rc = _subscribe_raw_data_topic(client, QOS1);
  341. if (rc < 0) {
  342. Log_e("Client Subscribe raw data topic Failed: %d", rc);
  343. goto exit;
  344. }
  345. // wait for subscription result
  346. IOT_MQTT_Yield(client, 500);
  347. do {
  348. if (sg_sub_packet_id > 0) {
  349. rc = _publish_raw_data_msg(client, QOS0);
  350. if (rc < 0) {
  351. Log_e("client publish topic failed :%d.", rc);
  352. }
  353. }
  354. rc = IOT_MQTT_Yield(client, 500);
  355. if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
  356. HAL_SleepMs(1000);
  357. continue;
  358. } else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED) {
  359. Log_e("exit with error: %d", rc);
  360. break;
  361. }
  362. if (sg_loop_test)
  363. HAL_SleepMs(5000);
  364. } while (sg_loop_test);
  365. exit:
  366. if(client!=NULL)
  367. {
  368. rc = IOT_MQTT_Destroy(&client);
  369. }
  370. ql_rtos_task_delete(NULL);
  371. }
  372. int raw_data_sample_start(void)
  373. {
  374. int err = 0;
  375. int count = 0;
  376. ql_task_t raw_data_sample_task = NULL;
  377. /* 主循环进入休眠 */
  378. while (count < 10)
  379. {
  380. count++;
  381. ql_rtos_task_sleep_s(1);
  382. Log_e("ql_qcloud_sdk_raw_data_sample_start_init -0x%04X\n", err);
  383. }
  384. err = ql_rtos_task_create(&raw_data_sample_task, 10*1024, APP_PRIORITY_NORMAL, "raw_data_sample", raw_data_sample, NULL, 5);
  385. if (err != QL_OSI_SUCCESS)
  386. {
  387. return -1;
  388. }
  389. return 0;
  390. }