#include "stdio.h" #include "rtthread.h" #include "board.h" #include "mystdlib.h" #include "list.h" #include "mystring.h" #include "signal.h" #include "prot_uc.h" #include "buff.h" #include "bytearray.h" #include "debug.h" #include "crc.h" #include "dev_flash.h" #include "codec.h" /*rc{ 协议编解码器,用于适配各种协议 }*/ // 二代批检仪协议解码 array_def *protu_decode(protu_def *p,array_def *data) { array_def *r=arr_creat(); param_check(r); DBG_LOG("decode for checker"); str_set(p->str_err,"ok"); if(arr_length(data)<9) { // 主机一帧数据至少9字节 DBG_WARN("recv data len too less."); str_set(p->str_err,"recv data len too less."); return r; } if((arr_get(data,0)!=0x59)||(arr_get(data,1)!=0x6d)) { // 帧头不对 DBG_WARN("frame head not 0x59 0x6d."); str_set(p->str_err,"frame head not 0x59 0x6d."); return r; } int len=arr_get(data,2)|(arr_get(data,3)<<8); if(len==65535) { // 重新设置数据长度 len=arr_get(data,7)|(arr_get(data,8)<<8)|(arr_get(data,9)<<16)|(arr_get(data,10)<<24); p->is_big_data=1; }else{ p->is_big_data=0; } if(len+6!=arr_length(data)) { // 如果长度不相等则产生了数据丢失 DBG_WARN("recv data have lossed."); str_set(p->str_err,"recv data have lossed."); return r; } uint8_t chk_a,chk_b; crc_crc16(arr_data(data)+2,len+2,&chk_a,&chk_b); if(chk_a!=arr_get(data,-2)||chk_b!=arr_get(data,-1)) { // crc校验不对 DBG_WARN("recv data check error.h_crc=%02x %02x,crc=%02x %02x",chk_a,chk_b,arr_get(data,-2),arr_get(data,-1)); str_set(p->str_err,"recv data check error."); } int cmd_no=arr_get(data,5)|(arr_get(data,6)<<8); if(p->cmd_no==cmd_no) { // 重复的cmd_no DBG_WARN("duplicate sequence number."); str_set(p->str_err,"duplicate sequence number."); } p->cmd=arr_get(data,4); // 数据负载 arr_delete(r); if(p->is_big_data==0) { return arr_mid(data,7,len-3); }else{ return arr_mid(data,11,len-7); } } // 二代批检仪协议编码 array_def *protu_encode(protu_def *p,array_def *data) { array_def *t=arr_creat(); param_check(t); uint16_t len=arr_length(data)+3; arr_append(t,0x59); arr_append(t,0x6d); arr_append(t,0x43); arr_append(t,len&0xff); arr_append(t,len>>8); arr_append(t,p->cmd); arr_append(t,p->cmd_no&0xff); arr_append(t,p->cmd_no>>8); arr_appends_from(t,data); uint8_t chk_a,chk_b; crc_crc16(arr_data(t)+3,len+2,&chk_a,&chk_b); arr_append(t,chk_a); arr_append(t,chk_b); return t; } protuc_codec_export(ym_checker,protu_decode,protu_encode); // 注码仪和批检仪协议相同 //protuc_codec_export(ym_coder2,protu_decode,protu_encode); // 赋码仪协议解码 array_def *protu_decode2(protu_def *p,array_def *data) { array_def *r=arr_creat(); param_check(r); DBG_LOG("decode for coder"); str_set(p->str_err,"ok"); if(arr_length(data)<6) { // 主机一帧数据至少9字节 DBG_WARN("recv data len too less."); str_set(p->str_err,"recv data len too less."); return r; } if((arr_get(data,0)!='Y')||(arr_get(data,1)!='m')) { // 帧头不对 DBG_WARN("frame head not 'Y' 'm'."); str_set(p->str_err,"frame head not 'Y' 'm'."); return r; } int len=arr_get(data,2)|(arr_get(data,3)<<8); p->is_big_data=0; if(len+6!=arr_length(data)) { // 如果长度不相等则产生了数据丢失 DBG_WARN("recv data have lossed."); str_set(p->str_err,"recv data have lossed."); return r; } uint8_t chk_a,chk_b; crc_sumcheck(arr_data(data)+4,len,&chk_a,&chk_b); if(chk_a!=arr_get(data,-2)||chk_b!=arr_get(data,-1)) { // crc校验不对 DBG_WARN("recv data check error.h_crc=%02x %02x,crc=%02x %02x",chk_a,chk_b,arr_get(data,-2),arr_get(data,-1)); str_set(p->str_err,"recv data check error."); } p->cmd_no=arr_get(data,5)|(arr_get(data,6)<<8); p->cmd=arr_get(data,4); // 数据负载 arr_delete(r); if(p->is_big_data==0) { return arr_mid(data,7,len-3); }else{ return arr_mid(data,11,len-7); } } // 赋码仪协议编码 array_def *protu_encode2(protu_def *p,array_def *data) { array_def *t=arr_creat(); param_check(t); uint16_t len=arr_length(data)+3; arr_append(t,0x59); arr_append(t,0x6d); arr_append(t,0x43); arr_append(t,len&0xff); arr_append(t,len>>8); arr_append(t,p->cmd); arr_append(t,p->cmd_no&0xff); arr_append(t,p->cmd_no>>8); arr_appends_from(t,data); uint8_t chk_a,chk_b; crc_sumcheck(arr_data(t)+5,len,&chk_a,&chk_b); arr_append(t,chk_a); arr_append(t,chk_b); return t; } protuc_codec_export(ym_coder,protu_decode2,protu_encode2);