upacker.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. ******************************************************************************
  3. * @file drv_packer.c
  4. * @author zpw
  5. * @version V1.0
  6. * @date
  7. * @brief 链路层通讯协议
  8. ******************************************************************************
  9. * @attention
  10. * 链路层通讯协议,数据封包解包
  11. ******************************************************************************
  12. */
  13. #include "upacker.h"
  14. using namespace std;
  15. /**
  16. * @brief 使用动态内存时需要初始化
  17. * @note size pack缓存的长度,大于最大的数据包长度就行,使用PACK_SIZE
  18. 无rtos最好用静态内存,不然要改heap
  19. * @param *cmd_packer:
  20. * @param *handler:
  21. * @retval None
  22. */
  23. int Upacker::upacker_init(PACKER_CB handler, PACKER_CB s)
  24. {
  25. #if USE_DYNAMIC_MEM
  26. packer->data = (uint8_t *)UP_MALLOC(MAX_PACK_SIZE);
  27. if (!packer->data)
  28. {
  29. return -1;
  30. }
  31. #endif
  32. cb = handler;
  33. send = s;
  34. return 0;
  35. }
  36. /**
  37. * @brief 封包数据并发送
  38. * @note
  39. * @param *packer:
  40. * @param *buff:
  41. * @param size:
  42. * @retval None
  43. */
  44. void Upacker::upacker_pack(uint8_t *buff, uint16_t size)
  45. {
  46. frame_encode(buff, size);
  47. }
  48. /**
  49. * @brief 解包输入数据
  50. * @note
  51. * @param cmd_packer:
  52. * @param *buff:
  53. * @param size:
  54. * @retval None
  55. */
  56. void Upacker::upacker_unpack(uint8_t *buff, uint16_t size)
  57. {
  58. for (uint16_t i = 0; i < size; i++)
  59. {
  60. if (frame_decode(buff[i]))
  61. {
  62. //解析成功,回调处理
  63. this->cb(this->data, this->flen);
  64. }
  65. }
  66. }
  67. uint8_t Upacker::frame_decode(uint8_t d)
  68. {
  69. if (this->state == 0 && d == STX_L)
  70. {
  71. this->state = 1;
  72. this->calc = 0x55;
  73. }
  74. else if (this->state == 1)
  75. {
  76. this->flen = d;
  77. this->calc ^= d;
  78. this->state = 2;
  79. }
  80. else if (this->state == 2)
  81. {
  82. //长度信息
  83. this->flen |= (uint16_t)d << 8;
  84. this->calc ^= d & 0x3F;
  85. //数据包超长得情况下直接丢包
  86. if ((this->flen & 0x3FFF) > MAX_PACK_SIZE)
  87. {
  88. this->state = 0;
  89. }
  90. this->state = 3;
  91. this->cnt = 0;
  92. }
  93. else if (this->state == 3)
  94. {
  95. //header校验
  96. uint8_t hc = ((d & 0x03) << 4) | ((this->flen & 0xC000) >> 12);
  97. this->check = d;
  98. if(hc != (this->calc & 0X3C)){
  99. this->state = 0;
  100. return 0;
  101. }
  102. this->state = 4;
  103. this->flen &= 0x3FFF;
  104. }
  105. else if (this->state == 4)
  106. {
  107. this->data[this->cnt++] = d;
  108. this->calc ^= d;
  109. if (this->cnt == this->flen)
  110. {
  111. this->state = 0;
  112. //接收完,检查check
  113. if((this->calc & 0xFC) == (this->check & 0XFC)){
  114. return 1;
  115. }else{
  116. return 0;
  117. }
  118. }
  119. }
  120. else
  121. {
  122. this->state = 0;
  123. }
  124. return 0;
  125. }
  126. uint8_t Upacker::frame_encode(uint8_t *data, uint16_t size)
  127. {
  128. uint8_t tmp[4] = {0};
  129. uint8_t crc = 0;
  130. if(size > 16384){
  131. return 0;
  132. }
  133. tmp[0] = 0x55;
  134. tmp[1] = size & 0xff;
  135. tmp[2] = (size >> 8) & 0x3f; //低14位用来保存size;header校验4位
  136. crc = tmp[0] ^ tmp[1] ^ tmp[2];
  137. tmp[2] |= (crc & 0x0C) << 4; //tmp[2][7:6]保存header检验[3:2]
  138. tmp[3] = 0x03 & (crc >> 4) ; //tmp[3][1:0]保存header校验[5:4]
  139. for (int i = 0; i < size; i++)
  140. {
  141. crc ^= data[i];
  142. }
  143. tmp[3] |= (crc & 0xfc) ; //tmp[3][7:2]保存data check[7:2]
  144. this->send(tmp, 4);
  145. this->send(data, size);
  146. return 1;
  147. }