vklink.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-09-29 liuya the first version
  9. */
  10. #include "vklink.h"
  11. #include <my_crc.h>
  12. #include <string.h>
  13. /**
  14. * @brief VK link 消息字节解析
  15. *
  16. * @param msg 消息结构体指针
  17. * @param data 待解析的字节
  18. * @return int 0-未收到一帧 1-收到一帧 -1-校验错误
  19. */
  20. int VKlink_ParseChar(VKlink_Msg_Type *msg, uint8_t data)
  21. {
  22. int ret_val = 0;
  23. switch (msg->rx_stage)
  24. {
  25. case VKLINK_RX_HEAD:
  26. if (VKLINK_MSG_HEAD == data)
  27. {
  28. msg->head = VKLINK_MSG_HEAD;
  29. msg->rx_stage = VKLINK_RX_PAYLOAD_LEN;
  30. }
  31. break;
  32. case VKLINK_RX_PAYLOAD_LEN:
  33. if (data <= sizeof(msg->payload))
  34. {
  35. msg->payload_len = data;
  36. msg->rx_stage = VKLINK_RX_SEQ;
  37. }
  38. else
  39. {
  40. msg->rx_stage = VKLINK_RX_HEAD;
  41. }
  42. break;
  43. case VKLINK_RX_SEQ:
  44. msg->seq = data;
  45. msg->rx_stage = VKLINK_RX_SYSID;
  46. break;
  47. case VKLINK_RX_SYSID:
  48. msg->sysid = data;
  49. msg->rx_stage = VKLINK_RX_COMPID;
  50. break;
  51. case VKLINK_RX_COMPID:
  52. msg->compid = data;
  53. msg->rx_stage = VKLINK_RX_MSGID;
  54. break;
  55. case VKLINK_RX_MSGID:
  56. msg->msgid = data;
  57. if (msg->payload_len > 0)
  58. msg->rx_stage = VKLINK_RX_PAYLOAD;
  59. else
  60. msg->rx_stage = VKLINK_RX_CHECK_LOW;
  61. msg->payload_rx_index = 0;
  62. break;
  63. case VKLINK_RX_PAYLOAD:
  64. msg->payload[msg->payload_rx_index++] = data;
  65. if (msg->payload_rx_index >= msg->payload_len)
  66. {
  67. msg->rx_stage = VKLINK_RX_CHECK_LOW;
  68. msg->payload_rx_index = 0;
  69. }
  70. break;
  71. case VKLINK_RX_CHECK_LOW:
  72. msg->crc16_check = data;
  73. msg->rx_stage = VKLINK_RX_CHECK_HIGH;
  74. break;
  75. case VKLINK_RX_CHECK_HIGH:
  76. {
  77. msg->crc16_check += ((uint16_t)data << 8);
  78. uint16_t crc_check =
  79. crc16_cyc_cal(0xFFFF, &msg->head, sizeof(msg->head));
  80. crc_check = crc16_cyc_cal(crc_check, &msg->payload_len,
  81. sizeof(msg->payload_len));
  82. crc_check = crc16_cyc_cal(crc_check, &msg->seq, sizeof(msg->seq));
  83. crc_check = crc16_cyc_cal(crc_check, &msg->sysid, sizeof(msg->sysid));
  84. crc_check = crc16_cyc_cal(crc_check, &msg->compid, sizeof(msg->compid));
  85. crc_check = crc16_cyc_cal(crc_check, &msg->msgid, sizeof(msg->msgid));
  86. crc_check = crc16_cyc_cal(crc_check, msg->payload, msg->payload_len);
  87. if (msg->crc16_check == crc_check)
  88. {
  89. ret_val = 1;
  90. }
  91. else
  92. {
  93. ret_val = -1;
  94. }
  95. msg->rx_stage = VKLINK_RX_HEAD;
  96. }
  97. break;
  98. default:
  99. msg->rx_stage = VKLINK_RX_HEAD;
  100. break;
  101. }
  102. return ret_val;
  103. }
  104. /**
  105. * @brief 往消息中填入数据
  106. *
  107. * @param pdata 需要填入的数据指针
  108. * @param len
  109. */
  110. int vklink_msg_payload_put_data(VKlink_Msg_Type *msg, const void *pdata,
  111. uint8_t len)
  112. {
  113. int ret_val = 0;
  114. const uint8_t *data = (const uint8_t *)pdata;
  115. for (uint32_t i = 0; i < len; ++i)
  116. {
  117. if (data)
  118. {
  119. msg->payload[msg->payload_len] = data[i];
  120. }
  121. else
  122. {
  123. msg->payload[msg->payload_len] = 0;
  124. }
  125. msg->payload_len++;
  126. ret_val++;
  127. /* 如果超过了最大 payload 长度,则返回 -1 */
  128. if (msg->payload_len > VKLINK_MSG_PAYLOAD_MAX_LEN)
  129. {
  130. ret_val = -1;
  131. break;
  132. }
  133. }
  134. return ret_val;
  135. }
  136. /**
  137. * @brief 将消息逐字节的放入一个buff中
  138. *
  139. * @param msg 消息指针
  140. * @param pTxBuf buff 指针
  141. * @return uint32_t 消息占用的总字节数
  142. */
  143. uint32_t VKlink_MsgTxFormat(const VKlink_Msg_Type *msg, uint8_t *pTxBuf)
  144. {
  145. uint32_t index = 0;
  146. memcpy(pTxBuf + index, &msg->head, sizeof(msg->head));
  147. index += sizeof(msg->head);
  148. memcpy(pTxBuf + index, &msg->payload_len, sizeof(msg->payload_len));
  149. index += sizeof(msg->payload_len);
  150. memcpy(pTxBuf + index, &msg->seq, sizeof(msg->seq));
  151. index += sizeof(msg->seq);
  152. memcpy(pTxBuf + index, &msg->sysid, sizeof(msg->sysid));
  153. index += sizeof(msg->sysid);
  154. memcpy(pTxBuf + index, &msg->compid, sizeof(msg->compid));
  155. index += sizeof(msg->compid);
  156. memcpy(pTxBuf + index, &msg->msgid, sizeof(msg->msgid));
  157. index += sizeof(msg->msgid);
  158. memcpy(pTxBuf + index, msg->payload, msg->payload_len);
  159. index += msg->payload_len;
  160. uint16_t check = crc16_cyc_cal(0xFFFF, pTxBuf, index);
  161. memcpy(pTxBuf + index, &check, sizeof(check));
  162. index += sizeof(check);
  163. return index;
  164. }