@@ -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 | |||
}; | |||
} | |||
} |
@@ -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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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); | |||
//} | |||
} | |||
} |
@@ -1,78 +1,20 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<Import Project="..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" /> | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
<ProjectGuid>{D1C5968B-741D-4D75-BB33-BD006C897D05}</ProjectGuid> | |||
<OutputType>Library</OutputType> | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>JT809.Protocol.Test</RootNamespace> | |||
<AssemblyName>JT809.Protocol.Test</AssemblyName> | |||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> | |||
<FileAlignment>512</FileAlignment> | |||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion> | |||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | |||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath> | |||
<IsCodedUITest>False</IsCodedUITest> | |||
<TestProjectType>UnitTest</TestProjectType> | |||
<NuGetPackageImportStamp> | |||
</NuGetPackageImportStamp> | |||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
<DebugSymbols>true</DebugSymbols> | |||
<DebugType>full</DebugType> | |||
<Optimize>false</Optimize> | |||
<OutputPath>bin\Debug\</OutputPath> | |||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
<DebugType>pdbonly</DebugType> | |||
<Optimize>true</Optimize> | |||
<OutputPath>bin\Release\</OutputPath> | |||
<DefineConstants>TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System" /> | |||
<Reference Include="System.Core" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="BaseTest.cs" /> | |||
<Compile Include="Encrypt\JT809EncryptImplTest.cs" /> | |||
<Compile Include="Escape\JT809EscapeImplTest.cs" /> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="packages.config" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\JT809.Protocol\JT809.Protocol.csproj"> | |||
<Project>{4d33a5c9-f583-4230-9791-ab0394efad57}</Project> | |||
<Name>JT809.Protocol</Name> | |||
</ProjectReference> | |||
<ProjectReference Include="..\JT809.Protocol\JT809.Protocol.csproj" /> | |||
</ItemGroup> | |||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props'))" /> | |||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets'))" /> | |||
</Target> | |||
<Import Project="..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" /> | |||
</Project> | |||
</Project> |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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")] |
@@ -1,6 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="MSTest.TestAdapter" version="1.2.1" targetFramework="net461" /> | |||
<package id="MSTest.TestFramework" version="1.2.1" targetFramework="net461" /> | |||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" /> | |||
</packages> |
@@ -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 | |||
@@ -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; | |||
} | |||
/// <summary> | |||
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。 | |||
/// </summary> | |||
public uint SessionId { get; set; } | |||
/// <summary> | |||
/// 加密配置 | |||
/// </summary> | |||
public JT809EncryptConfig JT809EncryptConfig { get; set; } | |||
/// <summary> | |||
/// 版本号 | |||
/// </summary> | |||
public JT809Version JT809Version { get; set; } = new JT809Version(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
@@ -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); | |||
} | |||
/// <summary> | |||
/// 字节数组转16进制字符串 | |||
/// </summary> | |||
/// <param name="bytes"></param> | |||
/// <param name="separator">默认 " "</param> | |||
/// <returns></returns> | |||
public static string ToHexString(this byte[] bytes,string separator=" ") | |||
{ | |||
return string.Join(separator, bytes.Select(s => s.ToString("X2"))); | |||
} | |||
/// <summary> | |||
/// 16进制字符串转16进制数组 | |||
/// </summary> | |||
/// <param name="hexString"></param> | |||
/// <param name="separator"></param> | |||
/// <returns></returns> | |||
public static byte[] ToHexBytes(this string hexString, string separator = " ") | |||
{ | |||
return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray(); | |||
} | |||
} | |||
} |
@@ -9,6 +9,28 @@ namespace JT809.Protocol.ProtocolPacket.Extensions | |||
/// </summary> | |||
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<byte> dataList = new List<byte>(); | |||
@@ -80,22 +102,22 @@ namespace JT809.Protocol.ProtocolPacket.Extensions | |||
var tempBuffe = dataList.ToArray(); | |||
return tempBuffe; | |||
} | |||
/// <summary> | |||
/// 从数据头到校验码前的 CRC 1 G-CCITT 的校验值,遵循人端排序方式的规定。 | |||
/// </summary> | |||
/// <param name="packege"></param> | |||
/// <param name="ucbuf"></param> | |||
/// <param name="offset"></param> | |||
/// <param name="iLen"></param> | |||
/// <returns></returns> | |||
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) | |||
{ | |||
@@ -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 | |||
/// <summary> | |||
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。 | |||
/// </summary> | |||
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; } | |||
/// <summary> | |||
/// 数据加密的密匙,长度为 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); | |||
} | |||
} | |||
} |
@@ -1,46 +1,46 @@ | |||
namespace JT809.Protocol.ProtocolPacket | |||
{ | |||
/// <summary> | |||
/// 协议版本好标识,上下级平台之间采用的标准协议版编号; | |||
/// 长度为 3 个字节来表示, | |||
/// 0x01 0x02 0x0F 标识的版本号是 v1.2.15,以此类推。 | |||
/// </summary> | |||
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 | |||
{ | |||
/// <summary> | |||
/// 协议版本好标识,上下级平台之间采用的标准协议版编号; | |||
/// 长度为 3 个字节来表示, | |||
/// 0x01 0x02 0x0F 标识的版本号是 v1.2.15,以此类推。 | |||
/// </summary> | |||
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}"; | |||
} | |||
} | |||
} |
@@ -9,5 +9,7 @@ namespace JT809.Protocol.ProtocolPacket | |||
/// </summary> | |||
public abstract class MessageBody: BufferedEntityBase | |||
{ | |||
protected MessageBody(params object[] properties) : base(properties){} | |||
protected MessageBody(byte[] buffer):base(buffer){} | |||
} | |||
} |
@@ -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) | |||