gagent_cloud.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. {
  68. gagent_err("read param failed!\n");
  69. }
  70. if(con->mac[0] == 0 || memcmp(con->mac, con_param.mac, sizeof(con->mac)) != 0)
  71. {
  72. rt_memset(con->did, 0, sizeof(con->did));
  73. //
  74. rt_memset(con->mac, 0, sizeof(con->mac));
  75. rt_memcpy(con->mac, con_param.mac, sizeof(con->mac) - 1);
  76. //
  77. write_flag = RT_TRUE;
  78. gagent_dbg("con->mac changed!\n");
  79. }
  80. if(con->pk[0] == 0 || strcmp(con->pk, con_param.product_key) != 0)
  81. {
  82. rt_memset(con->did, 0, sizeof(con->did));
  83. //
  84. rt_memset(con->pk, 0, sizeof(con->pk));
  85. rt_strncpy(con->pk, con_param.product_key, sizeof(con->pk) - 1);
  86. //
  87. write_flag = RT_TRUE;
  88. gagent_dbg("con->pk changed!\n");
  89. }
  90. if(con->pk_secret[0] == 0 || strcmp(con->pk_secret, con_param.product_secret) != 0)
  91. {
  92. rt_memset(con->did, 0, sizeof(con->did));
  93. //
  94. rt_memset(con->pk_secret, 0, sizeof(con->pk_secret));
  95. rt_strncpy(con->pk_secret, con_param.product_secret, sizeof(con->pk_secret) - 1);
  96. //
  97. write_flag = RT_TRUE;
  98. gagent_dbg("product secret changed!\n");
  99. }
  100. if(con->hard_version[0] == 0 || strcmp(con->hard_version, HARD_VERSION) != 0)
  101. {
  102. rt_memset(con->hard_version, 0, sizeof(con->hard_version));
  103. rt_strncpy(con->hard_version, HARD_VERSION, sizeof(con->hard_version) - 1);
  104. //
  105. write_flag = RT_TRUE;
  106. gagent_dbg("hard_version changed!\n");
  107. }
  108. if(con->soft_version[0] == 0 || strcmp(con->soft_version, SOFT_VERSION) != 0)
  109. {
  110. rt_memset(con->soft_version, 0, sizeof(con->soft_version));
  111. rt_strncpy(con->soft_version, SOFT_VERSION, sizeof(con->soft_version) - 1);
  112. //
  113. write_flag = RT_TRUE;
  114. gagent_dbg("soft_verson changed!\n");
  115. }
  116. if(con->passcode[0] == 0)
  117. {
  118. //passcode is empty
  119. rt_memset(con->passcode, 0, sizeof(con->passcode));
  120. rt_memcpy(con->passcode, con->pk, 10);
  121. //
  122. write_flag = RT_TRUE;
  123. gagent_dbg("passcode empty!\n");
  124. }
  125. #ifdef PKG_GAGENT_CLOUD_DEBUG
  126. {
  127. rt_uint8_t i;
  128. rt_kprintf("mac: ");
  129. for(i = 0; i < MAX_MAC_LEN; i ++)
  130. {
  131. rt_kprintf("%02x ", con->mac[i]);
  132. }
  133. rt_kprintf("\r\n");
  134. rt_kprintf("did:%s\n", con->did);
  135. rt_kprintf("passcode:%s\n", con->passcode);
  136. rt_kprintf("pk:%s\n", con->pk);
  137. rt_kprintf("pk_secret:%s\n", con->pk_secret);
  138. rt_kprintf("hard_version:%s\n", con->hard_version);
  139. rt_kprintf("soft_version:%s\n", con->soft_version);
  140. }
  141. #endif
  142. if(write_flag)
  143. {
  144. gagent_dbg("write param!\n");
  145. con_param.write_param_callback(con, sizeof(con_st));
  146. }
  147. return RT_EOK;
  148. }
  149. static int gagent_cloud_init(cloud_st *cloud)
  150. {
  151. int rc = RT_EOK;
  152. if(cloud->con->did[0] == 0)
  153. {
  154. rt_memset(cloud->con->did, 0, sizeof(cloud->con->did));
  155. rc = gagent_cloud_register(cloud);
  156. if(rc != RT_EOK)
  157. {
  158. gagent_err("gagent_cloud_register failed! errno:%d\n", rc);
  159. return rc;
  160. }
  161. //write param
  162. con_param.write_param_callback(cloud->con, sizeof(con_st));
  163. }
  164. rc = gagent_cloud_provision(cloud);
  165. return RT_EOK;
  166. }
  167. void gagent_cloud_thread(void *parameter)
  168. {
  169. int rc = RT_EOK;
  170. rc = gagent_cloud_parse_config(&con);
  171. if(rc != RT_EOK)
  172. {
  173. gagent_err("gagent_cloud_parse_config failed!\n");
  174. goto __exit;
  175. }
  176. rc = gagent_cloud_init(cloud);
  177. if(cloud == RT_NULL)
  178. {
  179. gagent_err("gagent_cloud_init failed!\n");
  180. goto __exit;
  181. }
  182. rc = gagent_lan_init(lan);
  183. if(rc != RT_EOK)
  184. {
  185. gagent_err("gagent_cloud_lan_init failed!\n");
  186. goto __exit;
  187. }
  188. rc = gagent_mqtt_init(cloud);
  189. if(rc != RT_EOK)
  190. {
  191. gagent_err("gagent_cloud_mqtt_init failed!\n");
  192. goto __exit;
  193. }
  194. rc = gagent_cloud_check_ota(cloud);
  195. __exit:
  196. return;
  197. }
  198. int gagent_cloud_start(gagent_cloud_param *param)
  199. {
  200. int rc = RT_EOK;
  201. rt_thread_t thread = RT_NULL;
  202. RT_ASSERT(param != RT_NULL);
  203. RT_ASSERT(param->product_key[0] != RT_NULL);
  204. RT_ASSERT(param->product_secret[0] != RT_NULL);
  205. RT_ASSERT(param->mac[0] != RT_NULL);
  206. RT_ASSERT(param->read_param_callback != RT_NULL);
  207. RT_ASSERT(param->write_param_callback != RT_NULL);
  208. memset(&con_param, 0, sizeof(con_param));
  209. memcpy(&con_param, param, sizeof(con_param));
  210. cloud = (cloud_st *)rt_malloc(sizeof(cloud_st));
  211. if(RT_NULL == cloud)
  212. {
  213. gagent_err("malloc failed!\n");
  214. rc = -RT_ENOMEM;
  215. goto __exit;
  216. }
  217. rt_memset(cloud, 0, sizeof(cloud_st));
  218. cloud->con = &con;
  219. lan = (lan_st *)rt_malloc(sizeof(lan_st));
  220. if(RT_NULL == lan)
  221. {
  222. gagent_err("malloc failed!\n");
  223. rc = -RT_ENOMEM;
  224. goto __exit;
  225. }
  226. memset(lan, 0, sizeof(lan_st));
  227. lan->con = &con;
  228. thread = rt_thread_create("gagent",
  229. gagent_cloud_thread,
  230. RT_NULL,
  231. 4096,
  232. RT_THREAD_PRIORITY_MAX / 3,
  233. 20);
  234. if(RT_NULL != thread)
  235. {
  236. rt_thread_startup(thread);
  237. }
  238. else
  239. {
  240. rc = -RT_ERROR;
  241. goto __exit;
  242. }
  243. return rc;
  244. __exit:
  245. if(RT_NULL != cloud)
  246. rt_free(cloud);
  247. if(RT_NULL != lan)
  248. rt_free(lan);
  249. return rc;
  250. }