/**************************************************************** FunctionName : GAgent_Local_ExtractOnePacket Description : extract one packet from local cycle buf, and put data into buf.Will change pos_start buf : dest buf return : >0 the local packet data length. <0 don't have one whole packet data ****************************************************************/ int32 GAgent_Local_ExtractOnePacket(uint8 *buf) { int32 ret; uint32 i; uint16 packetLen; if(NULL == buf) { GAgent_Printf(GAGENT_WARNING,"%s,%d,Input buf is NULL", __FUNCTION__, __LINE__); return RET_FAILED; } /* find one packet data form position pos_start of local driver buf */ ret = find_packet_forward(pos_start, &packetLen); if(ret >= 0) { /* a whole packet */ pos_start = ret; for(i = 0; i < packetLen; i++) { buf[i] = __halbuf_read(pos_start + i); } pos_start += packetLen; return packetLen; } return RET_FAILED; }
/**************************************************************** FunctionName : find_packet_backward Description : 在串口缓冲区中,从指定位置往回查找包含该数据的一帧数据, 并返回帧头所在偏移。没有完整一帧数据则返回已接收数据的起始位置。 pos : 指定位置. return : 帧头所在偏移 Add by will --2015-05-21 ****************************************************************/ static int32 find_packet_backward(uint32 pos) { uint32 offset; uint8 data1; uint8 data2; uint32 datalen; uint16 packetlen; // 缓冲区中已知数据长度 datalen = get_data_len(pos_start, pos); if(datalen < MCU_SYNC_HEAD_LEN) { return pos_start; } if(datalen <= MCU_SYNC_HEAD_LEN + sizeof(packetlen)) { return pos_start; } offset = pos - MCU_SYNC_HEAD_LEN; while(offset != pos_start) { data1 = __halbuf_read(offset); data2 = __halbuf_read(offset + 1); if(MCU_HDR_FF == data1 && MCU_HDR_FF == data2) { datalen = get_data_len(offset, pos + 1); packetlen = __halbuf_read(offset + MCU_LEN_POS); packetlen = (packetlen << 8) | __halbuf_read(offset + MCU_LEN_POS + 1); packetlen += MCU_SYNC_HEAD_LEN + sizeof(packetlen); if(datalen <= packetlen) { return offset; } else { return offset + packetlen; } break; } offset--; } return pos_start; }
/**************************************************************** FunctionName : find_packet_forward Description : 在串口缓冲区中,从指定位置往前查找最近一帧完整数据, 返回该帧数据头所在位置。 pos : 指定位置. packetLen : 输出参数,该帧数据的长度 return : 失败--RET_FAILED 成功--帧头所在偏移 Add by will --2015-05-21 ****************************************************************/ static int32 find_packet_forward(uint32 pos, uint16 *packetLen) { uint8 data1; uint8 data2; uint32 datalen; uint16 packetlen; uint16 packetLenMin; uint32 start, end; start = pos; end = pos_current; datalen = get_data_len(start, end); /* A packet len must larger than the member sync head + len */ packetLenMin = MCU_SYNC_HEAD_LEN + sizeof(packetlen); while( datalen > packetLenMin ) { data1 = __halbuf_read(start); data2 = __halbuf_read(start + 1); if(MCU_HDR_FF == data1 && MCU_HDR_FF == data2) { packetlen = __halbuf_read(start + MCU_LEN_POS); packetlen = (packetlen << 8) | __halbuf_read(start + MCU_LEN_POS + 1); packetlen += 4; if(datalen < packetlen) { return RET_FAILED; } else { *packetLen = packetlen; return start; } } start++; datalen--; } return RET_FAILED; }
// 向前(左)移动数据,被移动的数据为从p_start_pos开始,到p_end_pos,移动长度为move_len void move_data_backward( uint8 *buf, int32 pos_start, int32 pos_end, int32 move_len) { int32 k; int32 pos_new_start; int32 move_data_len = get_data_len(pos_start, pos_end); pos_new_start = pos_start + (-1)*move_len; for(k=0; k < move_data_len; k++) { __halbuf_write(pos_new_start + k, __halbuf_read(pos_start + k)); } }
int32 check_isInPacket(uint32 pos) { uint32 packetStart; uint8 data1, data2; uint32 datalen; uint32 packetLen; packetStart = find_packet_backward(pos); data1 = __halbuf_read(packetStart); data2 = __halbuf_read(packetStart + 1); if(MCU_HDR_FF == data1 && MCU_HDR_FF == data2) { datalen = get_data_len(packetStart, pos) + 1; if(datalen <= MCU_SYNC_HEAD_LEN + sizeof(uint16)) { return 0; } packetLen = __halbuf_read(packetStart + MCU_LEN_POS); packetLen = (packetLen << 8) | __halbuf_read(packetStart + MCU_LEN_POS + 1); packetLen += MCU_SYNC_HEAD_LEN + sizeof(uint16); if(datalen > packetLen) { return 0; } else { return 1; } } else { return 0; } }
/**************************************************************** FunctionName : GAgent_Local_ExtractOnePacket Description : extract one packet from local cycle buf, and put data into buf.Will change pos_start buf : dest buf return : >0 the local packet data length. <0 don't have one whole packet data ****************************************************************/ int32 GAgent_Local_ExtractOnePacket(uint8 *buf) { uint8 data; uint32 i = 0; while((pos_start & HAL_BUF_MASK) != (pos_current & HAL_BUF_MASK)) { data = __halbuf_read(pos_start); if(LOCAL_HAL_REC_SYNCHEAD1 == gu8LocalHalStatus) { if(MCU_HDR_FF == data) { gu8LocalHalStatus = LOCAL_HAL_REC_SYNCHEAD2; guiLocalPacketStart = pos_start; } } else if(LOCAL_HAL_REC_SYNCHEAD2 == gu8LocalHalStatus) { if(MCU_HDR_FF == data) { gu8LocalHalStatus = LOCAL_HAL_REC_DATALEN1; } else { gu8LocalHalStatus = LOCAL_HAL_REC_SYNCHEAD1; } } else { if(halRecKeyWord) { /* 前面接收到0xff */ halRecKeyWord = 0; if(0x55 == data) { data = 0xff; move_data_backward(hal_RxBuffer, pos_start + 1, pos_current, 1); pos_current--; pos_start--; } else if(MCU_HDR_FF == data) { /* 新的一包数据,前面数据丢弃 */ gu8LocalHalStatus = LOCAL_HAL_REC_DATALEN1; guiLocalPacketStart = pos_start - 1; pos_start++; continue; } else { if(LOCAL_HAL_REC_DATALEN1 == gu8LocalHalStatus) { /* 说明前面接收到的0xff和包头0xffff是连在一起的,以最近的0xffff作为包头起始, * 当前字节作为len字节进行解析 */ guiLocalPacketStart = pos_start - 2; } else { gu8LocalHalStatus = LOCAL_HAL_REC_SYNCHEAD1; pos_start++; continue; } } } else { if(MCU_HDR_FF == data) { halRecKeyWord = 1; pos_start++; continue; } } if(LOCAL_HAL_REC_DATALEN1 == gu8LocalHalStatus) { gu16LocalPacketDataLen = data; gu16LocalPacketDataLen = (gu16LocalPacketDataLen << 8) & 0xff00; gu8LocalHalStatus = LOCAL_HAL_REC_DATALEN2; } else if(LOCAL_HAL_REC_DATALEN2 == gu8LocalHalStatus) { gu16LocalPacketDataLen += data; gu8LocalHalStatus = LOCAL_HAL_REC_DATA; if(0 == gu16LocalPacketDataLen) { /* invalid packet */ gu8LocalHalStatus = LOCAL_HAL_REC_SYNCHEAD1; } } else { /* Rec data */ gu16LocalPacketDataLen--; if(0 == gu16LocalPacketDataLen) { /* 接收到完整一包数据,拷贝到应用层缓冲区 */ pos_start++; i = 0; while(guiLocalPacketStart != pos_start) { buf[i] = __halbuf_read(guiLocalPacketStart++); i++; } return i; } } } pos_start++; } return RET_FAILED; }
/**************************************************************** FunctionName : Local_decode_data Description : decode local data in local cycle buf.transfer 0xff55 to 0xff. start : the posation in local cycle buf where will be decode length : decode data length will change the global pointer "put"--pos_current ****************************************************************/ void hal_decode_data(uint32 start, uint32 length) { static uint8 isSyncHead = 0; uint8 data; uint32 i; uint32 offRec; uint32 invalidLen; int32 ret; if(0 == length) { return ; } offRec = start; for(i = 0; i < length; i++) { data = __halbuf_read(offRec); if(isSyncHead) { isSyncHead = 0; /* check if is a new packet */ if(0xFF == data) { /* check if pre byte is in one packet */ ret = check_isInPacket(offRec - 1); if(0 == ret) { /* new packet */ offRec++; continue; } else { ret = find_packet_backward(offRec); invalidLen = get_data_len(ret, offRec + 1); move_data_backward(hal_RxBuffer, offRec + 1, pos_current, invalidLen); offRec -= invalidLen; pos_current = pos_current - invalidLen; } } /* check if is 0xff 0x55 */ else if(0x55 == data) { if((offRec & HAL_BUF_MASK) == ((pos_current - 1) & HAL_BUF_MASK)) { /* the last byte has received */ __halbuf_write(offRec, 0x00); } else { move_data_backward(hal_RxBuffer, offRec + 1, pos_current, 1); } offRec -= 1; pos_current -= 1; } /* invalid packet */ else { /* 找到当前字节处于哪一个packet */ ret = find_packet_backward(offRec); invalidLen = get_data_len(ret, offRec + 1); move_data_backward(hal_RxBuffer, offRec + 1, pos_current, invalidLen); offRec -= invalidLen; pos_current = pos_current - invalidLen; } } else if(MCU_HDR_FF == data) { isSyncHead = 1; } offRec++; } }