//------------------------------------------------------------------------------- // 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"< 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; } //--------------------------------------------------------------------------------------------------