/// <summary> /// 解包NP层协议数据包 /// </summary> /// <param name="npData"></param> /// <param name="npLayer"></param> /// <param name="mapLayer"></param> /// <returns></returns> private static CmccUnpacketResult UnpacketNPA(byte[] npData, ref NPLayer npLayer, ref MapLayer mapLayer) { if (npData.Length <= 9) { return CmccUnpacketResult.OtherError; // without map data } int offset = 0; npLayer.siteId = BitConverter.ToUInt32(npData, offset); offset += 4; npLayer.subId = npData[offset++]; npLayer.packetId = BitConverter.ToUInt16(npData, offset); offset += 2; npLayer.npFlag = npData[offset++]; mapLayer.mapId = npData[offset++]; byte[] mapData = new byte[npData.Length - 9]; Array.Copy(npData, offset, mapData, 0, mapData.Length); offset += mapData.Length; switch (mapLayer.mapId) { case CmccConst.MapId.A: case CmccConst.MapId.B: case CmccConst.MapId.C: return UnpacketMapLayer(mapData, ref mapLayer); default: return CmccUnpacketResult.OtherError; } }
/// <summary> /// 解包AP.A协议数据包 /// </summary> /// <param name="apData"></param> /// <param name="npLayer"></param> /// <param name="mapLayer"></param> /// <returns></returns> private static CmccUnpacketResult UnpacketAPC(byte[] apData, ref NPLayer npLayer, ref MapLayer mapLayer) { List<byte> apDataEx = new List<byte>(); // Cancel Converting and remove start/stop flag ProtocolBase.PrintBytes("apData", apData); bool convert = false; foreach (byte element in apData) { if (element == CmccConst.ApFlag.A) { continue; } if (convert) { convert = false; switch (element) { case 0x5D: apDataEx.Add(0x5E); break; case 0x7D: apDataEx.Add(0x7E); break; default: return CmccUnpacketResult.OtherError; } } else { if (element == 0x5E) { convert = true; } else { apDataEx.Add(element); } } } byte[] bytes = apDataEx.ToArray(); if (bytes.Length <= 4) { return CmccUnpacketResult.OtherError; // without np data } int offset = 0; ProtocolBase.PrintBytes("UnpacketAPA", bytes); if (bytes[offset++] != CmccConst.ApId.C) { return CmccUnpacketResult.OtherError; } npLayer.npId = bytes[offset++]; byte[] npData = new byte[bytes.Length - 4]; Array.Copy(bytes, offset, npData, 0, npData.Length); offset += npData.Length; ushort crc_count = 0; ushort crc_read = 0; crc_count = ProtocolBase.CRC16(bytes[0], crc_count); crc_count = ProtocolBase.CRC16(bytes[1], crc_count); crc_count = ProtocolBase.CRC16(npData, crc_count); crc_read = BitConverter.ToUInt16(bytes, offset); offset += 2; if (crc_count != crc_read) { return CmccUnpacketResult.CrcError; } switch (npLayer.npId) { case CmccConst.NpId.A: return UnpacketNPA(npData, ref npLayer, ref mapLayer); default: return CmccUnpacketResult.OtherError; } }
/// <summary> /// 解包AP.B层协议数据包 /// </summary> /// <param name="apData"></param> /// <param name="npLayer"></param> /// <param name="mapLayer"></param> /// <returns></returns> private static CmccUnpacketResult UnpacketAPB(byte[] apData, ref NPLayer npLayer, ref MapLayer mapLayer) { List<byte> apDataEx = new List<byte>(); // Cancel Spliting and remove start/stop flag char hiChar = '-'; char loChar = '-'; byte combine = 0; foreach (byte element in apData) { if (element == CmccConst.ApFlag.B) { continue; } if (hiChar != '-') { loChar = (char)element; if (!ProtocolBase.CombineByte(hiChar, loChar, out combine)) { return CmccUnpacketResult.OtherError; } apDataEx.Add(combine); hiChar = '-'; } else { hiChar = (char)element; } } byte[] bytes = apDataEx.ToArray(); if (bytes.Length <= 4) { return CmccUnpacketResult.OtherError; // without np data } int offset = 0; if (bytes[offset++] != CmccConst.ApId.B) { return CmccUnpacketResult.OtherError; } npLayer.npId = bytes[offset++]; byte[] npData = new byte[bytes.Length - 4]; Array.Copy(bytes, offset, npData, 0, npData.Length); offset += npData.Length; ushort crc_count = 0; ushort crc_read = 0; crc_count = ProtocolBase.CRC16(bytes[0], crc_count); crc_count = ProtocolBase.CRC16(bytes[1], crc_count); crc_count = ProtocolBase.CRC16(npData, crc_count); crc_read = BitConverter.ToUInt16(bytes, offset); offset += 2; if (crc_count != crc_read) { return CmccUnpacketResult.CrcError; } switch (npLayer.npId) { case CmccConst.NpId.A: return UnpacketNPA(npData, ref npLayer, ref mapLayer); default: return CmccUnpacketResult.OtherError; } }
/// <summary> /// 打包NP.A /// </summary> /// <param name="npLayer"></param> /// <param name="mapId"></param> /// <param name="mapData"></param> /// <returns></returns> private static List<byte> PacketNPLayer(NPLayer npLayer, byte mapId, List<byte> mapData) { List<byte> npData = new List<byte>(); byte[] bytes = null; bytes = BitConverter.GetBytes(npLayer.siteId); foreach (byte element in bytes) { npData.Add(element); } npData.Add(npLayer.subId); bytes = BitConverter.GetBytes(npLayer.packetId); foreach (byte element in bytes) { npData.Add(element); } npData.Add(npLayer.npFlag); npData.Add(mapId); foreach (byte element in mapData) { npData.Add(element); } return npData; }
/// <summary> /// 探测并解包数据,属于外部接口 /// </summary> /// <param name="data"></param> /// <param name="apLayer"></param> /// <param name="npLayer"></param> /// <param name="mapLayer"></param> /// <returns></returns> public static CmccUnpacketResult Unpacket(byte[] data, ref APLayer apLayer, ref NPLayer npLayer, ref MapLayer mapLayer) { if (data == null) { return CmccUnpacketResult.OtherError; } int begin = -1; int end = -1; for (int n = 0; n < data.Length; n++) { if (data[n] == CmccConst.ApFlag.A) { if (data[n + 1] == CmccConst.ApId.A) { apLayer.apId = CmccConst.ApId.A; begin = n; break; } else if (data[n + 1] == CmccConst.ApId.C) { apLayer.apId = CmccConst.ApId.C; begin = n; break; } } if (data[n] == CmccConst.ApFlag.B) { apLayer.apId = CmccConst.ApId.B; begin = n; break; } } if (begin < 0) { return CmccUnpacketResult.OtherError; } for (int n = begin + 1; n < data.Length; n++) { if (data[n] == data[begin]) { end = n; break; } } if (end < 0) { return CmccUnpacketResult.OtherError; } byte[] apData = new byte[end - begin + 1]; for (int n = 0; n < apData.Length; n++) { apData[n] = data[n + begin]; } switch (apLayer.apId) { case CmccConst.ApId.A: return UnpacketAPA(apData, ref npLayer, ref mapLayer); case CmccConst.ApId.B: return UnpacketAPB(apData, ref npLayer, ref mapLayer); case CmccConst.ApId.C: return UnpacketAPC(apData, ref npLayer, ref mapLayer); default: return CmccUnpacketResult.OtherError; } }
/// <summary> /// 提供给用户的打包接口 /// </summary> /// <param name="apLayer"></param> /// <param name="npLayer"></param> /// <param name="mapLayer"></param> /// <returns></returns> public static byte[] Packet(APLayer apLayer, NPLayer npLayer, MapLayer mapLayer) { List<byte> apData = new List<byte>(); List<byte> npData = new List<byte>(); List<byte> mapData = new List<byte>(); // 打包MAP层数据包 mapData = PacketMapLayer(mapLayer); switch (npLayer.npId) { case CmccConst.NpId.A: npData = PacketNPLayer(npLayer, mapLayer.mapId, mapData); break; default: npData = mapData; break; } switch (apLayer.apId) { case CmccConst.ApId.A: apData = PacketAPA(npLayer.npId, npData); break; case CmccConst.ApId.B: apData = PacketAPB(npLayer.npId, npData); break; case CmccConst.ApId.C: apData = PacketAPC(npLayer.npId, npData); break; default: apData = npData; break; } return apData.ToArray(); }