439 lines
11 KiB
C++
439 lines
11 KiB
C++
|
//-------------------------------------------------------------------------------
|
|||
|
// File Name: comm.cpp
|
|||
|
// Brief:
|
|||
|
// Version: 1.0.0
|
|||
|
// Create Date: 2017/05/08
|
|||
|
// Create by: Marshal Lee
|
|||
|
// Copyright:
|
|||
|
// Copyright (c) 2017, Richpeace Co., LTD.
|
|||
|
// All rights reserved.
|
|||
|
//
|
|||
|
// Modify by: Marshal Lee
|
|||
|
// Modify Date: 2017/05/08
|
|||
|
//-------------------------------------------------------------------------------
|
|||
|
|
|||
|
#define _IN_COMM_CPP
|
|||
|
|
|||
|
#include "comm.h"
|
|||
|
#include "crc16.h"
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
|
|||
|
// 读空缓冲区
|
|||
|
void readBuffEmpty(DataExFuns * funs)
|
|||
|
{
|
|||
|
int rslt, len;
|
|||
|
u8 temp;
|
|||
|
|
|||
|
len = funs->getRsvLen();
|
|||
|
|
|||
|
while (len > 0)
|
|||
|
{
|
|||
|
rslt = funs->getCommData(&temp, 1);
|
|||
|
if (rslt != 1)
|
|||
|
{
|
|||
|
rslt = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
len--;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
// 功能: 从通讯口接收缓冲区中得到一个数据包, 如果有附加数据,包括附加数据
|
|||
|
// 参数: pPacket, 数据包指针
|
|||
|
// 返回: >=0, 成功取得一个数据包,包括定长数据包和可变长度数据包,返回值为数据包长度
|
|||
|
// -1, 参数错误
|
|||
|
// -2, CRC错误
|
|||
|
// -3, 数据不足
|
|||
|
// -4, 没有找到同步序列
|
|||
|
// -5,等待接收数据超时
|
|||
|
// -6, 数据包参数错误
|
|||
|
// -7, 附加数据CRC错误
|
|||
|
// -8, 发生未知错误
|
|||
|
|
|||
|
// 结果: 如果正确取得数据包,或通讯口没有命令, 循环队列尾指针回向后移动
|
|||
|
|
|||
|
int getANormalPacket(DataExFuns * funs, DataPacket * pPacket)
|
|||
|
{
|
|||
|
int rslt, len;
|
|||
|
int i;
|
|||
|
int phase;
|
|||
|
int status;
|
|||
|
int exlen;
|
|||
|
static int rdstatus = 0;
|
|||
|
static u8 odBuf[LEN_NORMAL_PACKET];
|
|||
|
|
|||
|
u8 temp;
|
|||
|
u8 rdBuf[LEN_NORMAL_PACKET];
|
|||
|
DataPacket * pDat;
|
|||
|
|
|||
|
u8 getBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
|
|||
|
int getBuflen;
|
|||
|
int getIdx;
|
|||
|
|
|||
|
u8 tmpBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
|
|||
|
int tmpBuflen;
|
|||
|
|
|||
|
if (funs == NULL || pPacket == NULL)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
rslt = 0;
|
|||
|
i = 0; // 扫描字节计数器
|
|||
|
getBuflen = 0;
|
|||
|
getIdx = 0;
|
|||
|
tmpBuflen = 0;
|
|||
|
pDat = (DataPacket *)rdBuf;
|
|||
|
|
|||
|
if (rdstatus == 0)
|
|||
|
{
|
|||
|
do
|
|||
|
{
|
|||
|
len = funs->getRsvLen(); // 得到接收长度
|
|||
|
len += getBuflen; // 加上已经获取的长度
|
|||
|
|
|||
|
if (len < LEN_NORMAL_PACKET)
|
|||
|
{
|
|||
|
rslt = -3;
|
|||
|
break; // 没有足够数据
|
|||
|
}
|
|||
|
|
|||
|
phase = 0;
|
|||
|
status = 0;
|
|||
|
rslt = 0;
|
|||
|
|
|||
|
// 从接收缓冲区中找数据包
|
|||
|
while(((len + phase) >= LEN_NORMAL_PACKET) && (phase < LEN_NORMAL_PACKET))
|
|||
|
{
|
|||
|
if (getBuflen == 0)
|
|||
|
{
|
|||
|
if (phase == 0 && i > MAX_ONCE_SCAN)
|
|||
|
{
|
|||
|
rslt = -4;
|
|||
|
break; // 查找同步序列超出最大单次扫描字节数
|
|||
|
}
|
|||
|
|
|||
|
rslt = funs->getCommData(&temp, 1);
|
|||
|
if (rslt != 1)
|
|||
|
{
|
|||
|
printf("error at GetCommData rslt\r\n");
|
|||
|
rslt = -8;
|
|||
|
break;
|
|||
|
}
|
|||
|
rslt = 0;
|
|||
|
i++; // 扫描字数增加
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
temp = getBuf[getIdx];
|
|||
|
getIdx++;
|
|||
|
getBuflen--;
|
|||
|
}
|
|||
|
|
|||
|
len--; // 剩余长度减小
|
|||
|
|
|||
|
pDat->buff.normal[phase] = temp;
|
|||
|
if (phase < DP_SYNC_LEN) // 识别同步序列
|
|||
|
{
|
|||
|
tmpBuflen = 0;
|
|||
|
|
|||
|
if (phase == 0)
|
|||
|
{
|
|||
|
if (temp == FLDP_SYNC[0])
|
|||
|
{
|
|||
|
status = 1;
|
|||
|
}
|
|||
|
else if (temp == VLDP_SYNC[0])
|
|||
|
{
|
|||
|
status = 2;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
status = 0;
|
|||
|
phase = 0;
|
|||
|
rslt = 0; // 非同步序列
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (status == 1)
|
|||
|
{
|
|||
|
if (temp != FLDP_SYNC[phase])
|
|||
|
{
|
|||
|
status = 0;
|
|||
|
phase = 0;
|
|||
|
rslt = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (status == 2)
|
|||
|
{
|
|||
|
if (temp != VLDP_SYNC[phase])
|
|||
|
{
|
|||
|
status = 0;
|
|||
|
phase = 0;
|
|||
|
rslt = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("error status in GetANormalPacket\r\n");
|
|||
|
rslt = -8;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
tmpBuf[tmpBuflen] = temp;
|
|||
|
tmpBuflen++;
|
|||
|
}
|
|||
|
|
|||
|
phase++;
|
|||
|
}
|
|||
|
|
|||
|
if (rslt != 0)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (phase >= LEN_NORMAL_PACKET) // 得到数据包
|
|||
|
{
|
|||
|
u16 crc;
|
|||
|
crc = calcCrc16(pDat->normal.content, DP_CONT_LEN);
|
|||
|
if (crc == pDat->normal.crc)
|
|||
|
{
|
|||
|
// 得到正确数据包
|
|||
|
memcpy(pPacket, pDat, LEN_NORMAL_PACKET);
|
|||
|
|
|||
|
// printf("GetANormalPacket ok\r\n");
|
|||
|
rslt = LEN_NORMAL_PACKET;
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// CRC 不正确
|
|||
|
printf("crc error in GetANormalPacket\r\n");
|
|||
|
// 拷贝需要再判断的数据
|
|||
|
if (tmpBuflen != 0)
|
|||
|
{
|
|||
|
memcpy(getBuf, tmpBuf, tmpBuflen);
|
|||
|
}
|
|||
|
getBuflen = tmpBuflen;
|
|||
|
getIdx = 0;
|
|||
|
// continue;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 没有找到同步序列的情况
|
|||
|
getBuflen = 0;
|
|||
|
getIdx = 0;
|
|||
|
// continue;
|
|||
|
}
|
|||
|
}while(1);
|
|||
|
}
|
|||
|
|
|||
|
if (rdstatus == 1)
|
|||
|
{
|
|||
|
memcpy(pPacket, odBuf, LEN_NORMAL_PACKET);
|
|||
|
rslt = LEN_NORMAL_PACKET;
|
|||
|
}
|
|||
|
|
|||
|
// 附加数据
|
|||
|
if (rslt == LEN_NORMAL_PACKET)
|
|||
|
{
|
|||
|
if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0) // 是可变长度数据包
|
|||
|
{
|
|||
|
exlen = pPacket->vldp.exlen;
|
|||
|
if (exlen > MAX_EXDP_LEN)
|
|||
|
{
|
|||
|
printf("data exlen error, len=%d\r\n", exlen);
|
|||
|
return -6; // 数据包参数错误
|
|||
|
}
|
|||
|
|
|||
|
memset(pPacket->buff.exData, 0, MAX_EXDP_LEN);
|
|||
|
|
|||
|
i = 0;
|
|||
|
status = 0; // 作为历史计数器
|
|||
|
// 读取附加数据
|
|||
|
do
|
|||
|
{
|
|||
|
rslt = funs->getCommData(pPacket->buff.exData, exlen);
|
|||
|
if (rslt == exlen)
|
|||
|
{
|
|||
|
u16 crc;
|
|||
|
// 校验CRC
|
|||
|
crc = calcCrc16(pPacket->buff.exData, exlen);
|
|||
|
if (crc == pPacket->vldp.excrc)
|
|||
|
{
|
|||
|
// printf("get exdata ok\r\n");
|
|||
|
rslt = exlen+LEN_NORMAL_PACKET;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("crc error at get exdata\r\n");
|
|||
|
rslt = -7; // CRC错误
|
|||
|
}
|
|||
|
rdstatus = 0;
|
|||
|
break; // 得到数据
|
|||
|
}
|
|||
|
else if (rslt == 0)
|
|||
|
{
|
|||
|
memcpy(odBuf, pPacket, LEN_NORMAL_PACKET);
|
|||
|
rdstatus = 1;
|
|||
|
rslt = -3;
|
|||
|
break;
|
|||
|
/*
|
|||
|
// 数据不足
|
|||
|
if (funs->delay != NULL)
|
|||
|
{
|
|||
|
funs->delay(1); // 延时等待
|
|||
|
}
|
|||
|
len = funs->getRsvLen(); // 得到接收数据长度
|
|||
|
qDebug()<<"getRsvLen"<<len;
|
|||
|
if (len != status) // 和上次长度比较
|
|||
|
{
|
|||
|
status = len;
|
|||
|
i = 0;
|
|||
|
}
|
|||
|
else // 如果没有变化,则计数器增加
|
|||
|
{
|
|||
|
i++;
|
|||
|
if (i > GTEX_TIME_OUT) // 如果无变化计数器值大于超时值
|
|||
|
{
|
|||
|
qDebug()<<"call GetCommData timeout";
|
|||
|
rslt = -5;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
*/
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
qDebug()<<"error after call GetCommData";
|
|||
|
break;
|
|||
|
}
|
|||
|
}while(1);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
return rslt;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
|
|||
|
// 功能: 添加数据到发送队列中, 通过通讯口发送数据
|
|||
|
// 参数: pPacket, 需要发送的数据,已经正确存放在了相应字段。
|
|||
|
// 结果:
|
|||
|
// 0, 可以发送, 添加到了发送数据队列中
|
|||
|
// -1, 参数错误
|
|||
|
// -2,发送错误
|
|||
|
// 1, 队列已满, 不能发送
|
|||
|
int sendAPacket(DataExFuns * funs, DataPacket * pPacket)
|
|||
|
{
|
|||
|
int rslt;
|
|||
|
int freelen, sendlen;
|
|||
|
|
|||
|
if (pPacket == NULL)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
if (memcmp(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN) == 0)
|
|||
|
{
|
|||
|
sendlen = LEN_NORMAL_PACKET;
|
|||
|
}
|
|||
|
else if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0)
|
|||
|
{
|
|||
|
sendlen = LEN_NORMAL_PACKET + pPacket->vldp.exlen;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("para err, not a corrected packet\r\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
freelen = funs->getTrsFreeLen();
|
|||
|
|
|||
|
if (freelen < sendlen)
|
|||
|
{
|
|||
|
// printf("buff is full in SendAPacket\r\n");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
rslt = funs->sendCommData(pPacket->datbuff, sendlen);
|
|||
|
if (rslt != sendlen)
|
|||
|
{
|
|||
|
printf("error at call SendCommData, rslt=%d\r\n", rslt);
|
|||
|
return -2;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
|
|||
|
// 功能: 打包一个固定长度数据包
|
|||
|
// 参数:
|
|||
|
// pPacket, 需要打包的数据包,其中除了sync和crc的部分已经就绪
|
|||
|
// 结果:
|
|||
|
// 0, 打包好数据
|
|||
|
// -1, 参数错误
|
|||
|
|
|||
|
int packetAFLDP(DataPacket * pPacket)
|
|||
|
{
|
|||
|
if (pPacket == NULL)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
memcpy(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN);
|
|||
|
pPacket->normal.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
|
|||
|
// 功能: 打包一个可变长度数据包
|
|||
|
// 参数: pPacket, 需要打包的数据包,需要填充其中的 SYNC EXLEN EXCRC 和 EXDAT 等部分
|
|||
|
// pExdat, 附加数据,可以为空
|
|||
|
// exlen,附加数据长度,可以为0
|
|||
|
// 结果:
|
|||
|
// 0, 打包好数据
|
|||
|
// -1, 参数错误
|
|||
|
// -2,
|
|||
|
|
|||
|
int packetAVLDP(DataPacket * pPacket, u8 * pExdat, u16 exlen)
|
|||
|
{
|
|||
|
if (pPacket == NULL)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
if (pExdat == NULL)
|
|||
|
{
|
|||
|
exlen = 0;
|
|||
|
}
|
|||
|
|
|||
|
memcpy(pPacket->vldp.sync, VLDP_SYNC, DP_SYNC_LEN);
|
|||
|
pPacket->vldp.exlen = exlen;
|
|||
|
pPacket->vldp.excrc = calcCrc16(pExdat, exlen);
|
|||
|
pPacket->vldp.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
|
|||
|
if (exlen != 0)
|
|||
|
{
|
|||
|
memcpy(pPacket->vldp.exData, pExdat, exlen);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------------------
|
|||
|
|
|||
|
|