From 6b9be08f0fc0ca924c8681b13838ff74ef042f7c Mon Sep 17 00:00:00 2001 From: SmallChi <564952747@qq.com> Date: Sun, 13 May 2018 23:24:29 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=BA=93=202.=E5=A2=9E=E5=8A=A0=E4=BA=8C=E8=BF=9B?= =?UTF-8?q?=E5=88=B6=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=203.=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0809=E9=85=8D=E7=BD=AE=204.=E5=A2=9E=E5=8A=A0=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=B6=88=E6=81=AF=EF=BC=88=E5=BE=85=E5=AE=8C=E5=96=84?= =?UTF-8?q?=EF=BC=89=205.=E4=BF=AE=E6=94=B9=E5=B9=B3=E5=8F=B0=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E7=A0=81=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT809.Protocol.Test/BaseTest.cs | 20 --- .../Encrypt/JT809EncryptImplTest.cs | 14 --- .../Escape/JT809EscapeImplTest.cs | 41 ------ .../JT809.Protocol.Test.csproj | 86 +++---------- src/JT809.Protocol.Test/PackageTest.cs | 117 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 20 --- src/JT809.Protocol.Test/packages.config | 6 - src/JT809.Protocol.sln | 10 +- src/JT809.Protocol/Configs/JT809Config.cs | 40 ++++++ .../Bodies/Master/Body_UP_CONNECT_REQ.cs | 47 +++++++ .../ProtocolPacket/BufferedEntityBase.cs | 16 ++- .../Extensions/BinaryExtensions.cs | 99 +++++++++++++++ .../Extensions/PackageExtensions.cs | 46 +++++-- src/JT809.Protocol/ProtocolPacket/Header.cs | 44 ++++++- .../{Version.cs => JT809Version.cs} | 92 +++++++------- .../ProtocolPacket/MessageBody.cs | 2 + src/JT809.Protocol/ProtocolPacket/Package.cs | 61 +++++++-- 17 files changed, 507 insertions(+), 254 deletions(-) delete mode 100644 src/JT809.Protocol.Test/BaseTest.cs delete mode 100644 src/JT809.Protocol.Test/Encrypt/JT809EncryptImplTest.cs delete mode 100644 src/JT809.Protocol.Test/Escape/JT809EscapeImplTest.cs create mode 100644 src/JT809.Protocol.Test/PackageTest.cs delete mode 100644 src/JT809.Protocol.Test/Properties/AssemblyInfo.cs delete mode 100644 src/JT809.Protocol.Test/packages.config create mode 100644 src/JT809.Protocol/Configs/JT809Config.cs create mode 100644 src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs create mode 100644 src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs rename src/JT809.Protocol/ProtocolPacket/{Version.cs => JT809Version.cs} (88%) diff --git a/src/JT809.Protocol.Test/BaseTest.cs b/src/JT809.Protocol.Test/BaseTest.cs deleted file mode 100644 index 669f4f8..0000000 --- a/src/JT809.Protocol.Test/BaseTest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using JT809.Protocol.Configs; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace JT809.Protocol.Test -{ - public class BaseTest - { - public JT809EncryptConfig JT809EncryptConfig = new JT809EncryptConfig() - { - Key=0x01, - IA1 = 20000000, - IC1= 30000000, - M1= 10000000 - }; - } -} diff --git a/src/JT809.Protocol.Test/Encrypt/JT809EncryptImplTest.cs b/src/JT809.Protocol.Test/Encrypt/JT809EncryptImplTest.cs deleted file mode 100644 index e356990..0000000 --- a/src/JT809.Protocol.Test/Encrypt/JT809EncryptImplTest.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace JT809.Protocol.Test.Encrypt -{ - [TestClass] - public class JT809EncryptImplTest: BaseTest - { - [TestMethod] - public void TestMethod1() - { - } - } -} diff --git a/src/JT809.Protocol.Test/Escape/JT809EscapeImplTest.cs b/src/JT809.Protocol.Test/Escape/JT809EscapeImplTest.cs deleted file mode 100644 index 544ddd2..0000000 --- a/src/JT809.Protocol.Test/Escape/JT809EscapeImplTest.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Text; -using JT809.Protocol.Configs; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; - -namespace JT809.Protocol.Test.Escape -{ - [TestClass] - public class JT809EscapeImplTest:BaseTest - { - //public IEncrypt encrypt; - - //public JT809EscapeImplTest() - //{ - // encrypt = new JT809EncryptImpl(base.JT809EncryptConfig); - //} - - //[TestMethod] - //public void Encrypt() - //{ - // byte[] buffer = System.Text.Encoding.UTF8.GetBytes("smallchi"); - // Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); - // encrypt.Encrypt(buffer); - // Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); - //} - - //[TestMethod] - //public void Decrypt() - //{ - // byte[] buffer =new byte [8]{ 92, 113, 125, 112, 112, 127, 116, 117}; - // Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); - // encrypt.Decrypt(buffer); - // Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); - // string name = System.Text.Encoding.UTF8.GetString(buffer); - // Assert.AreEqual("smallchi", name); - //} - } -} diff --git a/src/JT809.Protocol.Test/JT809.Protocol.Test.csproj b/src/JT809.Protocol.Test/JT809.Protocol.Test.csproj index fc90444..0970015 100644 --- a/src/JT809.Protocol.Test/JT809.Protocol.Test.csproj +++ b/src/JT809.Protocol.Test/JT809.Protocol.Test.csproj @@ -1,78 +1,20 @@ - - - + + - Debug - AnyCPU - {D1C5968B-741D-4D75-BB33-BD006C897D05} - Library - Properties - JT809.Protocol.Test - JT809.Protocol.Test - v4.6.1 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - + netcoreapp2.0 + + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - + - + + + + + - - {4d33a5c9-f583-4230-9791-ab0394efad57} - JT809.Protocol - + - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - - - \ No newline at end of file + + diff --git a/src/JT809.Protocol.Test/PackageTest.cs b/src/JT809.Protocol.Test/PackageTest.cs new file mode 100644 index 0000000..e1e86fb --- /dev/null +++ b/src/JT809.Protocol.Test/PackageTest.cs @@ -0,0 +1,117 @@ +using System; +using System.Text; +using JT809.Protocol.Configs; +using JT809.Protocol.ProtocolPacket; +using JT809.Protocol.ProtocolPacket.Bodies.Master; +using Xunit; + +namespace JT809.Protocol.Test.ProtocolPacket +{ + public class PackageTest + { + readonly static JT809Config JT809Config = new JT809Config + { + + }; + + [Fact] + public void CreatePackageTest() + { + var body_UP_CONNECT_REQ= new Body_UP_CONNECT_REQ(20140813, + Encoding.UTF8.GetBytes("20140813"), + Encoding.UTF8.GetBytes("20140813"), + 809); + Package package = Package.GeneratePackage(Enums.BusinessType.UP_CONNECT_REQ, + body_UP_CONNECT_REQ, + JT809Config); + var data = package.Buffer.ToHexString(); + Package package1 = new Package(package.Buffer); + package1.Buffer.ToHexString(); + } + + [Fact] + public void TestMethod1() + { + //5B + //00 00 00 48 + //00 00 00 85 + //10 01 + //01 33 53 D5 + //01 00 00 + //00 + //00 00 27 0F + //01 33 53 0D 32 30 31 34 30 38 31 33 31 32 37 2E 30 2E 30 2E 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 29 51 83 + //5D + + //UP-CONNECT-REQ + byte[] login = new byte[]{ + 91, + 00,00,00,48, + 00,00,00,85, + 10,01, + 01,33,53,213, + 01,00,00, + 00,00,00, + 27,15,01,33, + 53,13,32,30, + 31,34,30,38, + 31,33,31,32, + 37,46,30,46, + 30,46,31,00, + 00,00,00,00, + 00,00,00,00, + 00,00,00,00, + 00,00,00,00, + 00,00, + 00,00, + 00,00,03,29, + 51,83, + 93 }; + Package package = new Package(login); + } + + [Fact] + public void CrcTest() + { + byte[] login = new byte[] {51,83}; + + + var CRC16 = BitConverter.ToUInt16(login, 0); + byte[] login1 = new byte[] { 83, 51 }; + var CRC161 = BitConverter.ToUInt16(login1, 0); + } + + [Fact] + public void MSG_GNSSCENTERIDTest() + {//8449 + UInt64 result = 0; + //00, 01, D7, 28 + //01 ,33 ,53 ,0xD5 + //00 01 D7 27 + //00 00 27 0F + //5B + + byte[] data = new byte[] { 00 ,0x8A ,0xDA ,0xEB }; + int length = 4; + //00 << 8*(4-0-1)=>00 << 24 + //01 << 8*(4-1-1)=>01 << 16 + //0xD7 << 8*(4-2-1)=>0xD7 << 8 + //27 << 8*(4-3-1)=>27 << 0 + //var a1 = 27 << 0; + //for (int i = 0; i < length; i++) + //{ + + // UInt64 currentData = (UInt64)data[i] << (8 * (length - i - 1)); + // result += currentData; + //} + uint value = 20141013; + var a1 = (byte)(value >> 24); + var a2 = (byte)(value >> 16); + var a3 = (byte)(value >> 8); + var a4 = (byte)(value); + //01 51 83 213 + var b = (uint)(data[3] | data[2] << 8 | data[1] << 16 | data[0] << 24); + var a=result.ToString(); + } + } +} diff --git a/src/JT809.Protocol.Test/Properties/AssemblyInfo.cs b/src/JT809.Protocol.Test/Properties/AssemblyInfo.cs deleted file mode 100644 index d5dfc22..0000000 --- a/src/JT809.Protocol.Test/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("JT809.Protocol.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("JT809.Protocol.Test")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] - -[assembly: Guid("d1c5968b-741d-4d75-bb33-bd006c897d05")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/JT809.Protocol.Test/packages.config b/src/JT809.Protocol.Test/packages.config deleted file mode 100644 index b48b200..0000000 --- a/src/JT809.Protocol.Test/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/JT809.Protocol.sln b/src/JT809.Protocol.sln index 490d49e..2fad148 100644 --- a/src/JT809.Protocol.sln +++ b/src/JT809.Protocol.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.27428.2005 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809.Protocol", "JT809.Protocol\JT809.Protocol.csproj", "{4D33A5C9-F583-4230-9791-AB0394EFAD57}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT809.Protocol.Test", "JT809.Protocol.Test\JT809.Protocol.Test.csproj", "{D1C5968B-741D-4D75-BB33-BD006C897D05}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT809.Protocol.Test", "JT809.Protocol.Test\JT809.Protocol.Test.csproj", "{59D2D876-8D81-4CCE-839A-B153912C0C27}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,10 +17,10 @@ Global {4D33A5C9-F583-4230-9791-AB0394EFAD57}.Debug|Any CPU.Build.0 = Debug|Any CPU {4D33A5C9-F583-4230-9791-AB0394EFAD57}.Release|Any CPU.ActiveCfg = Release|Any CPU {4D33A5C9-F583-4230-9791-AB0394EFAD57}.Release|Any CPU.Build.0 = Release|Any CPU - {D1C5968B-741D-4D75-BB33-BD006C897D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1C5968B-741D-4D75-BB33-BD006C897D05}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1C5968B-741D-4D75-BB33-BD006C897D05}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1C5968B-741D-4D75-BB33-BD006C897D05}.Release|Any CPU.Build.0 = Release|Any CPU + {59D2D876-8D81-4CCE-839A-B153912C0C27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59D2D876-8D81-4CCE-839A-B153912C0C27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59D2D876-8D81-4CCE-839A-B153912C0C27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59D2D876-8D81-4CCE-839A-B153912C0C27}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/JT809.Protocol/Configs/JT809Config.cs b/src/JT809.Protocol/Configs/JT809Config.cs new file mode 100644 index 0000000..475755d --- /dev/null +++ b/src/JT809.Protocol/Configs/JT809Config.cs @@ -0,0 +1,40 @@ +using JT809.Protocol.ProtocolPacket; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.Configs +{ + public class JT809Config + { + public JT809Config() { } + + public JT809Config(uint sessionId, JT809Version jt809Version) + { + SessionId = sessionId; + JT809Version = jt809Version; + } + + public JT809Config(uint sessionId, JT809Version jt809Version, JT809EncryptConfig encryptConfig) + { + SessionId = sessionId; + JT809Version = jt809Version; + JT809EncryptConfig = encryptConfig; + } + + /// + /// 下级平台接入码,上级平台给下级平台分配唯一标识码。 + /// + public uint SessionId { get; set; } + + /// + /// 加密配置 + /// + public JT809EncryptConfig JT809EncryptConfig { get; set; } + + /// + /// 版本号 + /// + public JT809Version JT809Version { get; set; } = new JT809Version(); + } +} diff --git a/src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs b/src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs new file mode 100644 index 0000000..bcb344b --- /dev/null +++ b/src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace JT809.Protocol.ProtocolPacket.Bodies.Master +{ + public sealed class Body_UP_CONNECT_REQ : MessageBody + { + public uint UserId { get; private set; } + + public byte[] Password { get; private set; } + + public byte[] DownLinkIp { get; private set; } + + public ushort DownLinkPort { get; private set; } + + public Body_UP_CONNECT_REQ(byte[] buffer) : base(buffer) { } + + public Body_UP_CONNECT_REQ(uint userId, byte[] password, byte[] downLinkIp, ushort downLinkPort) + : base(userId, password, downLinkIp, downLinkPort) { } + + protected override void InitializeProperties(object[] properties, int startIndex) + { + UserId = (uint)properties[startIndex++]; + Password = SetMatchBytes((byte[])properties[startIndex++], 8); + DownLinkIp = SetMatchBytes((byte[])properties[startIndex++], 32); + DownLinkPort = (ushort)properties[startIndex++]; + } + + protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader) + { + UserId = reader.ReadUInt32Little(); + Password = reader.ReadBytes(8); + DownLinkIp = reader.ReadBytes(32); + DownLinkPort = reader.ReadUInt16Little(); + } + + protected override void OnWriteToBuffer(BinaryWriter writer) + { + writer.WriteLittle(UserId); + writer.WriteLittle(Password); + writer.WriteLittle(DownLinkIp); + writer.WriteLittle(DownLinkPort); + } + } +} diff --git a/src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs b/src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs index 9511741..9d82e4d 100644 --- a/src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs +++ b/src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Text; namespace JT809.Protocol.ProtocolPacket { @@ -28,12 +26,26 @@ namespace JT809.Protocol.ProtocolPacket InitializeProperties(properties, 0); ToBuffer(); } + protected BufferedEntityBase(byte[] buffer) { Buffer = buffer; InitializePropertiesFromBuffer(); } + public static byte[] SetMatchBytes(byte[] bufferIn, int lengthMatch, byte mask = 0X00) + { + if (bufferIn.Length != lengthMatch) + { + var tempBuffer = new byte[lengthMatch]; + Array.ForEach(tempBuffer, b => b = mask);//TODO : Maybe mask error + var copyLength = bufferIn.Length > lengthMatch ? lengthMatch : bufferIn.Length; + Array.Copy(bufferIn, 0, tempBuffer, 0, copyLength); + return tempBuffer; + } + return bufferIn; + } + protected abstract void InitializeProperties(object[] properties, int startIndex); protected abstract void OnInitializePropertiesFromReadBuffer(BinaryReader reader); diff --git a/src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs b/src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs new file mode 100644 index 0000000..4e9efc1 --- /dev/null +++ b/src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using System.Linq; + +namespace JT809.Protocol.ProtocolPacket +{ + public static class BinaryExtensions + { + public static void WriteLittle(this BinaryWriter writer, ulong value) + { + writer.Write((byte)(value >> 56)); + writer.Write((byte)(value >> 48)); + writer.Write((byte)(value >> 40)); + writer.Write((byte)(value >> 32)); + writer.Write((byte)(value >> 24)); + writer.Write((byte)(value >> 16)); + writer.Write((byte)(value >> 8)); + writer.Write((byte)(value)); + } + + public static void WriteLittle(this BinaryWriter writer, uint value) + { + writer.Write((byte)(value >> 24)); + writer.Write((byte)(value >> 16)); + writer.Write((byte)(value >> 8)); + writer.Write((byte)(value)); + } + + public static void WriteLittle(this BinaryWriter writer, int value) + { + writer.Write((byte)(value >> 24)); + writer.Write((byte)(value >> 16)); + writer.Write((byte)(value >> 8)); + writer.Write((byte)(value)); + } + + public static void WriteLittle(this BinaryWriter writer, short value) + { + writer.Write((byte)(value >> 8)); + writer.Write((byte)(value)); + } + + public static void WriteLittle(this BinaryWriter writer, ushort value) + { + writer.Write((byte)(value >> 8)); + writer.Write((byte)(value)); + } + + public static void WriteLittle(this BinaryWriter writer, byte value) + { + writer.Write(value); + } + + public static void WriteLittle(this BinaryWriter writer, byte[] value) + { + writer.Write(value); + } + + public static ulong ReadUInt64Little(this BinaryReader read) + { + var buffer = read.ReadBytes(8); + return (ulong)(buffer[7] | buffer[6] << 8 | buffer[5] << 16 | buffer[4] << 24| buffer[3] << 32 | buffer[2] << 40 | buffer[1] << 48 | buffer[0] << 56); + } + + public static uint ReadUInt32Little(this BinaryReader read) + { + var buffer = read.ReadBytes(4); + return (uint)(buffer[3] | buffer[2] << 8 | buffer[1] << 16 | buffer[0] << 24); + } + + public static ushort ReadUInt16Little(this BinaryReader read) + { + var buffer = read.ReadBytes(2); + return (ushort)(buffer[1] | buffer[0] << 8); + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// 默认 " " + /// + public static string ToHexString(this byte[] bytes,string separator=" ") + { + return string.Join(separator, bytes.Select(s => s.ToString("X2"))); + } + + /// + /// 16进制字符串转16进制数组 + /// + /// + /// + /// + public static byte[] ToHexBytes(this string hexString, string separator = " ") + { + return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray(); + } + } +} diff --git a/src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs b/src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs index 332ba91..c2b282b 100644 --- a/src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs +++ b/src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs @@ -9,6 +9,28 @@ namespace JT809.Protocol.ProtocolPacket.Extensions /// public static class PackageExtensions { + const ushort cnCRC_CCITT = 0x1021; //CRC校验多项式 + static ulong[] CRC = new ulong[256]; //建立CRC16表 + static PackageExtensions() + { + ushort i, j; + ushort nData; + ushort nAccum; + for (i = 0; i < 256; i++) + { + nData = (ushort)(i << 8); + nAccum = 0; + for (j = 0; j < 8; j++) + { + if (((nData ^ nAccum) & 0x8000) > 0) + nAccum = (ushort)((nAccum << 1) ^ cnCRC_CCITT); + else + nAccum <<= 1; + nData <<= 1; + } + CRC[i] = (ulong)nAccum; + } + } internal static byte[] Escape(this Package packege, byte[] bytes) { List dataList = new List(); @@ -80,22 +102,22 @@ namespace JT809.Protocol.ProtocolPacket.Extensions var tempBuffe = dataList.ToArray(); return tempBuffe; } + /// + /// 从数据头到校验码前的 CRC 1 G-CCITT 的校验值,遵循人端排序方式的规定。 + /// + /// + /// + /// + /// + /// internal static ushort CRC16_CCITT(this Package packege, byte[] ucbuf, int offset, int iLen) { - ushort crc = 0xFFFF; - ushort polynomial = 0x1021; - for (int j = 0; j < iLen; ++j) + ushort checkCode = 0xFFFF; + for (int j = offset; j < iLen; ++j) { - for (int i = 0; i < 8; i++) - { - bool bit = ((ucbuf[j + offset] >> (7 - i) & 1) == 1); - bool c15 = ((crc >> 15 & 1) == 1); - crc <<= 1; - if (c15 ^ bit) crc ^= polynomial; - } + checkCode = (ushort)((checkCode << 8) ^ (ushort)CRC[(checkCode >> 8) ^ ucbuf[j]]); } - crc &= 0xffff; - return crc; + return checkCode; } internal static byte[] Encrypt(this Package packege, byte[] buffer, int size, JT809EncryptConfig Config) { diff --git a/src/JT809.Protocol/ProtocolPacket/Header.cs b/src/JT809.Protocol/ProtocolPacket/Header.cs index 05fd481..772ec14 100644 --- a/src/JT809.Protocol/ProtocolPacket/Header.cs +++ b/src/JT809.Protocol/ProtocolPacket/Header.cs @@ -1,4 +1,5 @@ -using JT809.Protocol.Enums; +using JT809.Protocol.Configs; +using JT809.Protocol.Enums; using System; using System.IO; @@ -40,8 +41,8 @@ namespace JT809.Protocol.ProtocolPacket /// /// 下级平台接入码,上级平台给下级平台分配唯一标识码。 /// - public uint GNSSCENTERID { get; set; } - public Version Version { get; private set; } + public uint SessionId { get; set; } + public JT809Version JT809Version { get; private set; } public EncryptOpitions EncryptOpition { get; private set; } /// /// 数据加密的密匙,长度为 4 个字节。 @@ -50,20 +51,51 @@ namespace JT809.Protocol.ProtocolPacket public Header(byte[] buffer) : base(buffer) { CounterOnRecieveGenerater++; } + internal Header(uint length, uint number, BusinessType businessID, JT809Config jt809Config) : base(length, number, businessID, jt809Config) + { CounterOnSendGenerater++; } + + public Header(uint length, BusinessType businessID, JT809Config jt809Config) : this(length, CounterOnSendGenerater, businessID, jt809Config) { } protected override void InitializeProperties(object[] properties, int startIndex) { - throw new NotImplementedException(); + Length = (uint)properties[0] + Package.NotDataLength; + SN = (uint)properties[1]; + BusinessID = (BusinessType)properties[2]; + JT809Config jt809Config=(JT809Config)properties[3]; + SessionId = jt809Config.SessionId; + JT809Version = jt809Config.JT809Version; + EncryptOpition = jt809Config.JT809EncryptConfig==null? EncryptOpitions.None: EncryptOpitions.Common; + if(jt809Config.JT809EncryptConfig == null) + { + EncryptOpition = EncryptOpitions.None; + } + else + { + EncryptOpition = EncryptOpitions.Common; + EncryptKey = jt809Config.JT809EncryptConfig.Key; + } } protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader) { - throw new NotImplementedException(); + Length = reader.ReadUInt32Little(); + SN = reader.ReadUInt32Little(); + BusinessID = (BusinessType)reader.ReadUInt16Little(); + SessionId = reader.ReadUInt32Little(); + JT809Version = new JT809Version(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); + EncryptOpition = (EncryptOpitions)reader.ReadByte(); + EncryptKey = reader.ReadUInt32Little(); } protected override void OnWriteToBuffer(BinaryWriter writer) { - throw new NotImplementedException(); + writer.WriteLittle(Length); + writer.WriteLittle(SN); + writer.WriteLittle((ushort)BusinessID); + writer.WriteLittle(SessionId); + writer.WriteLittle(JT809Version.Buffer); + writer.WriteLittle((byte)EncryptOpition); + writer.WriteLittle(EncryptKey); } } } diff --git a/src/JT809.Protocol/ProtocolPacket/Version.cs b/src/JT809.Protocol/ProtocolPacket/JT809Version.cs similarity index 88% rename from src/JT809.Protocol/ProtocolPacket/Version.cs rename to src/JT809.Protocol/ProtocolPacket/JT809Version.cs index 6801953..22226ac 100644 --- a/src/JT809.Protocol/ProtocolPacket/Version.cs +++ b/src/JT809.Protocol/ProtocolPacket/JT809Version.cs @@ -1,46 +1,46 @@ -namespace JT809.Protocol.ProtocolPacket -{ - /// - /// 协议版本好标识,上下级平台之间采用的标准协议版编号; - /// 长度为 3 个字节来表示, - /// 0x01 0x02 0x0F 标识的版本号是 v1.2.15,以此类推。 - /// - public class Version - { - public byte[] Buffer { get; } = new byte[3]; - private const int MajorIndex = 0; - private const int MinorIndex = 1; - private const int BuildIndex = 2; - public byte Major - { - get { return Buffer[MajorIndex]; } - private set { Buffer[MajorIndex] = value; } - } - public byte Minor - { - get { return Buffer[MinorIndex]; } - private set { Buffer[MinorIndex] = value; } - } - public byte Build - { - get { return Buffer[BuildIndex]; } - private set { Buffer[BuildIndex] = value; } - } - public Version() - { - Major = 1; - Minor = 0; - Build = 0; - } - public Version(byte major, byte minor, byte buid) - { - Major = major; - Minor = minor; - Build = buid; - } - public override string ToString() - { - return $"{Major}.{Minor}.{Build}"; - } - } -} +namespace JT809.Protocol.ProtocolPacket +{ + /// + /// 协议版本好标识,上下级平台之间采用的标准协议版编号; + /// 长度为 3 个字节来表示, + /// 0x01 0x02 0x0F 标识的版本号是 v1.2.15,以此类推。 + /// + public class JT809Version + { + public byte[] Buffer { get; } = new byte[3]; + private const int MajorIndex = 0; + private const int MinorIndex = 1; + private const int BuildIndex = 2; + public byte Major + { + get { return Buffer[MajorIndex]; } + private set { Buffer[MajorIndex] = value; } + } + public byte Minor + { + get { return Buffer[MinorIndex]; } + private set { Buffer[MinorIndex] = value; } + } + public byte Build + { + get { return Buffer[BuildIndex]; } + private set { Buffer[BuildIndex] = value; } + } + public JT809Version() + { + Major = 1; + Minor = 0; + Build = 0; + } + public JT809Version(byte major, byte minor, byte buid) + { + Major = major; + Minor = minor; + Build = buid; + } + public override string ToString() + { + return $"{Major}.{Minor}.{Build}"; + } + } +} diff --git a/src/JT809.Protocol/ProtocolPacket/MessageBody.cs b/src/JT809.Protocol/ProtocolPacket/MessageBody.cs index ccb59ba..017d648 100644 --- a/src/JT809.Protocol/ProtocolPacket/MessageBody.cs +++ b/src/JT809.Protocol/ProtocolPacket/MessageBody.cs @@ -9,5 +9,7 @@ namespace JT809.Protocol.ProtocolPacket /// public abstract class MessageBody: BufferedEntityBase { + protected MessageBody(params object[] properties) : base(properties){} + protected MessageBody(byte[] buffer):base(buffer){} } } diff --git a/src/JT809.Protocol/ProtocolPacket/Package.cs b/src/JT809.Protocol/ProtocolPacket/Package.cs index 0f5e3cf..9709882 100644 --- a/src/JT809.Protocol/ProtocolPacket/Package.cs +++ b/src/JT809.Protocol/ProtocolPacket/Package.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.Linq; using System.Text; using JT809.Protocol.Configs; using JT809.Protocol.Enums; @@ -18,8 +20,10 @@ namespace JT809.Protocol.ProtocolPacket public const int Crc16ByteLength = 2; public const byte BeginFlag = 0X5B; public const byte EndFlag = 0X5D; + public const int BeginFixedByteLength = 1; + public const int EndFixedByteLength = 1; - public JT809EncryptConfig Config; + public JT809Config JT809Config; public Header Header { get; private set; } @@ -27,24 +31,29 @@ namespace JT809.Protocol.ProtocolPacket private ushort CRC16 { get; set; } - public Package(byte[] buffer) : base(buffer) - { } + public Package(byte[] buffer) : base(buffer){} - public Package(Header header, MessageBody body) : base(header, body) - { } + public Package(Header header, MessageBody body, JT809Config jt809Config) : base(header, body) + { + JT809Config = jt809Config; + } protected override void InitializeProperties(object[] properties, int startIndex) { - throw new NotImplementedException(); + Header = properties[0] as Header; + Body = properties[1] as MessageBody; + if (Header == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Header can't be null."); + if (Body == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Body can't be null."); } protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader) { - var content00 = Buffer; + var content00 = new byte[Buffer.Length- BeginFixedByteLength-EndFixedByteLength]; + Array.Copy(Buffer, BeginFixedByteLength, content00, 0, Buffer.Length- BeginFixedByteLength-EndFixedByteLength); var content01 = this.UnEscape(content00); var crc16 = this.CRC16_CCITT(content01, 0, content01.Length - Crc16ByteLength); CRC16 = BitConverter.ToUInt16(new[] { content01[content01.Length - 1], content01[content01.Length - 2] }, 0); - if (CRC16 != crc16) throw new JT809Exception(ErrorCode.CRC16CheckInvalid); + if (CRC16 != crc16) throw new JT809Exception(ErrorCode.CRC16CheckInvalid,$"{CRC16}-{crc16},{content01.ToHexString()}"); Header = new Header(content01); var bodyBuffer00 = new byte[content01.Length - Header.HeaderFixedByteLength - Crc16ByteLength]; Array.Copy(content01, Header.HeaderFixedByteLength, bodyBuffer00, 0, bodyBuffer00.Length); @@ -55,7 +64,7 @@ namespace JT809.Protocol.ProtocolPacket case EncryptOpitions.None: break; case EncryptOpitions.Common: - bodyBuffer01 = this.Encrypt(bodyBuffer01, bodyBuffer01.Length, Config); + bodyBuffer01 = this.Encrypt(bodyBuffer01, bodyBuffer01.Length, JT809Config.JT809EncryptConfig); break; } if (Header.Length != (bodyBuffer01.Length + NotDataLength)) throw new JT809Exception(ErrorCode.HeaderLengthNotEqualBodyLength); @@ -64,7 +73,39 @@ namespace JT809.Protocol.ProtocolPacket protected override void OnWriteToBuffer(BinaryWriter writer) { - throw new NotImplementedException(); + writer.WriteLittle(BeginFlag); + //Dealling Code On Header + var headerBuffer00 = Header.Buffer; + //Dealling Code On Body + byte[] bodyBuffer00 = Body.Buffer; + switch (Header.EncryptOpition) + { + case EncryptOpitions.None: + bodyBuffer00 = Body.Buffer; + break; + case EncryptOpitions.Common: + bodyBuffer00 = this.Encrypt(Body.Buffer, Body.Buffer.Length, JT809Config.JT809EncryptConfig); + break; + } + //Content:Except BeginFlag & EndFlag + var content = new byte[headerBuffer00.Length + bodyBuffer00.Length + Crc16ByteLength]; + Array.Copy(headerBuffer00, 0, content, 0, headerBuffer00.Length); + Array.Copy(bodyBuffer00, 0, content, headerBuffer00.Length, bodyBuffer00.Length); + //Dealling Code On CRC16 + CRC16 = this.CRC16_CCITT(content, 0, content.Length - Crc16ByteLength); + var crc1600 = BitConverter.GetBytes(CRC16).Reverse().ToArray(); + Array.Copy(crc1600, 0, content, headerBuffer00.Length + bodyBuffer00.Length, Crc16ByteLength); + //Last Content + var content00 = this.Escape(content); + //ToBuffer Core. + writer.WriteLittle(content00); + writer.WriteLittle(EndFlag); + } + + public static Package GeneratePackage(BusinessType businessType, MessageBody messageBody, JT809Config jt809Config) + { + var header = new Header((uint)messageBody.Buffer.Length, businessType, jt809Config); + return new Package(header, messageBody, jt809Config); } public static MessageBody GenerateBody(BusinessType businessID, byte[] bodyBuffer)