using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; using System.Net; using Gps.Plugin.Common.Helpers; using System.IO; using System.Collections; namespace Gps.Plugin.Tcp.GT808 { public class PackHelper { public static byte[] ToBytes(string deviceId, MessageIds messageId, ushort seqNO, byte[] bodyBytesReturn) { HeadPack head = new HeadPack() { BodyProp = 0, MessageId = (ushort)messageId, SeqNO = seqNO }; head.SetDeviceId(deviceId); //BodyPropertyHelper.SetMessageLength(ref head.BodyProp,(ushort)bodyBytesReturn.Length); BodyPropertyHelper.SetMessageLength(ref head.BodyProp, (ushort)bodyBytesReturn.Length); return RawFormatter.Instance.Struct2Bytes(head).Concat(bodyBytesReturn).ToArray(); } public static byte[] DecodeBytes(byte[] buffer) { return DecodeBytes(buffer, 0, buffer.Length); } public static byte[] DecodeBytes(byte[] bytes, int offset, int length) { int index = 0; int endOffset = Math.Min(length, bytes.Length - offset) + offset; for (int i = offset; i < endOffset; ) { if (bytes[i] == 0x7d && bytes[i + 1] == 0x02) { bytes[index++] = 0x7e; i += 2; } else if (bytes[i] == 0x7d && bytes[i + 1] == 0x01) { bytes[index++] = 0x7d; i += 2; } else { bytes[index++] = bytes[i++]; } } return bytes.Take(index).ToArray(); } public static byte[] EncodeBytes(IEnumerable bytes) { MemoryStream ms = new MemoryStream(); foreach (var b in bytes) { if (b == 0x7e) { ms.WriteByte(0x7d); ms.WriteByte(0x02); } else if (b == 0x7d) { ms.WriteByte(0x7d); ms.WriteByte(0x01); } else { ms.WriteByte(b); } } return ms.ToArray(); } /// /// 计算校验位 /// /// /// /// /// public static byte CalcCheckByte(byte[] bytes, int offset, int count) { if (count == 0) return 0; byte ret = bytes[offset]; for (int i = offset + 1; i < offset + count; ++i) { ret ^= bytes[i]; } return ret; } /// /// 计算校验位 /// /// public static void CalcCheckByte(byte[] bytes) { if (bytes.Length == 0) return; bytes[bytes.Length - 1] = CalcCheckByte(bytes, 0, bytes.Length - 1); } } /* 车载GPS定位器通信协议(GT808)(TCP_6004).pdf P2 * * 7E-01-02-00-06-00-20-47-05-52-32-00-00-30-31-32-33-34-35-06-7E */ [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class HeadPack { public static byte FixPrefix = 0x7e; public static Int32 PackSize = Marshal.SizeOf(typeof(HeadPack)); /// /// 消息 ID /// public BigEndianUInt16 MessageId; /// /// 消息体属性 /// public BigEndianUInt16 BodyProp; /// /// 终端手机号 /// protected BCD8421_6BytesString DeviceId; /// /// 自增一序列号 /// public BigEndianUInt16 SeqNO; public string GetDeviceId() { //return string.Concat("460", DeviceId); return DeviceId; } public void SetDeviceId(string value) { if (value.Length > 12) { DeviceId = value.Substring(value.Length - 12, 12); } else { DeviceId = value.PadLeft(12, '0'); } } } public static class BodyPropertyHelper { /// /// 9-0 BIT /// /// /// public static Int16 GetMessageLength(BigEndianUInt16 val) { return (Int16)((UInt16)val & 0x03ff); } /// /// 9-0 BIT /// /// /// public static void SetMessageLength(ref BigEndianUInt16 val, UInt16 length) { val = (UInt16)(((UInt16)val & (~0x03ff)) + length); } /// /// 12-10 BIT /// /// /// public static Byte GetEncodeType(BigEndianUInt16 val) { return (Byte)((val >> 10) & 0x03); } public static void SetEncodeType(ref BigEndianUInt16 val, byte encType) { ushort v = val; v = (ushort)(v & ~(0x03 << 10) + encType << 10); val = v; } /// /// 13 BIT /// /// /// public static bool IsMutliPack(this BigEndianUInt16 val) { return ((val >> 13) & 0x01) == 0x0001; } } [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class PackProperty { public static Int32 PackSize = Marshal.SizeOf(typeof(PackProperty)); public BigEndianUInt16 Total; public BigEndianUInt16 Index; } [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class ServerAnswerPack { public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack)); /// /// 流水 /// public BigEndianUInt16 SeqNO; /// /// 消息ID /// public BigEndianUInt16 MessageId; /// /// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持 4:报警处理确认 /// public byte Result; } /// /// 终端通用应答 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class ClientAnswerPack { public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack)); /// /// 流水 /// public BigEndianUInt16 SeqNO; /// /// 消息ID /// public BigEndianUInt16 MessageId; /// /// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持 /// public byte Result; } /// /// 终端注册 最后是GBK字串,车牌号 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class ClientRegistPack { public static Int32 PackSize = Marshal.SizeOf(typeof(ClientRegistPack)); /// /// 省 /// public BigEndianUInt16 Province; /// /// 市 /// public BigEndianUInt16 City; /// /// 制造商 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] Manufacturer; /// /// 终端型号 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] DeviceModel; /// /// 终端ID /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public byte[] DeviceId; /// /// 车牌颜色 /// public byte CarColor; //最后是GBK字串,车牌号 } [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class ClientRegistReturnPack { /// /// 自增一序列号 /// public BigEndianUInt16 SeqNum; /// /// 0成功, 1车辆已经注册, 2数据库中无此车辆, 3终端已经被注册, 4数据库中无该终端 /// public Byte Result; } /// /// 位置包汇报 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class PositionReportPack { public static Int32 PackSize = Marshal.SizeOf(typeof(PositionReportPack)); /// /// 报警标志 /// public BigEndianUInt32 AlermFlags; /// /// 状态 /// public BigEndianUInt32 State; /// /// 纬度 度*10^6 /// public BigEndianUInt32 Latitude; /// /// 经度 度*10^6 /// public BigEndianUInt32 Longitude; /// /// 高程 单位为米 /// public BigEndianUInt16 Altitude; /// /// 速度 1/10KM/H /// public BigEndianUInt16 Speed; /// /// 方向 0~359 正北为0 顺时针 /// public BigEndianUInt16 Direction; /// /// 时间 /// public BCD8421_6BytesString Time; } /// /// 立即拍照命令 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class CmdPhotographePack { /// /// 通道ID > 0 /// public Byte Channel; /// /// 拍摄命令 0表示停止拍摄;0xffff表示录像;其它表示拍摄张数 /// public BigEndianUInt16 Cmd; /// /// 拍照间隔,录像时间。 单位为秒,0表示最小间隔拍照或者一直录像 /// public BigEndianUInt16 Interval; /// /// 保存标志 1保存 0立即上传 /// public byte Deal; /// /// 图像分辨率 0x01:320*240 0x02:640*480 0x03:800*600 0x04:1024*768 /// 0x05:176*144(Qcif) 0x06:352*288(Cif) 0x07:704*288(HALF D1) 0x08:704*546(D1) /// public byte Resolution; /// /// 图像质量 1 ~ 10 1表示质量损失最小, 10表示压缩最大 /// public byte Quality; /// /// 亮度 0 ~ 255 /// public byte Brightness; /// /// 对比度 0 ~ 127 /// public byte Contrast; /// /// 饱和度 0 ~ 127 /// public byte Saturation; /// /// 色度 0 ~ 255 /// public byte Chroma; } [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class CmdSendTextPack { public byte Flag; /// /// 紧急 /// public bool IsUrgent { get { return (Flag & 0x01) == 0x01; } set { Flag = (byte)(Flag | 0x01); } } /// /// 终端显示器显示 /// public bool IsDisplay { get { return (Flag & 0x04) == 0x04; } set { Flag = (byte)(Flag | 0x04); } } /// /// 终端显示器显示 /// public bool IsTTS { get { return (Flag & 0x08) == 0x08; } set { Flag = (byte)(Flag | 0x08); } } /// /// 终端显示器显示 /// public bool IsAD { get { return (Flag & 0x10) == 0x10; } set { Flag = (byte)(Flag | 0x10); } } //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)] //public byte[] MessageBytes; } /// /// 多媒体数据上传 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class GpsMultimediaUploadPack { public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaUploadPack)); /// /// 多媒体ID >0 /// public BigEndianUInt32 ID; /// /// 多媒体类型 0:图像 1:音频 2:视频 /// public Byte Type; /// /// 多媒体格式编码 0:JPEG 1:TIF 2:MP3 3:WAV 4:WMV /// public byte Format; /// /// 事件项编码 0:平台下发指令 1:定时动作 2:抢劫报警触发 3:碰撞侧翻触发报警 4:保留 /// public byte EventCode; /// /// 通道ID > 0 /// public Byte Channel; } /// /// 多媒体数据上传 /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class GpsMultimediaReUploadPack { public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaReUploadPack)); /// /// 多媒体ID >0 /// public BigEndianUInt32 ID; /// /// 多媒体类型 0:图像 1:音频 2:视频 /// public Byte Count; ///// ///// 要求重发的下一个包 ///// //public Byte NextIndex; } public class BitValueState { private BitArray bitArray; public BitValueState(ushort state) { this.bitArray = new BitArray(BitConverter.GetBytes(state)); } /// /// ACC 开关 /// bool ACC { get { return bitArray[0]; } set { bitArray[0] = value; } } /// /// 是否定位 /// //Position = 0x0002, bool Position { get { return bitArray[1]; } set { bitArray[1] = value; } } /// /// 0北纬 1南纬 /// //NorthOrSouth = 0x0004, bool IsSouth { get { return bitArray[2]; } set { bitArray[2] = value; } } /// /// 0东经 1西经 /// //EastOrWest = 0x0008, bool IsWest { get { return bitArray[3]; } set { bitArray[3] = value; } } /// /// 0运营状态 1停运 /// //OperationState = 0x0010, bool OperationStoped { get { return bitArray[4]; } set { bitArray[4] = value; } } /// /// 经纬度是否加密 /// //EncodeLongitudeLatitude = 0x0020, bool EncodeLongitudeLatitude { get { return bitArray[5]; } set { bitArray[5] = value; } } /// /// 0车辆油路正常 1断开 /// //CarOilchannel = 0x0400, bool CarOilchannelBreaked { get { return bitArray[10]; } set { bitArray[10] = value; } } /// /// 0车辆电子正常 1断开 /// //CarCircuit = 0x0800, bool CarCircuitBreaked { get { return bitArray[11]; } set { bitArray[11] = value; } } /// /// 0车辆车门解锁 1加锁 /// //CarDoorLock = 0x1000 bool CarDoorLocked { get { return bitArray[12]; } set { bitArray[12] = value; } } } public class BitValueAlerm { //private uint data; private BitArray bitArray; public BitValueAlerm(UInt32 alerm) { //this.data = alerm; bitArray = new BitArray(new int[] { (int)alerm }); } /// /// 紧急报警, 触动报警开关后触发 收到答应后清除 /// bool Urgent { get { return bitArray[0]; } set { bitArray[0] = value; } } /// /// 超速报警 标志维持到报警条件解除 /// bool Speeding { get { return bitArray[1]; } set { bitArray[1] = value; } } /// /// 疲劳驾驶 标志维持到报警条件解除 /// bool Fatigue { get { return bitArray[2]; } set { bitArray[2] = value; } } /// /// 预警 收到答应后清除 /// bool Forewarning { get { return bitArray[3]; } set { bitArray[3] = value; } } //TODO:未完, 以后用到添加 } public enum MessageIds : ushort { /// /// 终端通用应答 /// ClientAnswer = 0x0001, /// /// 终端心跳 /// ClientPump = 0x0002, /// /// 终端注销 /// ClientUnregist = 0x0003, /// /// 终端注册 /// ClientRegist = 0x0100, /// /// 终端鉴权 /// ClientAuth = 0x0102, /// /// 位置信息汇报 /// PositionReport = 0x0200, /// /// 多媒体事件信息上传 /// MultimediaEventUpload = 0x0800, /// /// 多媒体数据上传 /// MultimediaUpload = 0x0801, /// /// 多媒体数据上传 /// MultimediaUploadAnswer = 0x8800, /// /// 平台通用应答 /// ServerAnswer = 0x8001, /// /// 终端注册应答 /// ClientRegistReturn = 0x8100, /// /// 立即拍照 /// Photographe = 0x8801, /// /// 下发文本 /// SendTextMessage = 0x8300 } }