gagent_cloud.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * File : gagent_cloud.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2018-01-03 flyingcys first version
  23. */
  24. #include <rtthread.h>
  25. #include "gagent_def.h"
  26. #include "gagent_cloud.h"
  27. //
  28. #if !defined(PKG_PAHOMQTT_SUBSCRIBE_HANDLERS) || (PKG_PAHOMQTT_SUBSCRIBE_HANDLERS < 2)
  29. #error "must defined PKG_PAHOMQTT_SUBSCRIBE_HANDLERS >= 2 in menuconfig"
  30. #endif
  31. static con_st con; //config info
  32. static gagent_cloud_param con_param = {0};
  33. //
  34. cloud_st *cloud = RT_NULL; //cloud handle
  35. lan_st *lan = RT_NULL; //lan handle
  36. int gagent_cloud_send_packet(rt_uint8_t action, rt_uint8_t *buf, rt_uint16_t buf_len)
  37. {
  38. int rc = RT_EOK;
  39. RT_ASSERT(action != 0);
  40. rc = gagent_mqtt_send_packet(cloud, action, buf, buf_len);
  41. if(rc != RT_EOK)
  42. {
  43. gagent_err("gagent_mqtt_send_packet failed:%d\n", rc);
  44. }
  45. rc = gagent_lan_send_packet(lan, action, buf, buf_len);
  46. if(rc != RT_EOK)
  47. {
  48. gagent_err("gagent_lan_send_packet failed:%d\n", rc);
  49. }
  50. return rc;
  51. }
  52. int gagent_cloud_recv_packet(rt_uint8_t from, rt_uint8_t action, rt_uint8_t *kv, rt_uint16_t kv_len)
  53. {
  54. int rc = RT_EOK;
  55. gagent_dbg("from:%s\n", (from == CMD_FROM_LAN) ? "lan packet" : "mqtt packet");
  56. if(con_param.recv_packet_callback != RT_NULL)
  57. rc = con_param.recv_packet_callback(from, action, kv, kv_len);
  58. return rc;
  59. }
  60. static int gagent_cloud_parse_config(con_st *con)
  61. {
  62. rt_bool_t write_flag = RT_FALSE;
  63. RT_ASSERT(con != RT_NULL);
  64. //read file
  65. memset(con, 0, sizeof(con_st));
  66. if(con_param.read_param_callback(con, sizeof(con_st)) != RT_EOK)
  67. gagent_err("read param failed!\n");
  68. if(con->mac[0] == 0 || memcmp(con->mac, con_param.mac, sizeof(con->mac)) != 0)
  69. {
  70. rt_memset(con->did, 0, sizeof(con->did));
  71. //
  72. rt_memset(con->mac, 0, sizeof(con->mac));
  73. rt_memcpy(con->mac, con_param.mac, sizeof(con->mac) - 1);
  74. write_flag = RT_TRUE;
  75. gagent_dbg("con->mac changed!\n");
  76. }
  77. if(con->pk[0] == 0 || strcmp(con->pk, con_param.product_key) != 0)
  78. {
  79. rt_memset(con->did, 0, sizeof(con->did));
  80. //
  81. rt_memset(con->pk, 0, sizeof(con->pk));
  82. rt_strncpy(con->pk, con_param.product_key, sizeof(con->pk) - 1);
  83. write_flag = RT_TRUE;
  84. gagent_dbg("con->pk changed!\n");
  85. }
  86. if(con->pk_secret[0] == 0 || strcmp(con->pk_secret, con_param.product_secret) != 0)
  87. {
  88. rt_memset(con->did, 0, sizeof(con->did));
  89. //
  90. rt_memset(con->pk_secret, 0, sizeof(con->pk_secret));
  91. rt_strncpy(con->pk_secret, con_param.product_secret, sizeof(con->pk_secret) - 1);
  92. write_flag = RT_TRUE;
  93. gagent_dbg("product secret changed!\n");
  94. }
  95. if(con->hard_version[0] == 0 || strcmp(con->hard_version, HARD_VERSION) != 0)
  96. {
  97. rt_memset(con->hard_version, 0, sizeof(con->hard_version));
  98. rt_strncpy(con->hard_version, HARD_VERSION, sizeof(con->hard_version) - 1);
  99. write_flag = RT_TRUE;
  100. gagent_dbg("hard_version changed!\n");
  101. }
  102. if(con->soft_version[0] == 0 || strcmp(con->soft_version, SOFT_VERSION) != 0)
  103. {
  104. rt_memset(con->soft_version, 0, sizeof(con->soft_version));
  105. rt_strncpy(con->soft_version, SOFT_VERSION, sizeof(con->soft_version) - 1);
  106. write_flag = RT_TRUE;
  107. gagent_dbg("soft_verson changed!\n");
  108. }
  109. if(con->passcode[0] == 0)
  110. {
  111. //passcode is empty
  112. rt_memset(con->passcode, 0, sizeof(con->passcode));
  113. rt_memcpy(con->passcode, con->pk, 10);
  114. write_flag = RT_TRUE;
  115. gagent_dbg("passcode empty!\n");
  116. }
  117. #if (PKG_GAGENT_CLOUD_DEBUG == 1)
  118. {
  119. rt_uint8_t i;
  120. rt_kprintf("mac: ");
  121. for(i = 0; i < MAX_MAC_LEN; i ++)
  122. {
  123. rt_kprintf("%02x ", con->mac[i]);
  124. }
  125. rt_kprintf("\r\n");
  126. rt_kprintf("did:%s\n", con->did);
  127. rt_kprintf("passcode:%s\n", con->passcode);
  128. rt_kprintf("pk:%s\n", con->pk);
  129. rt_kprintf("pk_secret:%s\n", con->pk_secret);
  130. rt_kprintf("hard_version:%s\n", con->hard_version);
  131. rt_kprintf("soft_version:%s\n", con->soft_version);
  132. }
  133. #endif
  134. if(write_flag)
  135. {
  136. gagent_dbg("write param!\n");
  137. con_param.write_param_callback(con, sizeof(con_st));
  138. }
  139. return RT_EOK;
  140. }
  141. static int gagent_cloud_init(cloud_st *cloud)
  142. {
  143. int rc = RT_EOK;
  144. if(cloud->con->did[0] == 0)
  145. {
  146. rt_memset(cloud->con->did, 0, sizeof(cloud->con->did));
  147. rc = gagent_cloud_register(cloud);
  148. if(rc != RT_EOK)
  149. {
  150. gagent_err("gagent_cloud_register failed! errno:%d\n", rc);
  151. return rc;
  152. }
  153. //write param
  154. con_param.write_param_callback(cloud->con, sizeof(con_st));
  155. }
  156. rc = gagent_cloud_provision(cloud);
  157. return RT_EOK;
  158. }
  159. void gagent_cloud_thread(void *parameter)
  160. {
  161. int rc = RT_EOK;
  162. rc = gagent_cloud_parse_config(&con);
  163. if(rc != RT_EOK)
  164. {
  165. gagent_err("gagent_cloud_parse_config failed!\n");
  166. goto __exit;
  167. }
  168. rc = gagent_cloud_init(cloud);
  169. if(cloud == RT_NULL)
  170. {
  171. gagent_err("gagent_cloud_init failed!\n");
  172. goto __exit;
  173. }
  174. rc = gagent_lan_init(lan);
  175. if(rc != RT_EOK)
  176. {
  177. gagent_err("gagent_cloud_lan_init failed!\n");
  178. goto __exit;
  179. }
  180. rc = gagent_mqtt_init(cloud);
  181. if(rc != RT_EOK)
  182. {
  183. gagent_err("gagent_cloud_mqtt_init failed!\n");
  184. goto __exit;
  185. }
  186. rc = gagent_cloud_check_ota(cloud);
  187. __exit:
  188. return;
  189. }
  190. int gagent_cloud_start(gagent_cloud_param *param)
  191. {
  192. int rc = RT_EOK;
  193. rt_thread_t thread = RT_NULL;
  194. RT_ASSERT(param != RT_NULL);
  195. RT_ASSERT(param->product_key[0] != RT_NULL);
  196. RT_ASSERT(param->product_secret[0] != RT_NULL);
  197. RT_ASSERT(param->mac[0] != RT_NULL);
  198. RT_ASSERT(param->read_param_callback != RT_NULL);
  199. RT_ASSERT(param->write_param_callback != RT_NULL);
  200. memset(&con_param, 0, sizeof(con_param));
  201. memcpy(&con_param, param, sizeof(con_param));
  202. cloud = (cloud_st *)rt_malloc(sizeof(cloud_st));
  203. if(RT_NULL == cloud)
  204. {
  205. gagent_err("malloc failed!\n");
  206. rc = -RT_ENOMEM;
  207. goto __exit;
  208. }
  209. rt_memset(cloud, 0, sizeof(cloud_st));
  210. cloud->con = &con;
  211. lan = (lan_st *)rt_malloc(sizeof(lan_st));
  212. if(RT_NULL == lan)
  213. {
  214. gagent_err("malloc failed!\n");
  215. rc = -RT_ENOMEM;
  216. goto __exit;
  217. }
  218. memset(lan, 0, sizeof(lan_st));
  219. lan->con = &con;
  220. thread = rt_thread_create("gagent",
  221. gagent_cloud_thread,
  222. RT_NULL,
  223. 4096,
  224. RT_THREAD_PRIORITY_MAX / 3,
  225. 20);
  226. if(RT_NULL != thread)
  227. {
  228. rt_thread_startup(thread);
  229. }
  230. else
  231. {
  232. rc = -RT_ERROR;
  233. goto __exit;
  234. }
  235. return rc;
  236. __exit:
  237. if(cloud != RT_NULL)
  238. rt_free(cloud);
  239. if(lan != RT_NULL)
  240. rt_free(lan);
  241. return rc;
  242. }