Files
ESPC3-wireless/app/drivers/sertrf/protocol/resend_protl.c

276 lines
9.6 KiB
C
Raw Normal View History

2025-09-09 18:16:48 +08:00
#include "resend_protl.h"
void resend_init(resend_device_t *resend_device, int (*send)(void* data, uint16_t len, int timeout), int (*recv)(void* data, uint16_t len, int timeout), int (*get_length )(void), void (*resend_user_parse)(void *resend_device))
{
resend_device->send = send;
resend_device->recv = recv;
resend_device->get_length = get_length;
resend_device->resend_user_parse = resend_user_parse;
resend_device->status.c_state = RESEND_IDLE;
resend_device->tx_frame.header_0 = RESEND_HEADER_0;
resend_device->tx_frame.header_1 = RESEND_HEADER_1;
resend_device->tx_frame.seq = 0;
resend_device->tx_frame.cmd = 0;
resend_device->tx_frame.retry_cnt = 0;
resend_device->tx_frame.len = 0;
resend_device->tx_frame.crc = 0;
}
void resend_set(resend_device_t *resend_device)
{
resend_device->tx_frame.seq = resend_device->rx_frame.seq;
}
int resend_encode(resend_device_t *resend_device, void *out, uint8_t cmd, void* data, uint16_t len)
{
if(!out ) return -1;
uint8_t* c = (uint8_t*)out;
// header
c[0] = resend_device->tx_frame.header_0;
c[1] = resend_device->tx_frame.header_1;
// seq
if(cmd != RESEND_CMD_DATA && cmd != RESEND_CMD_ACK && resend_device->tx_frame.retry_cnt == 0)
resend_device->tx_frame.seq++;
c[2] = resend_device->tx_frame.seq;
// cmd
c[3] = resend_device->tx_frame.cmd = cmd;
// retry_cnt
c[4] = resend_device->tx_frame.retry_cnt;
// len big endian
c[5] = (uint8_t)((len) & 0xFF);
c[6] = (uint8_t)((len >> 8) & 0xFF);
2025-09-09 18:16:48 +08:00
// payload
if (len > 0 && data) memcpy(&c[7], data, len);
// compute crc over seq..payload (i.e. bytes p+1 .. p+5+len)
uint16_t crc = fmav_crc_calculate(&c[2], 5 + len);
c[7 + len] = (uint8_t)(crc & 0xFF);
c[7 + len + 1] = (uint8_t)((crc >> 8) & 0xFF);
2025-09-09 18:16:48 +08:00
return (int)(len + RESEND_MAX_PAYLOAD);
}
int resend_decode(resend_device_t *resend_device, uint8_t c)
{
static uint16_t frame_crc = 0;
switch(resend_device->status.c_state)
{
case RESEND_IDLE:
if (c == RESEND_HEADER_0) {
resend_device->status.c_state = RESEND_HDR;
}
else{
resend_device->status.c_state = RESEND_IDLE;
}
break;
case RESEND_HDR:
if (c == RESEND_HEADER_1) {
resend_device->status.c_state = RESEND_SEQ;
fmav_crc_init(&frame_crc);
}else{
resend_device->status.c_state = RESEND_IDLE;
}
break;
case RESEND_SEQ:
resend_device->rx_frame.seq = c;
fmav_crc_accumulate(&frame_crc, c);
resend_device->status.c_state = RESEND_CMD;
break;
case RESEND_CMD:
resend_device->rx_frame.cmd = c;
fmav_crc_accumulate(&frame_crc, c);
resend_device->status.c_state = RESEND_RETRY_CNT;
break;
case RESEND_RETRY_CNT:
resend_device->rx_frame.retry_cnt = c;
//超过最大允许重传次数
if(resend_device->rx_frame.retry_cnt > RESEND_MAX_RETRY_CNT)
resend_device->status.c_state = RESEND_IDLE;
2025-09-09 18:16:48 +08:00
fmav_crc_accumulate(&frame_crc, c);
resend_device->status.c_state = RESEND_LEN_1;
break;
case RESEND_LEN_1:
resend_device->rx_frame.len = 0;
resend_device->rx_frame.len |= c;
2025-09-09 18:16:48 +08:00
fmav_crc_accumulate(&frame_crc, c);
resend_device->status.c_state = RESEND_LEN_2;
break;
case RESEND_LEN_2:
resend_device->rx_frame.len |= (uint16_t)(c << 8);;
2025-09-09 18:16:48 +08:00
fmav_crc_accumulate(&frame_crc, c);
if(resend_device->rx_frame.len > 0)
{
resend_device->status.data_offset = 0;
resend_device->status.c_state = RESEND_DATA;
//超过允许的字节数
if(resend_device->rx_frame.len > RESEND_DATA_SIZE)
resend_device->status.c_state = RESEND_IDLE;
2025-09-09 18:16:48 +08:00
}
else
resend_device->status.c_state = RESEND_CRC_1;
break;
case RESEND_DATA:
resend_device->rx_frame.payload[resend_device->status.data_offset ++] = c;
fmav_crc_accumulate(&frame_crc, c);
if(resend_device->rx_frame.len == resend_device->status.data_offset){
resend_device->status.data_offset = 0;
resend_device->status.c_state = RESEND_CRC_1;
}
break;
case RESEND_CRC_1:
if((uint8_t)(frame_crc) == c){
2025-09-09 18:16:48 +08:00
resend_device->status.c_state = RESEND_CRC_2;
}else{
resend_device->status.c_state = RESEND_IDLE;
}
break;
case RESEND_CRC_2:
if((uint8_t)(frame_crc >> 8 & 0xFF) == c){
2025-09-09 18:16:48 +08:00
resend_device->status.c_state = RESEND_IDLE;
resend_device->rx_frame.crc = frame_crc;
if(resend_device->rx_frame.cmd != RESEND_CMD_DATA && resend_device->rx_frame.cmd != RESEND_CMD_ACK && resend_device->rx_frame.retry_cnt == 0)
resend_device->tx_frame.seq++;
return 0;
}else{
resend_device->status.c_state = RESEND_IDLE;
}
break;
default:
break;
}
return 1;
}
int resend_recv_data(resend_device_t *resend_device, int timeout)
{
uint8_t data[RESEND_FRAME_SIZE];
int ret = resend_device->recv(data, RESEND_FRAME_SIZE, timeout);
if(ret <= 0)
return -1;
int ret_later = ret;
static uint8_t seq_lat = 0;
while(ret_later --)
{
if(!resend_decode(resend_device, data[ret - ret_later - 1]))
{
// printf("tx_req %d rx_req %d retry_cnt %d cmd %d\r\n", resend_device->tx_frame.seq, resend_device->rx_frame.seq, resend_device->rx_frame.retry_cnt, resend_device->rx_frame.cmd);
2025-09-09 18:16:48 +08:00
if(seq_lat == resend_device->rx_frame.seq){
resend_device->status.resend_flag = 1;
} else {
resend_device->status.resend_flag = 0;
}
resend_device->resend_user_parse(resend_device);
resend_parse_data(resend_device);
seq_lat = resend_device->rx_frame.seq;
}
}
return ret;
}
int resend_send_cmd(resend_device_t *resend_device, uint8_t cmd, int timeout)
{
uint8_t out[RESEND_MAX_PAYLOAD];
int ret = resend_encode(resend_device, out, cmd, NULL, 0);
if (ret <= 0)
return -1;
return resend_device->send(out, ret, timeout);
}
int resend_send_data(resend_device_t *resend_device, uint8_t cmd, void* data, uint16_t len, int timeout)
{
uint8_t out[RESEND_MAX_PAYLOAD + len];
memcpy(resend_device->tx_frame.payload, data, len);
resend_device->tx_frame.retry_cnt = 0;
int ret = resend_encode(resend_device, out, cmd, data, len);
if (ret <= 0)
return -1;
// 初始化ack应答标志位需等待应答
resend_device->status.ack_flag = 1;
while(resend_device->status.ack_flag)
{
if(resend_device->tx_frame.retry_cnt)
{
//进行重发 重新编码
ret = resend_encode(resend_device, out, cmd, data, len);
if (ret <= 0)
return -1;
printf("data retry cnt %d\n", resend_device->tx_frame.retry_cnt);
}
ret = resend_device->send(out, ret, 0);
if(ret < RESEND_MAX_PAYLOAD)
return ret;
// 特殊命令以及应答信号不需要等待
if(cmd == RESEND_CMD_DATA || cmd == RESEND_CMD_ACK)
resend_device->status.ack_flag = 0;
resend_device->tx_frame.retry_cnt ++;
// 接收数据
uint16_t timeout_lat = timeout + 1;
while(timeout_lat --)
{
if(resend_recv_data(resend_device, 0) > 0)
break;
os_thread_sleep(1);
}
2025-09-09 18:16:48 +08:00
// 超过允许的等待次数
if(resend_device->tx_frame.retry_cnt > RESEND_MAX_RETRY_CNT && resend_device->status.ack_flag)
2025-09-09 18:16:48 +08:00
{
printf("timeout cnt max\n");
resend_device->tx_frame.retry_cnt = 0;
resend_device->status.ack_flag = 0;
return -1;
} else if(!resend_device->status.ack_flag){
return ret;
2025-09-09 18:16:48 +08:00
}
}
return ret;
// return resend_device->send(out, resend_frame_encode(resend_device, out, data, len), timeout);
}
int resend_parse_data(resend_device_t *resend_device)
{
switch(resend_device->rx_frame.cmd){
case RESEND_CMD_DATA:
break;
case RESEND_CMD_ACK:
printf("ACK\n");
resend_device->status.ack_flag = 0;
break;
case RESEND_CMD_PARAM:
2025-09-09 18:16:48 +08:00
resend_set(resend_device);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_GET_PARAM:
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
resend_device->handle_flag = RESEND_CMD_GET_PARAM;
break;
case RESEND_CMD_SET_PARAM:
break;
2025-09-09 18:16:48 +08:00
case RESEND_CMD_DATA_ACK:
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_OTA_GET_PARAM:
//针对OTA的应答
resend_device->status.ack_flag = 0;
break;
2025-09-09 18:16:48 +08:00
case RESEND_CMD_OTA_START:
resend_device->handle_flag = RESEND_CMD_OTA_GET_PARAM;
2025-09-09 18:16:48 +08:00
break;
case RESEND_CMD_OTA_DATA:
break;
case RESEND_CMD_OTA_END:
break;
default:
break;
}
return 0;
}