/// <summary> /// 将字节流转换成命令 /// </summary> /// <param name="cmddata"></param> /// <returns></returns> public CmdTag Parse(byte[] cmddata) { CmdTag cmd = new CmdTag(); //命令类 cmd.CmdType = cmddata[3]; // cmd.CmdType = (UInt16)((cmd.CmdType << 8) | cmddata[4]); //命令字 cmd.CmdCode = cmddata[4]; // cmd.CmdCode = (UInt16)((cmd.CmdCode << 8) | cmddata[6]); //指令状态 cmd.CmdState = cmddata[5]; //设备ID Array.Copy(cmddata, 6, cmd.DeviceInfo.Serial, 0, 7); cmd.DeviceInfo.Parse(cmd.DeviceInfo.Serial); //参数区 cmd.Param = new byte[cmddata.Length - CommandCommon.CMD_MIN_LENGTH]; Array.Copy(cmddata, 13, cmd.Param, 0, cmd.Param.Length); return(cmd); }
private static byte[] BuildCmd(byte cmdType, byte cmdCode, byte cmdState, byte safeCode) { CmdTag tag = new CmdTag(); tag.CmdType = cmdType; tag.CmdCode = cmdCode; tag.CmdState = cmdState; tag.Param = new byte[0]; tag.DeviceInfo = new DeviceIdTag(); return(BuildCmd(tag, safeCode)); }
/// <summary> /// 解析命令,返回处理后的命令列表 /// </summary> /// <param name="cmdData">被处理命令的buffer</param> /// <param name="safeCode">需要转义的转义码</param> /// <param name="cmdList">处理后的命令列表</param> private static void ParseCmd(ref CmdBuffer cmdData, byte safeCode, ref MemQueue <CmdTag> cmdList, string socketID) { CmdBuffer temp = new CmdBuffer(); byte sigByte = 0x00; UInt16 cmd_length = 0; sigByte = (byte)(safeCode - 0x01); //解析命令,如果接收的数据长度小于最短命令长度,即命令接收不完整 if (cmdData.Length < CommandCommon.CMD_MIN_LENGTH) { return; } int sigByteStartIndex = 0; lock (cmdData.Buffer) { // Debug.Print("Parse:{0}", FormatHelper.ByteArrayToHexString(cmdData.Buffer, cmdData.Length)); //查找协议头 sigByteStartIndex = Array.IndexOf(cmdData.Buffer, safeCode, 0, cmdData.Length); } //没有找到协议头 if (sigByteStartIndex < 0) { cmdData.Length = 0; return; } //数据长度不够,即最后一个字节为协议标识 if ((sigByteStartIndex + 1) == cmdData.Length) { cmdData.Buffer[0] = safeCode; cmdData.Length = 1; return; } //第一字节非协议头 if (sigByteStartIndex > 0) { cmdData.Length = cmdData.Length - sigByteStartIndex; if ((cmdData.Length <= 0) || (cmdData.Length >= CmdBuffer.BUFFER_MAX_LENGTH)) { cmdData.Length = 0; return; } Array.Copy(cmdData.Buffer, sigByteStartIndex, cmdData.Buffer, 0, cmdData.Length); } //查找协议尾 int sigByteEndIndex = 0; lock (cmdData.Buffer) { sigByteEndIndex = Array.IndexOf(cmdData.Buffer, safeCode, 1, cmdData.Length - 1); } //没有找到协议尾 if (sigByteEndIndex < 0) { return; } //包头包尾粘连 if (sigByteEndIndex == 1) { cmdData.Length -= 1; if (cmdData.Length <= 0) { cmdData.Length = 0; return; } if (cmdData.Length == 1) { cmdData.Buffer[0] = safeCode; cmdData.Length = 1; return; } Array.Copy(cmdData.Buffer, 1, cmdData.Buffer, 0, cmdData.Length); sigByteEndIndex = Array.IndexOf(cmdData.Buffer, safeCode, 1, cmdData.Length - 1); } //长度小于最短命令长度 if ((sigByteEndIndex + 1) < CommandCommon.CMD_MIN_LENGTH) { cmdData.Length = cmdData.Length - sigByteEndIndex - 1; if (cmdData.Length > 0) { Array.Copy(cmdData.Buffer, sigByteEndIndex + 1, cmdData.Buffer, 0, cmdData.Length); } else { cmdData.Length = 0; } return; } //当前命令超长 if ((sigByteEndIndex + 1) >= CommandCommon.CMD_MAX_LENGTH) { cmdData.Length = cmdData.Length - sigByteEndIndex - 1; if (cmdData.Length >= CmdBuffer.BUFFER_MAX_LENGTH) { cmdData.Length = 0; return; } if (cmdData.Length > 0) { Array.Copy(cmdData.Buffer, sigByteEndIndex + 1, cmdData.Buffer, 0, cmdData.Length); //递归调用 if (cmdData.Length >= CommandCommon.CMD_MIN_LENGTH) { ParseCmd(ref cmdData, safeCode, ref cmdList, socketID); } return; } if (cmdData.Length < 0) { cmdData.Length = 0; } return; } //拷贝命令数据 byte[] cmd_bytearray = new byte[sigByteEndIndex + 1]; Array.Copy(cmdData.Buffer, 0, cmd_bytearray, 0, cmd_bytearray.Length); cmdData.Length = cmdData.Length - cmd_bytearray.Length; if (cmdData.Length >= CmdBuffer.BUFFER_MAX_LENGTH) { cmdData.Length = 0; return; } //安全容错 if (cmdData.Length > 0) { Array.Copy(cmdData.Buffer, sigByteEndIndex + 1, cmdData.Buffer, 0, cmdData.Length); } if (cmdData.Length < 0) { cmdData.Length = 0; } //执行解析 //1:处理转义字符 byte[] parsed_bytearray; //调用时,除去头尾 UInt16 crc1 = ConvertSafeCodeToCmdSigByte(cmd_bytearray, safeCode, out parsed_bytearray); UInt16 crc2 = 0x00; // Debug.Print("Cmd:{0}", Utils.FormatHelper.ByteArrayToHexString( parsed_bytearray )); crc2 = parsed_bytearray[parsed_bytearray.Length - 3]; crc2 = (UInt16)((crc2 << 8) | parsed_bytearray[parsed_bytearray.Length - 2]); //2:校验crc if (crc1 != crc2) { //Debug.Print("CRC非法,计算值:0x{0:X4} 指令值:{1:X4}", crc1, crc2); //递归调用 if (cmdData.Length >= CommandCommon.CMD_MIN_LENGTH) { ParseCmd(ref cmdData, safeCode, ref cmdList, socketID); } return; } //长度 cmd_length = parsed_bytearray[2]; cmd_length = (UInt16)((cmd_length << 8) | parsed_bytearray[1]); //指令长度非法 if ((cmd_length < CommandCommon.CMD_MIN_LENGTH) || (cmd_length > CommandCommon.CMD_MAX_LENGTH)) { //Debug.Print("指令长度与协议长度不匹配,指令长度:{0} 数据:{1}", cmd_length, parsed_bytearray.Length); //递归调用 if (cmdData.Length >= CommandCommon.CMD_MIN_LENGTH) { ParseCmd(ref cmdData, safeCode, ref cmdList, socketID); } return; } //3:开始解析成命令 CmdTag cmd = new CmdTag(); cmd = cmd.Parse(parsed_bytearray); cmd.SocketID = socketID; cmdList.Add(cmd); //加入至命令组 ////递归调用 //if (cmdData.Length >= Common.CMD_MIN_LENGTH) //{ // ParseCmd(ref cmdData, safeCode, ref cmdList,socketID); //} }
/// <summary> /// 生成命令 /// </summary> /// <param name="cmdTag">指令结构体</param> /// <param name="safeCode">安全码,即命令头尾</param> /// <returns>相关命令</returns> private static byte[] BuildCmd(CmdTag cmdTag, byte safeCode) { byte[] cmd = new byte[CommandCommon.CMD_MIN_LENGTH + cmdTag.Param.Length]; int cmdIndex = 0; int i = 0; byte sigByte = 0x00; sigByte = (byte)(safeCode - 0x01); //开始组合 //1.起始标识位 cmd[0] = safeCode; cmdIndex += 1; //2.长度 cmd[cmdIndex] = (byte)(cmd.Length & 0x00FF); cmdIndex += 1; cmd[cmdIndex] = (byte)((cmd.Length & 0xFF00) >> 8); cmdIndex += 1; //生成命令类 cmd[cmdIndex] = (byte)(cmdTag.CmdType & 0x00FF); cmdIndex += 1; //生成命字 cmd[cmdIndex] = (byte)(cmdTag.CmdCode & 0x00FF); cmdIndex += 1; //状态 cmd[cmdIndex] = cmdTag.CmdState; cmdIndex += 1; //设备ID Array.Copy(cmdTag.DeviceInfo.Serial, 0, cmd, cmdIndex, cmdTag.DeviceInfo.Serial.Length); cmdIndex += cmdTag.DeviceInfo.Serial.Length; //数据区 Array.Copy(cmdTag.Param, 0, cmd, cmdIndex, cmdTag.Param.Length); //cmdIndex += cmdTag.Param.Length; //计算校验码 UInt16 crc = FormatHelper.CRC16(cmd, 0, cmd.Length - 3); //添加校验码 cmd[cmd.Length - 3] = (byte)((crc & 0xFF00) >> 8); // cmdIndex += 1; cmd[cmd.Length - 2] = (byte)(crc & 0x00FF); // cmdIndex += 1; cmd[cmd.Length - 1] = safeCode; // cmdIndex += 1; //处理转义字 byte[] temp = new byte[cmd.Length * 2]; i = 1; cmdIndex = 1; temp[0] = cmd[0]; while (i < (cmd.Length - 1)) { temp[cmdIndex] = cmd[i]; if (temp[cmdIndex] == sigByte) { // temp[cmdIndex] = safeCode; cmdIndex += 1; temp[cmdIndex] = 0x02; } if (temp[cmdIndex] == safeCode) { temp[cmdIndex] = sigByte; cmdIndex += 1; temp[cmdIndex] = 0x01; } cmdIndex += 1; i++; } //添加标识尾 temp[cmdIndex] = safeCode; cmdIndex += 1; byte[] ret = new byte[cmdIndex]; Array.Copy(temp, ret, cmdIndex); return(ret); }
/// <summary> /// 生成设备间的通信协议 /// </summary> /// <param name="cmdTag"></param> /// <returns></returns> public static byte[] BuildDeviceCmd(CmdTag cmdTag) { return(BuildCmd(cmdTag, CommandCommon.CMD_DEVICE_SAFE_CODE)); }
/// <summary> /// 生成平台间的通信协议 /// </summary> /// <param name="cmdTag"></param> /// <param name="safeCode"></param> /// <returns></returns> public static byte[] BuildPlatformCmd(CmdTag cmdTag) { return(BuildCmd(cmdTag, CommandCommon.CMD_PLATFORM_SAFE_CODE)); }