pando_cloud_access.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #include "pando_cloud_access.h"
  2. #include "pando_storage_interface.h"
  3. #include "pando_types.h"
  4. #include "gateway_defs.h"
  5. #include "pando_channel.h"
  6. //#include "pando_system_time.h"
  7. #include "mqtt.h"
  8. #include "sub_device_protocol.h"
  9. #include "pando_protocol.h"
  10. #include "pando_sys.h"
  11. #include "pando_subdevice.h"
  12. #define PORT_STR_LEN 8
  13. #define DEVICE_TOKEN_LEN 8
  14. gateway_callback error_callback = NULL;
  15. uint8_t pando_device_token[DEVICE_TOKEN_LEN];
  16. MQTT_Client mqtt_client;
  17. static uint8_t str_device_id_hex[17];
  18. struct pd_timer send_data_timer;
  19. static int FUNCTION_ATTRIBUTE
  20. conv_addr_str(const char * ip_str, uint8_t * str_ip_addr, int * port)
  21. {
  22. char * colon = NULL;
  23. if ((colon = strchr(ip_str, ':')) == NULL)
  24. {
  25. return -1;
  26. }
  27. // ip address
  28. uint32_t ip_len = colon - ip_str;
  29. pd_strncpy(str_ip_addr, ip_str, ip_len);
  30. str_ip_addr[ip_len] = '\0';
  31. // port
  32. char str_port_addr[PORT_STR_LEN];
  33. pd_strncpy(str_port_addr, colon+1, PORT_STR_LEN);
  34. *port = atoi(str_port_addr);
  35. return 0;
  36. }
  37. static void FUNCTION_ATTRIBUTE
  38. init_gateway_info()
  39. {
  40. // initialize gateway package.
  41. struct protocol_base gateway_info;
  42. pd_memset(&gateway_info, 0, sizeof(gateway_info));
  43. gateway_info.device_id = atol(pando_data_get(DATANAME_DEVICE_ID));
  44. pd_memcpy(gateway_info.token, pando_device_token, DEVICE_TOKEN_LEN);
  45. pd_printf("token:\n");
  46. show_package(gateway_info.token, DEVICE_TOKEN_LEN);
  47. pando_protocol_init(gateway_info);
  48. send_data_timer.interval = 5000;
  49. send_data_timer.repeated = 1;
  50. send_data_timer.timer_cb = report_status;
  51. send_data_timer.timer_no = 2;
  52. }
  53. static void FUNCTION_ATTRIBUTE
  54. pando_publish_data_channel1(uint8_t* buffer, uint16_t length)
  55. {
  56. pd_printf("pando_publish_data_channel1");
  57. struct pando_buffer *gateway_data_buffer = NULL;
  58. uint16_t buf_len = 0;
  59. uint16_t payload_type = 0;
  60. buf_len = GATE_HEADER_LEN + length - sizeof(struct device_header);
  61. gateway_data_buffer = pando_buffer_create(buf_len, GATE_HEADER_LEN - sizeof(struct device_header));
  62. if (gateway_data_buffer->buffer == NULL)
  63. {
  64. pd_printf("%s:malloc failed.\n", __func__);
  65. return;
  66. }
  67. pd_memcpy(gateway_data_buffer->buffer + gateway_data_buffer->offset, buffer, length);
  68. if (pando_protocol_encode(gateway_data_buffer, &payload_type))
  69. {
  70. pd_printf("pando_protocol_encode error.\n");
  71. return;
  72. }
  73. pando_protocol_set_sub_device_id(gateway_data_buffer, 1);
  74. show_package(gateway_data_buffer->buffer, gateway_data_buffer->buff_len);
  75. char topic[2];
  76. switch(payload_type)
  77. {
  78. case PAYLOAD_TYPE_COMMAND:
  79. pd_memcpy(topic, "c", 2);
  80. break;
  81. case PAYLOAD_TYPE_EVENT:
  82. pd_memcpy(topic, "e", 2);
  83. break;
  84. case PAYLOAD_TYPE_DATA:
  85. pd_memcpy(topic, "s", 2);
  86. break;
  87. default:
  88. pd_printf("error payload type\n");
  89. pando_buffer_delete(gateway_data_buffer);
  90. return;
  91. }
  92. if(mqtt_client.connState == MQTT_DATA)
  93. {
  94. MQTT_Publish(&mqtt_client, topic, gateway_data_buffer->buffer, gateway_data_buffer->buff_len, 1, 0);
  95. }
  96. else
  97. {
  98. pd_printf("MQTT state is not avaiable for publish/n");
  99. }
  100. pando_buffer_delete(gateway_data_buffer);
  101. }
  102. static void FUNCTION_ATTRIBUTE
  103. mqtt_data_cb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
  104. {
  105. pd_printf("mqtt_data_cb\n");
  106. pd_printf("mqtt topic length: %d\n", topic_len);
  107. pd_printf("mqtt data length: %d\n", data_len);
  108. uint16_t sub_device_id = 0;
  109. if((topic == NULL) || (data == NULL))
  110. {
  111. pd_printf("no needed mqtt package!");
  112. return;
  113. }
  114. char *topic_buf = (char*)pd_malloc(topic_len+1);
  115. pd_memset(topic_buf, 0 , topic_len + 1);
  116. pd_memcpy(topic_buf, topic, topic_len);
  117. topic_buf[topic_len] = 0;
  118. pd_printf("the topic is: %s\n", topic_buf);
  119. uint8_t payload_type = 0;
  120. switch(*topic_buf)
  121. {
  122. case 's':
  123. payload_type = PAYLOAD_TYPE_DATA;
  124. break;
  125. case 'c':
  126. payload_type = PAYLOAD_TYPE_COMMAND;
  127. break;
  128. case 'e':
  129. payload_type = PAYLOAD_TYPE_EVENT;
  130. break;
  131. case 'd':
  132. payload_type = PAYLOAD_TYPE_DATA;
  133. break;
  134. default:
  135. return;
  136. }
  137. if(topic_buf != NULL)
  138. {
  139. pd_free(topic_buf);
  140. topic_buf = NULL;
  141. }
  142. struct pando_buffer* pd_buffer;
  143. pd_buffer = (struct pando_buffer *)pd_malloc(sizeof(struct pando_buffer));
  144. if(pd_buffer == NULL)
  145. {
  146. pd_printf("malloc error!\n");
  147. return;
  148. }
  149. pd_buffer->buff_len = data_len;
  150. pd_buffer->buffer = (uint8_t*)pd_malloc(data_len);
  151. if(pd_buffer->buffer == NULL)
  152. {
  153. pd_printf("malloc error!\n");
  154. return;
  155. }
  156. pd_memcpy(pd_buffer->buffer, data, data_len);
  157. pd_buffer->offset = 0;
  158. pando_protocol_get_sub_device_id(pd_buffer, &sub_device_id);
  159. pd_printf("package from server, get rid of mqtt head:\n");
  160. show_package(pd_buffer->buffer, pd_buffer->buff_len);
  161. if(pando_protocol_decode(pd_buffer, payload_type) != 0)
  162. {
  163. pd_printf("the data from server is wrong!\n");
  164. return;
  165. }
  166. struct sub_device_buffer *device_buffer = (struct sub_device_buffer *)pd_malloc(sizeof(struct sub_device_buffer));
  167. device_buffer->buffer_length = pd_buffer->buff_len - pd_buffer->offset;
  168. device_buffer->buffer = (uint8_t*)pd_malloc(device_buffer->buffer_length);
  169. pd_memcpy(device_buffer->buffer, pd_buffer->buffer + pd_buffer->offset, device_buffer->buffer_length);
  170. pando_buffer_delete(pd_buffer);
  171. if(sub_device_id == 1 || sub_device_id == 65535) //65535 is broadcast id.
  172. {
  173. pd_printf("transfer data to sub device: %d\n", sub_device_id);
  174. channel_send_to_subdevice(PANDO_CHANNEL_PORT_1, device_buffer->buffer,device_buffer->buffer_length);
  175. }
  176. else if(sub_device_id == 0)
  177. {
  178. channel_send_to_subdevice(PANDO_CHANNEL_PORT_0, device_buffer->buffer,device_buffer->buffer_length);
  179. }
  180. delete_device_package(device_buffer);
  181. }
  182. static void FUNCTION_ATTRIBUTE
  183. mqtt_published_cb(uint32_t *arg)
  184. {
  185. pd_printf("MQTT: Published\r\n");
  186. MQTT_Client* client = (MQTT_Client*)arg;
  187. }
  188. static void FUNCTION_ATTRIBUTE
  189. mqtt_connect_cb(uint32_t* arg)
  190. {
  191. pd_printf("MQTT: Connected\r\n");
  192. MQTT_Client* client = (MQTT_Client*)arg;
  193. on_device_channel_recv(PANDO_CHANNEL_PORT_1, pando_publish_data_channel1);
  194. pando_timer_init(&send_data_timer);
  195. pando_timer_stop(&send_data_timer);
  196. pando_timer_start(&send_data_timer);
  197. }
  198. static void FUNCTION_ATTRIBUTE
  199. mqtt_disconnect_cb(uint32_t* arg)
  200. {
  201. pd_printf("MQTT: Disconnected\r\n");
  202. MQTT_Client* client = (MQTT_Client*)arg;
  203. }
  204. static void FUNCTION_ATTRIBUTE
  205. mqtt_error_cb(uint32_t* arg)
  206. {
  207. pd_printf("MQTT: connecting error\r\n");
  208. if(error_callback != NULL)
  209. {
  210. error_callback(PANDO_ACCESS_ERR);
  211. }
  212. }
  213. /******************************************************************************
  214. * FunctionName : pando_cloud_access
  215. * Description : pando cloud device access api.
  216. * Parameters : callback: the specify access callback function.
  217. * Returns :
  218. *******************************************************************************/
  219. void FUNCTION_ATTRIBUTE
  220. pando_cloud_access(gateway_callback callback)
  221. {
  222. pd_printf("PANDO: begin access cloud...\n");
  223. pd_printf("before access:\n");
  224. if(callback != NULL)
  225. {
  226. error_callback = callback;
  227. }
  228. char* access_addr = pando_data_get(DATANAME_ACCESS_ADDR);
  229. if( NULL == access_addr )
  230. {
  231. pd_printf("no access server address found...\n");
  232. error_callback(PANDO_ACCESS_ERR);
  233. return;
  234. }
  235. int port;
  236. uint8_t ip_string[16];
  237. if(0 != (conv_addr_str(access_addr, ip_string, &port)))
  238. {
  239. pd_printf("wrong access server address...\n");
  240. error_callback(PANDO_ACCESS_ERR);
  241. return;
  242. }
  243. char* str_device_id = pando_data_get(DATANAME_DEVICE_ID);
  244. int device_id = atol(str_device_id); // TODO: device id is 64bit, atol not support.
  245. pd_sprintf(str_device_id_hex, "%x", device_id);
  246. init_gateway_info();
  247. MQTT_InitConnection(&mqtt_client, ip_string, port, 1);
  248. char access_token_str[64];
  249. char* token_str = pando_data_get(DATANAME_ACCESS_TOKEN);
  250. pd_memcpy(access_token_str, token_str, pd_strlen(token_str) + 1);
  251. MQTT_InitClient(&mqtt_client, str_device_id_hex, "", access_token_str, PANDO_KEEPALIVE_TIME, 1);
  252. pd_printf("access str_device_id_hex:%s\n", &str_device_id_hex);
  253. MQTT_OnConnected(&mqtt_client, mqtt_connect_cb);
  254. MQTT_OnDisconnected(&mqtt_client, mqtt_disconnect_cb);
  255. MQTT_OnPublished(&mqtt_client, mqtt_published_cb);
  256. MQTT_OnData(&mqtt_client, mqtt_data_cb);
  257. MQTT_OnConnect_Error(&mqtt_client, mqtt_error_cb);
  258. MQTT_Connect(&mqtt_client);
  259. // to consider: reconnect.
  260. }