/* * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2020-09-29 liuya the first version */ #include "vklink.h" #include #include /** * @brief VK link 消息字节解析 * * @param msg 消息结构体指针 * @param data 待解析的字节 * @return int 0-未收到一帧 1-收到一帧 -1-校验错误 */ int VKlink_ParseChar(VKlink_Msg_Type *msg, uint8_t data) { int ret_val = 0; switch (msg->rx_stage) { case VKLINK_RX_HEAD: if (VKLINK_MSG_HEAD == data) { msg->head = VKLINK_MSG_HEAD; msg->rx_stage = VKLINK_RX_PAYLOAD_LEN; } break; case VKLINK_RX_PAYLOAD_LEN: if (data <= sizeof(msg->payload)) { msg->payload_len = data; msg->rx_stage = VKLINK_RX_SEQ; } else { msg->rx_stage = VKLINK_RX_HEAD; } break; case VKLINK_RX_SEQ: msg->seq = data; msg->rx_stage = VKLINK_RX_SYSID; break; case VKLINK_RX_SYSID: msg->sysid = data; msg->rx_stage = VKLINK_RX_COMPID; break; case VKLINK_RX_COMPID: msg->compid = data; msg->rx_stage = VKLINK_RX_MSGID; break; case VKLINK_RX_MSGID: msg->msgid = data; if (msg->payload_len > 0) msg->rx_stage = VKLINK_RX_PAYLOAD; else msg->rx_stage = VKLINK_RX_CHECK_LOW; msg->payload_rx_index = 0; break; case VKLINK_RX_PAYLOAD: msg->payload[msg->payload_rx_index++] = data; if (msg->payload_rx_index >= msg->payload_len) { msg->rx_stage = VKLINK_RX_CHECK_LOW; msg->payload_rx_index = 0; } break; case VKLINK_RX_CHECK_LOW: msg->crc16_check = data; msg->rx_stage = VKLINK_RX_CHECK_HIGH; break; case VKLINK_RX_CHECK_HIGH: { msg->crc16_check += ((uint16_t)data << 8); uint16_t crc_check = crc16_cyc_cal(0xFFFF, &msg->head, sizeof(msg->head)); crc_check = crc16_cyc_cal(crc_check, &msg->payload_len, sizeof(msg->payload_len)); crc_check = crc16_cyc_cal(crc_check, &msg->seq, sizeof(msg->seq)); crc_check = crc16_cyc_cal(crc_check, &msg->sysid, sizeof(msg->sysid)); crc_check = crc16_cyc_cal(crc_check, &msg->compid, sizeof(msg->compid)); crc_check = crc16_cyc_cal(crc_check, &msg->msgid, sizeof(msg->msgid)); crc_check = crc16_cyc_cal(crc_check, msg->payload, msg->payload_len); if (msg->crc16_check == crc_check) { ret_val = 1; } else { ret_val = -1; } msg->rx_stage = VKLINK_RX_HEAD; } break; default: msg->rx_stage = VKLINK_RX_HEAD; break; } return ret_val; } /** * @brief 往消息中填入数据 * * @param pdata 需要填入的数据指针 * @param len */ int vklink_msg_payload_put_data(VKlink_Msg_Type *msg, const void *pdata, uint8_t len) { int ret_val = 0; const uint8_t *data = (const uint8_t *)pdata; for (uint32_t i = 0; i < len; ++i) { if (data) { msg->payload[msg->payload_len] = data[i]; } else { msg->payload[msg->payload_len] = 0; } msg->payload_len++; ret_val++; /* 如果超过了最大 payload 长度,则返回 -1 */ if (msg->payload_len > VKLINK_MSG_PAYLOAD_MAX_LEN) { ret_val = -1; break; } } return ret_val; } /** * @brief 将消息逐字节的放入一个buff中 * * @param msg 消息指针 * @param pTxBuf buff 指针 * @return uint32_t 消息占用的总字节数 */ uint32_t VKlink_MsgTxFormat(const VKlink_Msg_Type *msg, uint8_t *pTxBuf) { uint32_t index = 0; memcpy(pTxBuf + index, &msg->head, sizeof(msg->head)); index += sizeof(msg->head); memcpy(pTxBuf + index, &msg->payload_len, sizeof(msg->payload_len)); index += sizeof(msg->payload_len); memcpy(pTxBuf + index, &msg->seq, sizeof(msg->seq)); index += sizeof(msg->seq); memcpy(pTxBuf + index, &msg->sysid, sizeof(msg->sysid)); index += sizeof(msg->sysid); memcpy(pTxBuf + index, &msg->compid, sizeof(msg->compid)); index += sizeof(msg->compid); memcpy(pTxBuf + index, &msg->msgid, sizeof(msg->msgid)); index += sizeof(msg->msgid); memcpy(pTxBuf + index, msg->payload, msg->payload_len); index += msg->payload_len; uint16_t check = crc16_cyc_cal(0xFFFF, pTxBuf, index); memcpy(pTxBuf + index, &check, sizeof(check)); index += sizeof(check); return index; }