/// <summary> /// 通过“消息ID”和“参数结构体对象列表”执行操作。 /// </summary> /// <param name="messageId"> /// 消息ID。 /// <para><see cref="MessageId"/>类型,长度为2个字节。</para> /// </param> /// <param name="parameterList">参数结构体对象列表。</param> /// <exception cref="CsaException">表示发生错误时引发的 CSA018 异常。</exception> /// <returns></returns> private byte[] GetOperateCommand(MessageId messageId, List <Parameter> parameterList) { // 获取消息体对象。 MessageBody mb = new MessageBody( messageId, GatewayId, LuminaireId, parameterList, DESKey); // 获取消息体字节数组。 byte[] msgBody = mb.GetBody(); // 获取消息头对象。 MessageHead mh = new MessageHead( MessageType, (ushort)(msgBody.Length), Crc32.GetCrc32(msgBody)); // 返回消息报文字节数组。 return(new Datagram(mh, mb).GetDatagram()); }
/// <summary> /// 获取命令执行结果数据报文字节数组。 /// <para>用于获取“命令执行结果”字节数组。</para> /// </summary> /// <param name="seqNumber"> /// 消息序号。 /// <para>uint类型,长度为4个字节。</para> /// </param> /// <param name="messageId"> /// 消息ID。 /// <para><see cref="MessageId"/>类型,长度为2个字节。</para> /// </param> /// <param name="errorCode"> /// 错误代码。 /// <para><see cref="ErrorCode"/>类型,长度为4个字节。</para> /// <para>可选字段,对“命令结果”类型的消息有效。</para> /// </param> /// <param name="errorInfo"> /// 错误信息。 /// <para>string类型,长度可变。</para> /// <para>可选字段,对“命令结果”类型的消息有效。</para> /// </param> /// <returns></returns> public byte[] GetResultCommand(uint seqNumber, MessageId messageId, ErrorCode errorCode, string errorInfo = null) { // 获取消息体对象。 MessageBody mb = new MessageBody( messageId, GatewayId, LuminaireId, errorCode, errorInfo, DESKey); // 获取消息体字节数组。 byte[] msgBody = mb.GetBody(); // 获取消息头对象。 MessageHead mh = new MessageHead( MessageType, seqNumber, (ushort)(msgBody.Length), Crc32.GetCrc32(msgBody)); // 返回消息报文字节数组。 return(new Datagram(mh, mb).GetDatagram()); }
/// <summary> /// 获取消息报文对象列表。 /// </summary> /// <param name="dataArray">消息报文字节数组。</param> /// <param name="desKey"> /// DES 密钥,默认不加密。 /// <para>该密钥运算模式采用 ECB 模式。</para> /// </param> /// <param name="isTcpOrUdp">报文承载方式是否是TCP或UDP,默认为false。</param> /// <param name="isCheckCrc">是否校验CRC。</param> /// <returns>消息报文对象列表。</returns> internal static List <Datagram> GetDatagramList(byte[] dataArray, byte[] desKey = null, bool isTcpOrUdp = false, bool isCheckCrc = true) { List <byte> dataList = new List <byte>(dataArray); for (int i = dataArray.Length - 1; i >= 0; i--) { if (dataList[i] > 0) { break; } dataList.RemoveAt(i); } if (dataList.Count < 15) { foreach (var item in dataList) { if (item == 0xFF) { return(new List <Datagram>() { new Datagram ( new MessageHead(MessageType.HeartbeatData) ) }); } if (item == 0xFE) { return(new List <Datagram>() { new Datagram ( new MessageHead(MessageType.HeartbeatResponse) ) }); } } throw new CsaException("消息解析错误。", ErrorCode.MessageParseError); } List <Datagram> datagramList = new List <Datagram>(); List <byte[]> newByteArrayList; if (!isTcpOrUdp) { List <byte[]> byteArrayList = new List <byte[]>(); GetByteArrayList(dataList.ToArray(), 0, ref byteArrayList); newByteArrayList = Descaping(byteArrayList); } else { newByteArrayList = new List <byte[]> { dataList.ToArray() }; } foreach (var tempByteArray in newByteArrayList) { if (tempByteArray.Length > 15) { if (!Enum.IsDefined(typeof(MessageType), tempByteArray[0])) { throw new CsaException("参数类型未定义。", ErrorCode.ParameterTypeUndefined); } Datagram d = new Datagram(); MessageHead mh = new MessageHead(); mh.Type = (MessageType)tempByteArray[0]; mh.SeqNumber = (uint)((tempByteArray[1] << 24) + (tempByteArray[2] << 16) + (tempByteArray[3] << 8) + tempByteArray[4]); mh.Length = (ushort)((tempByteArray[5] << 8) + tempByteArray[6]); mh.Reserved = (ulong)((tempByteArray[7] << 32) + (tempByteArray[8] << 24) + (tempByteArray[9] << 16) + (tempByteArray[10] << 8) + tempByteArray[11]); mh.Crc32 = (uint)((tempByteArray[12] << 24) + (tempByteArray[13] << 16) + (tempByteArray[14] << 8) + tempByteArray[15]); if (mh.Type == MessageType.Command || mh.Type == MessageType.Event || mh.Type == MessageType.CommandResult) { byte[] newByteArray = tempByteArray.Where((b, index) => index >= 16 && index < 16 + mh.Length).ToArray(); byte[] msgBody; if (desKey?.Length == 8) { DESHelper des = new DESHelper(); msgBody = des.Decrypt(desKey, newByteArray); // 设置一个值指示采用 DES 密钥加密。 d.IsCryptographic = true; } else { msgBody = newByteArray; } if (msgBody.Length >= 10) { if (!Enum.IsDefined(typeof(MessageId), (ushort)((msgBody[0] << 8) + msgBody[1]))) { throw new CsaException("消息ID未定义。", ErrorCode.MessageIdUndefined); } MessageBody mb = new MessageBody(); mb.MessageId = (MessageId)((msgBody[0] << 8) + msgBody[1]); mb.GatewayId = ((uint)msgBody[2] << 24) + ((uint)msgBody[3] << 16) + ((uint)msgBody[4] << 8) + msgBody[5]; mb.LuminaireId = ((uint)msgBody[6] << 24) + ((uint)msgBody[7] << 16) + ((uint)msgBody[8] << 8) + msgBody[9]; if (mh.Type == MessageType.CommandResult) { mb.ErrorCode = (ErrorCode)((msgBody[10] << 24) + (msgBody[11] << 16) + (msgBody[12] << 8) + msgBody[13]); List <byte> errorInfoArrayList = new List <byte>(); for (int i = 14; i < msgBody.Length; i++) { errorInfoArrayList.Add(msgBody[i]); } if (errorInfoArrayList.Count > 0) { mb.ErrorInfo = errorInfoArrayList.ToArray().ToString2(); } } else { List <Parameter> pmtList = new List <Parameter>(); Parameter.GetParameterList(msgBody, 10, ref pmtList); mb.ParameterList = pmtList; } if (isCheckCrc && Crc32.GetCrc32(newByteArray) != mh.Crc32) { throw new CsaException("消息体CRC校验错误。", ErrorCode.ChecksumError); } d.Body = mb; } else { throw new CsaException("消息解析错误。", ErrorCode.MessageParseError); } } d.Head = mh; datagramList.Add(d); } } return(datagramList); }