/* * 截取纯包出来 */ private CheckError cut(out PacketType out_ptye, out PacketCombineStatus out_fragtype, PacketType in_ptype, bool hasMiddleTag, byte middleTag, int middletag_rel_position, byte eTag, int endtag_rel_position, int purepctlength) { out_fragtype = getFragType(in_ptype); if (rawText_purepct_prt + purepctlength - 1 > rawText_length - 1) //碎片,继续拼接 { out_ptye = in_ptype; out_fragtype = getFragType(in_ptype); return(CheckError.CONTINUE); } //验证标志中间标志 if (hasMiddleTag == true) { if (rawText[rawText_purepct_prt + middletag_rel_position] != middleTag) { out_ptye = in_ptype; //out_fragtype = PacketCombineStatus.OK; //格式错误,抛弃数据 if (CombineError_Ev != null) { CombineError_Ev(getDataFormatErrorType(in_ptype)); } return(CheckError.DATA_FORMAT_ERROR); } } //验证结束标志 if (rawText[rawText_purepct_prt + endtag_rel_position] != eTag) { out_ptye = in_ptype; //out_fragtype = PacketCombineStatus.OK; //格式错误,抛弃数据 if (CombineError_Ev != null) { CombineError_Ev(getDataFormatErrorType(in_ptype)); } return(CheckError.DATA_FORMAT_ERROR); } //祝贺,拼接除了一个完整的包! out_ptye = in_ptype; out_fragtype = PacketCombineStatus.OK; PacketRecevied_Ev(getBuffer(rawText_purepct_prt, rawText_purepct_prt + purepctlength - 1), in_ptype); return(CheckError.OK); }
//检查格式已知包 //@param // private CheckError check_known_type_fn(PacketCombineStatus cmbstu, out PacketCombineStatus fragtype, out PacketType ptype) { ptype = PacketType.UNKNOWN; fragtype = PacketCombineStatus.FRAGMENT_UNKONWN; switch (cmbstu) { case PacketCombineStatus.FRAGMENT_VALUE: //'G',数据包 return(cut(out ptype, out fragtype, PacketType.DATA_VALUE, true, 0x48, machineinfo.DataPctMiddleTag, 0x49, machineinfo.DataPctEndTag, machineinfo.DataPctLength)); case PacketCombineStatus.FRAGMENT_RES_COMPUTE: //'X' 回应计算包 return(cut(out ptype, out fragtype, PacketType.RES_COMPUTE_VALUE, true, 0x48, machineinfo.ResComputePctMiddleTag, 0x49, machineinfo.ResComputePctEndTag, machineinfo.ResComputePctLength)); case PacketCombineStatus.FRAGMENT_SEQUENCE: //'S',序号包 return(cut(out ptype, out fragtype, PacketType.SEQUENCE, false, 0x0, 0, 0x45, machineinfo.SrlPctEndTag, machineinfo.SrlPctLength)); case PacketCombineStatus.FRAGMENT_CORRECT: //'C', 纠正包 return(cut(out ptype, out fragtype, PacketType.CORRECT_RESPONSE, true, 0x4d, machineinfo.CrtPctMiddleTag, 0x54, machineinfo.CrtPctEndTag, machineinfo.CrtPctLength)); case PacketCombineStatus.FRAGMENT_AIR_FLUENT: return(cut(out ptype, out fragtype, PacketType.AIR_FLUENT, true, (byte)machineinfo.AirFluPctMiddleTag, machineinfo.AirFluPctMiddleStart, (byte)machineinfo.AirFluPctEndTag, machineinfo.AirFluPctEndStart, machineinfo.AirFluPctLength)); case PacketCombineStatus.FRAGMENT_AIR_SAMPLE_TIME: return(cut(out ptype, out fragtype, PacketType.AIR_SAMPLE_TIME, true, (byte)machineinfo.AirSTPctMiddleTag, machineinfo.AirSTPctMiddleStart, (byte)machineinfo.AirSTPctEndTag, machineinfo.AirSTPctEndStart, machineinfo.AirSTPctLength)); case PacketCombineStatus.FRAGMENT_GETSTATUS_RESPONSE: return(cut(out ptype, out fragtype, PacketType.GETSTATUS_RESPONSE, true, (byte)machineinfo.GetStatusResPctMiddleTag, machineinfo.GetStatusResPctMiddleStart, (byte)machineinfo.GetStatusResPctEndTag, machineinfo.GetStatusResPctEndStart, machineinfo.GetStatusResPctLength)); case PacketCombineStatus.FRAGMENT_NORCMD_RESPONSE: return(cut(out ptype, out fragtype, PacketType.NORCMD_RESPONSE, true, (byte)machineinfo.NorCmdResPctMiddleTag, machineinfo.NorCmdResPctMiddleStart, (byte)machineinfo.NorCmdResPctEndTag, machineinfo.NorCmdResPctEndStart, machineinfo.NorCmdResPctLength)); } return(CheckError.CONTINUE); }
//检查包的完整性,寻找包的起始位置和结束位置。 //算法提示- rawText_bigpct_prt。 //@param // 返回值 - true,是个完整包。其它情况,fasle。 // // cmbstus - 上一个包状态 // fragtype - 碎片类型 // ptype - 包类型 // packetstart - 纯包开始位置,相对于rawText_bigpct_prt private CheckError check(PacketCombineStatus cmbstus, out PacketCombineStatus fragtype, out PacketType ptype) { ptype = PacketType.UNKNOWN; fragtype = cmbstus; switch (cmbstus) { case PacketCombineStatus.OK: //新包或格式未知道碎片 case PacketCombineStatus.FRAGMENT_UNKONWN: return(check_unknown_type_fn(out fragtype, out ptype)); case PacketCombineStatus.FRAGMENT_CORRECT: case PacketCombineStatus.FRAGMENT_SEQUENCE: case PacketCombineStatus.FRAGMENT_VALUE: case PacketCombineStatus.FRAGMENT_RES_COMPUTE: case PacketCombineStatus.FRAGMENT_AIR_FLUENT: case PacketCombineStatus.FRAGMENT_AIR_SAMPLE_TIME: case PacketCombineStatus.FRAGMENT_GETSTATUS_RESPONSE: case PacketCombineStatus.FRAGMENT_NORCMD_RESPONSE: return(check_known_type_fn(cmbstus, out fragtype, out ptype)); } return(CheckError.CONTINUE); }
//检查格式未知包 // // // // @param // private CheckError check_unknown_type_fn(out PacketCombineStatus fragtype, out PacketType ptype) { ptype = PacketType.UNKNOWN; fragtype = PacketCombineStatus.FRAGMENT_UNKONWN; //搜索包起始标志, abs表示相对于rawText的起点, int start_abs = -1; for (int i = rawText_bigpct_prt; i < rawText_length; i++) { if (rawText[i] == 0x46) //找到起始标志F { start_abs = i; break; } } //找不到F起始标志,继续拼包 if (start_abs == -1) { if (start_abs > 1000) //长时间无法找到起始标志, 碎片过大, 发出错误事件 { if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.NOT_FOUND_START_TAG_LONG); } return(CheckError.CONTINUE); } else { return(CheckError.CONTINUE); } } //F在rawtext最后,继续拼包 if (start_abs == rawText_length - 1) //F标志在rawtext的最后一位,仍然是无法识别包格式 { return(CheckError.CONTINUE); } //找到起始标志,识别包格式 rawText_purepct_prt = start_abs; switch (rawText[rawText_purepct_prt + 1]) { case 0x47: //'G',数据包, H, I return(cut(out ptype, out fragtype, PacketType.DATA_VALUE, true, 0x48, machineinfo.DataPctMiddleTag, 0x49, machineinfo.DataPctEndTag, machineinfo.DataPctLength)); case 0x58: //'X' 回应计算包, H, I return(cut(out ptype, out fragtype, PacketType.RES_COMPUTE_VALUE, true, 0x48, machineinfo.ResComputePctMiddleTag, 0x49, machineinfo.ResComputePctEndTag, machineinfo.ResComputePctLength)); case 0x53: //'S',序号包 ,E return(cut(out ptype, out fragtype, PacketType.SEQUENCE, false, 0x0, 0, 0x45, machineinfo.SrlPctEndTag, machineinfo.SrlPctLength)); case 0x43: //'C', 纠正包,0x4d, 0x54 return(cut(out ptype, out fragtype, PacketType.CORRECT_RESPONSE, true, 0x4d, machineinfo.CrtPctMiddleTag, 0x54, machineinfo.CrtPctEndTag, machineinfo.CrtPctLength)); case 0x41: //'A' 气体取样时间包 return(cut(out ptype, out fragtype, PacketType.AIR_SAMPLE_TIME, true, (byte)machineinfo.AirSTPctMiddleTag, machineinfo.AirSTPctMiddleStart, (byte)machineinfo.AirSTPctEndTag, machineinfo.AirSTPctEndStart, machineinfo.AirSTPctLength)); case 0x44: //'D' 气体流量包 return(cut(out ptype, out fragtype, PacketType.AIR_FLUENT, true, (byte)machineinfo.AirFluPctMiddleTag, machineinfo.AirFluPctMiddleStart, (byte)machineinfo.AirFluPctEndTag, machineinfo.AirFluPctEndStart, machineinfo.AirFluPctLength)); case 0x4A: //'J' 状态获取命令回应包 return(cut(out ptype, out fragtype, PacketType.GETSTATUS_RESPONSE, true, (byte)machineinfo.GetStatusResPctMiddleTag, machineinfo.GetStatusResPctMiddleStart, (byte)machineinfo.GetStatusResPctEndTag, machineinfo.GetStatusResPctEndStart, machineinfo.GetStatusResPctLength)); case 0x5A: //'Z'普通命令回应包 return(cut(out ptype, out fragtype, PacketType.NORCMD_RESPONSE, true, (byte)machineinfo.NorCmdResPctMiddleTag, machineinfo.NorCmdResPctMiddleStart, (byte)machineinfo.NorCmdResPctEndTag, machineinfo.NorCmdResPctEndStart, machineinfo.NorCmdResPctLength)); default: //无法识别包的类型 ptype = PacketType.UNKNOWN; fragtype = PacketCombineStatus.FRAGMENT_UNKONWN; return(CheckError.PACKET_TPYE_ERROR); } }
private PhyCombine() { rawText = new byte[rawText_maxlength]; Array.Clear(rawText, 0, rawText_maxlength); machineinfo = new MachineInfo(); //初始化机器类型 initmachineinfo(); CombineFragmentSg = delegate(byte[] rawitem) { #region phase1: get machine header /* * ////phase 1: 获取机器格式头//// * int st = -1; * * if (!append(rawitem)) * { * Console.WriteLine("到达尾部,无法append"); * return; * } * rawText_length += rawitem.Length; * * for (int i = rawText_bigpct_prt; i < rawText_length -1; i++) //查找包起始标志 * { * if (rawText[i] == 0x46 && rawText[i+1] == 0x4C ) //找到'FL' * { * st = i; * break; * } * } * if (st == -1 && rawText_length > rawText_maxlength - 100) //长时间不能收到机器类型包 * { * Console.WriteLine("长时间不能收到机器类型包"); * if(CombineError_Ev != null) CombineError_Ev(CombineErrorInfo.NOT_FOUND_MACHINE_HEADER_LONG); * * return; * } * if (st == -1 ||(st + MachineTypeHeaderLength > rawText_length )) //找不到起始标志'F', 或者碎片太短,继续拼包 * { * return; * } * if(rawText[st+2] != 0x01) //未能识别的机器类型 * { * Console.WriteLine("未能识别的机器类型"); * if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.INVALID_MACHINE_TYPE); } * return; * } * * //找到机器类型包,准备自弃 * switch (rawText[st+2]) * { * case 0x01: * machineinfo.CrtPctEndTag = 16; * machineinfo.CrtPctLength = 17; * machineinfo.CrtPctMiddleTag = 7; * machineinfo.CrtPctDStart = 2; * machineinfo.CrtPctSStart = 10; //序号起始位置 * machineinfo.CrtPctVStart = 8; * * machineinfo.DataPctEndTag = 10; * machineinfo.DataPctLength = 11; * machineinfo.DataPctMiddleTag = 7; * machineinfo.DataPctDStart = 2; * machineinfo.DataPctVStart = 8; * * machineinfo.SrlPctEndTag = 8; * machineinfo.SrlPctLength = 9; * * //气体流量包 * machineinfo.AirFluPctDataWidth = 1; * machineinfo.AirFluPctDStart = 2; * machineinfo.AirFluPctEndStart = 6; * machineinfo.AirFluPctEndTag = 0x49; * machineinfo.AirFluPctLength = 7; * machineinfo.AirFluPctMiddleStart = 3; * machineinfo.AirFluPctMiddleTag = 0x45; * machineinfo.AirFluPctVStart = 4; * * //气体取样时间包 * machineinfo.AirSTPctDataWidth = 2; * machineinfo.AirSTPctDStart = 2; * machineinfo.AirSTPctEndStart = 7; * machineinfo.AirSTPctEndTag = 0x49; * machineinfo.AirSTPctLength = 8; * machineinfo.AirSTPctMiddleStart = 4; * machineinfo.AirSTPctMiddleTag = 0x42; * machineinfo.AirSTPctVStart = 5; * * //状态获取命令回应包 * machineinfo.GetStatusResPctDataWidth = 8; * machineinfo.GetStatusResPctDStart = 4; * machineinfo.GetStatusResPctEndStart = 16; * machineinfo.GetStatusResPctEndTag = 0x49; * machineinfo.GetStatusResPctLength = 17; * machineinfo.GetStatusResPctMiddleStart = 13; * machineinfo.GetStatusResPctMiddleTag = 0x48; * machineinfo.GetStatusResPctVStart = 14; * * //普通命令回应包 * machineinfo.NorCmdResPctDataWidth =3 ; * machineinfo.NorCmdResPctDStart = 2; * machineinfo.NorCmdResPctEndStart = 8; * machineinfo.NorCmdResPctEndTag = 0x49; * machineinfo.NorCmdResPctLength = 9; * machineinfo.NorCmdResPctMiddleStart = 5; * machineinfo.NorCmdResPctMiddleTag = 0x48; * machineinfo.NorCmdResPctVStart = 6; * * machineinfo.DataWidth = 5; * machineinfo.SequenceLength = 6; * machineinfo.Type = 0x01; * * rawText_bigpct_prt = st + MachineTypeHeaderLength; * break; * } */ #endregion #region phase2: analyze ////phase 2: 分析数据//// CombineFragmentSg = delegate(byte[] rawit) { PacketType out_ptype; PacketCombineStatus out_ftype; if (!append(rawit)) { return; } rawText_length += rawit.Length; //串口上传过来的一片数据可能包含多个包,循环直到处理完该片中的所有包 CheckError errslt = CheckError.OK; while (errslt == CheckError.OK || errslt == CheckError.DATA_FORMAT_ERROR || errslt == CheckError.PACKET_TPYE_ERROR) { errslt = check(rawText_frag_status, out out_ftype, out out_ptype); switch (errslt) { case CheckError.OK: //成功组包,拨动指针。如果尾部没有其它数据添加回车换行符合 switch (out_ptype) { case PacketType.CORRECT_RESPONSE: if (rawText_purepct_prt + machineinfo.CrtPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.CrtPctLength); } break; case PacketType.DATA_VALUE: if (rawText_purepct_prt + machineinfo.DataPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.DataPctLength); } break; case PacketType.RES_COMPUTE_VALUE: if (rawText_purepct_prt + machineinfo.ResComputePctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.ResComputePctLength); } break; case PacketType.SEQUENCE: if (rawText_purepct_prt + machineinfo.SrlPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.SrlPctLength); } break; case PacketType.AIR_FLUENT: if (rawText_purepct_prt + machineinfo.AirFluPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.AirFluPctLength); } break; case PacketType.AIR_SAMPLE_TIME: if (rawText_purepct_prt + machineinfo.AirSTPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.AirSTPctLength); } break; case PacketType.GETSTATUS_RESPONSE: if (rawText_purepct_prt + machineinfo.GetStatusResPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.GetStatusResPctLength); } break; case PacketType.NORCMD_RESPONSE: if (rawText_purepct_prt + machineinfo.NorCmdResPctLength == rawText_length) { if (appendCRLF()) { rawText_length += "\r\n".Length; rawText_bigpct_prt = rawText_length; } } else { rawText_bigpct_prt = (rawText_purepct_prt + machineinfo.NorCmdResPctLength); } break; } break; case CheckError.CONTINUE: //碎片,不要拨动指针 break; case CheckError.DATA_FORMAT_ERROR: //抛弃,拨动指针,跳过这个坏包,发出事件 switch (out_ftype) { case PacketCombineStatus.FRAGMENT_CORRECT: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.CrtPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.CORRECT_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_SEQUENCE: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.SrlPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.SEQUENCE_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_VALUE: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.DataPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.VALUE_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_RES_COMPUTE: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.ResComputePctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.RES_COMPUTE_VALUE_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_AIR_FLUENT: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.AirFluPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.AIR_FLUENT_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_AIR_SAMPLE_TIME: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.AirSTPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.AIR_SAMPLE_TIME_PCT_DATA_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_GETSTATUS_RESPONSE: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.GetStatusResPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.GETSTATUS_RESPONSE_FORMAT_ERROR); } break; case PacketCombineStatus.FRAGMENT_NORCMD_RESPONSE: rawText_bigpct_prt = rawText_purepct_prt + machineinfo.NorCmdResPctLength; if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.NORCMD_RESPONSE_FORMAT_ERROR); } break; } rawText_frag_status = PacketCombineStatus.OK; //抛弃格式错误包 break; case CheckError.PACKET_TPYE_ERROR: ////抛弃,拨动指针,发出事件 rawText_bigpct_prt += 1; //跳过"S" if (CombineError_Ev != null) { CombineError_Ev(CombineErrorInfo.INVALID_PACKET_TYPE); } break; } } }; return; #endregion }; }