pando_protocol.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*******************************************************
  2. * File name: pando_protocol.c
  3. * Author: LIJIAN
  4. * Versions: 0.1
  5. * Description: APIs for access device layer to manipulate packets.
  6. * History:
  7. * 1.Date:
  8. * Author:
  9. * Modification:
  10. *********************************************************/
  11. #include "pando_protocol.h"
  12. #include "../platform/include/pando_sys.h"
  13. static int FUNCTION_ATTRIBUTE check_pdbin_header(struct mqtt_bin_header *bin_header);
  14. static int FUNCTION_ATTRIBUTE init_device_header(struct device_header *header, struct mqtt_bin_header *bin_header,
  15. uint16_t payload_type, uint16_t payload_len);
  16. static int FUNCTION_ATTRIBUTE init_pdbin_header(struct mqtt_bin_header *bin_header, struct device_header *header);
  17. typedef long long unsigned int llui;
  18. struct protocol_base protocol_tool_base_params;
  19. static int file_cmd_sequence; //need to be array when there are sub devices more than one.
  20. struct pando_buffer * FUNCTION_ATTRIBUTE pando_buffer_create(int length, int offset)
  21. {
  22. struct pando_buffer *protocol_buffer = (struct pando_buffer *)pd_malloc(sizeof(struct pando_buffer));
  23. if (protocol_buffer == NULL)
  24. {
  25. return NULL;
  26. }
  27. protocol_buffer->buff_len = length;
  28. protocol_buffer->offset = offset;
  29. protocol_buffer->buffer = (uint8_t *)pd_malloc(protocol_buffer->buff_len);
  30. if (protocol_buffer->buffer == NULL)
  31. {
  32. pd_free(protocol_buffer);
  33. return NULL;
  34. }
  35. pd_memset(protocol_buffer->buffer, 0, protocol_buffer->buff_len);
  36. return protocol_buffer;
  37. }
  38. void FUNCTION_ATTRIBUTE pando_buffer_delete(struct pando_buffer *pdbuf)
  39. {
  40. if (pdbuf == NULL)
  41. {
  42. return;
  43. }
  44. if (pdbuf->buffer != NULL)
  45. {
  46. pd_free(pdbuf->buffer);
  47. }
  48. pd_free(pdbuf);
  49. }
  50. int FUNCTION_ATTRIBUTE pando_protocol_decode(struct pando_buffer *pdbuf, uint16_t payload_type)
  51. {
  52. //get valid data position of buffer
  53. uint8_t *position = pdbuf->buffer + pdbuf->offset;
  54. uint8_t *pdbuf_end = pdbuf->buffer + pdbuf->buff_len;
  55. struct device_header sub_device_header;
  56. struct mqtt_bin_header *m_header = (struct mqtt_bin_header *)position;
  57. //check token
  58. if (check_pdbin_header(m_header))
  59. {
  60. return -1;
  61. }
  62. position += GATE_HEADER_LEN;
  63. if (position > pdbuf_end)
  64. {
  65. pd_printf("Incorrect decode buffer length.\n");
  66. return -1;
  67. }
  68. init_device_header(&sub_device_header, m_header, payload_type,
  69. pdbuf->buff_len - pdbuf->offset);
  70. //point to sub device packet header in the buffer
  71. position -= DEV_HEADER_LEN;
  72. pd_memcpy(position, &sub_device_header, DEV_HEADER_LEN);
  73. //now from offset to the end of buffer, is sub device packet to send
  74. pdbuf->offset = pdbuf->offset + GATE_HEADER_LEN - DEV_HEADER_LEN;
  75. return 0;
  76. }
  77. int FUNCTION_ATTRIBUTE pando_protocol_encode(struct pando_buffer *pdbuf, uint16_t *payload_type)
  78. {
  79. uint8_t *position = pdbuf->buffer + pdbuf->offset;
  80. uint8_t *buffer_end = pdbuf->buffer + pdbuf->buff_len;
  81. struct mqtt_bin_header m_header;
  82. struct device_header sub_device_header;
  83. struct device_header *header = (struct device_header*)position;
  84. if ((position += DEV_HEADER_LEN) > buffer_end)
  85. {
  86. pd_printf("Incorrect encode buffer length.\n");
  87. return -1;
  88. }
  89. pd_memcpy((void*)payload_type, (void*)&(header->payload_type), sizeof(header->payload_type));
  90. *payload_type = net16_to_host(*payload_type);
  91. pd_memcpy((void*)&(sub_device_header.flags), (void*)&(header->flags), sizeof(header->flags));
  92. sub_device_header.flags = net16_to_host(sub_device_header.flags);
  93. if (init_pdbin_header(&m_header, &sub_device_header))
  94. {
  95. pd_printf("Init pdbin header failed.\n");
  96. return -1;
  97. }
  98. position -= GATE_HEADER_LEN;
  99. pd_memcpy(position, &m_header, GATE_HEADER_LEN);
  100. pdbuf->offset = pdbuf->offset + DEV_HEADER_LEN - GATE_HEADER_LEN;
  101. return 0;
  102. }
  103. int FUNCTION_ATTRIBUTE check_pdbin_header(struct mqtt_bin_header *bin_header)
  104. {
  105. if (pd_memcmp(bin_header->token, protocol_tool_base_params.token, sizeof(protocol_tool_base_params.token)))
  106. {
  107. pd_printf("Token error.\n");
  108. return -1;
  109. }
  110. return 0;
  111. }
  112. int FUNCTION_ATTRIBUTE init_device_header(struct device_header *header, struct mqtt_bin_header *bin_header,
  113. uint16_t payload_type, uint16_t payload_len)
  114. {
  115. protocol_tool_base_params.sub_device_cmd_seq++;
  116. header->frame_seq = host32_to_net(protocol_tool_base_params.sub_device_cmd_seq);
  117. header->magic = MAGIC_HEAD_SUB_DEVICE;
  118. header->crc = 0x46;
  119. header->flags = host16_to_net(bin_header->flags);
  120. header->payload_len = host16_to_net(payload_len);
  121. header->payload_type = host16_to_net(payload_type);
  122. return 0;
  123. }
  124. int FUNCTION_ATTRIBUTE init_pdbin_header(struct mqtt_bin_header *bin_header, struct device_header *header)
  125. {
  126. bin_header->flags = host16_to_net(header->flags);
  127. bin_header->timestamp = host64_to_net((uint64_t)pd_get_timestamp());
  128. pd_memcpy(bin_header->token, protocol_tool_base_params.token,
  129. sizeof(protocol_tool_base_params.token));
  130. return 0;
  131. }
  132. int FUNCTION_ATTRIBUTE pando_protocol_init(struct protocol_base init_params)
  133. {
  134. if ((struct protocol_base *)pd_memcpy(&protocol_tool_base_params, &init_params, sizeof(init_params)) == NULL)
  135. {
  136. pd_printf("pando_protocol_init failed.\n");
  137. return -1;
  138. }
  139. return 0;
  140. }
  141. int FUNCTION_ATTRIBUTE pando_protocol_get_sub_device_id(struct pando_buffer *buf, uint16_t *sub_device_id)
  142. {
  143. uint8_t *pos = buf->buffer + GATE_HEADER_LEN + buf->offset;
  144. if (pos == NULL)
  145. {
  146. pd_printf("subdevice null\n");
  147. return -1;
  148. }
  149. else
  150. {
  151. pd_memcpy(sub_device_id, pos, sizeof(*sub_device_id));
  152. *sub_device_id = net16_to_host(*sub_device_id);
  153. return 0;
  154. }
  155. }
  156. int FUNCTION_ATTRIBUTE pando_protocol_set_sub_device_id(struct pando_buffer *buf, uint16_t sub_device_id)
  157. {
  158. uint8_t *pos = buf->buffer + GATE_HEADER_LEN + buf->offset;
  159. if (pos == NULL)
  160. {
  161. pd_printf("subdevice null\n");
  162. return -1;
  163. }
  164. else
  165. {
  166. pd_printf("set sub_device_id %d\n", sub_device_id);
  167. sub_device_id = host16_to_net(sub_device_id);
  168. pd_memcpy(pos, &sub_device_id, sizeof(sub_device_id));
  169. return 0;
  170. }
  171. #if 0
  172. uint8_t *pos = NULL;
  173. int rc = 0;
  174. uint16_t tmp_devid = sub_device_id;
  175. pos = buf->buffer + GATE_HEADER_LEN + buf->offset;
  176. if (buf == NULL || sub_device_id > 127*128)
  177. {
  178. INFO("subdevice null, subdevice id :%d\n", sub_device_id);
  179. return -1;
  180. }
  181. else
  182. {
  183. INFO("sub_device_id %d\n", sub_device_id);
  184. do
  185. {
  186. char d = tmp_devid % 128;
  187. tmp_devid /= 128;
  188. /* if there are more digits to encode, set the top bit of this digit */
  189. if (tmp_devid > 0)
  190. d |= 0x80;
  191. pos[rc++] = d;
  192. } while (tmp_devid > 0);
  193. /* sub device using 2 bytes space.*/
  194. if (rc == 1)
  195. {
  196. for(;pos >= buf->buffer; pos--)
  197. {
  198. *(pos + 1) = *pos;
  199. }
  200. buf->offset += 1;
  201. }
  202. return 0;
  203. }
  204. #endif
  205. }
  206. uint64_t FUNCTION_ATTRIBUTE pando_protocol_get_cmd_sequence()
  207. {
  208. return protocol_tool_base_params.command_sequence;
  209. }
  210. void FUNCTION_ATTRIBUTE save_file_sequence()
  211. {
  212. file_cmd_sequence = protocol_tool_base_params.sub_device_cmd_seq;
  213. }
  214. int FUNCTION_ATTRIBUTE is_file_feedback(uint32_t sequence)
  215. {
  216. return (sequence == file_cmd_sequence)?1:0;
  217. }
  218. #if 0
  219. char *FUNCTION_ATTRIBUTE pando_protocol_get_uri(struct pando_buffer *pdbuf)
  220. {
  221. if (pdbuf == NULL)
  222. {
  223. return NULL;
  224. }
  225. struct sub_device_buffer device_buffer;
  226. device_buffer.buffer_length = pdbuf->buff_len - pdbuf->offset;
  227. device_buffer.buffer = pdbuf->buffer + pdbuf->offset;
  228. struct pando_command cmd_body;
  229. struct TLV *cmd_param = get_sub_device_command(&device_buffer, &cmd_body);
  230. int i = 0;
  231. uint16_t tlv_type, tlv_length;
  232. for (i = 0; i < cmd_body.params->count; i++)
  233. {
  234. pd_memcpy(&tlv_type, &(cmd_param->type), sizeof(tlv_type));
  235. tlv_type = net16_to_host(tlv_type);
  236. pd_memcpy(&tlv_length, &(cmd_param->length), sizeof(tlv_length));
  237. tlv_length = net16_to_host(tlv_length);
  238. if (tlv_type == TLV_TYPE_URI)
  239. {
  240. return (char *)cmd_param->value;
  241. }
  242. cmd_param = (struct TLV *)((uint8_t *)cmd_param + sizeof(struct TLV) + tlv_length);
  243. }
  244. return NULL;
  245. }
  246. #endif
  247. //pdbuf points to the buffer contains command from server ,it's big endian.
  248. uint16_t FUNCTION_ATTRIBUTE pando_protocol_get_payload_type(struct pando_buffer *pdbuf)
  249. {
  250. struct device_header *gateway_header;
  251. if (pdbuf == NULL)
  252. {
  253. return -1;
  254. }
  255. gateway_header = (struct device_header *)(pdbuf->buffer + pdbuf->offset);
  256. return net16_to_host(gateway_header->payload_type);
  257. }
  258. int FUNCTION_ATTRIBUTE is_pando_file_command(struct pando_buffer *pdbuf)
  259. {
  260. struct mqtt_bin_header *header = (struct mqtt_bin_header *)(pdbuf->buffer + pdbuf->offset);
  261. if (header->flags == 1)
  262. {
  263. return 1;
  264. }
  265. else
  266. {
  267. return 0;
  268. }
  269. }
  270. uint8_t FUNCTION_ATTRIBUTE *pando_get_package_begin(struct pando_buffer *buf)
  271. {
  272. return (buf->buffer + buf->offset);
  273. }
  274. uint16_t FUNCTION_ATTRIBUTE pando_get_package_length(struct pando_buffer *buf)
  275. {
  276. return (buf->buff_len - buf->offset);
  277. }