pando_cloud_access.c 8.4 KB

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