@@ -0,0 +1,23 @@ | |||
name: .NET Core | |||
on: [push] | |||
jobs: | |||
build: | |||
runs-on: ubuntu-latest | |||
steps: | |||
- uses: actions/checkout@master | |||
- name: Setup .NET Core | |||
uses: actions/setup-dotnet@master | |||
with: | |||
dotnet-version: 3.1.101 | |||
- name: dotnet info | |||
run: dotnet --info | |||
- name: dotnet restore | |||
run: dotnet restore ./src/JT809.Protocol.sln | |||
- name: dotnet build | |||
run: dotnet build ./src/JT809.Protocol.Test/JT809.Protocol.Test.csproj | |||
- name: dotnet test | |||
run: dotnet test ./src/JT809.Protocol.Test/JT809.Protocol.Test.csproj |
@@ -1,15 +0,0 @@ | |||
language: csharp | |||
solution: JT809.Protocol.sln | |||
dotnet: 3.1.100 | |||
os: linux | |||
mono: none | |||
dist: trusty2 | |||
script: | |||
- dotnet restore src/JT809.Protocol.sln | |||
- dotnet build src/JT809.Protocol.Test/JT809.Protocol.Test.csproj | |||
- dotnet test src/JT809.Protocol.Test/JT809.Protocol.Test.csproj | |||
after_success: | |||
- echo successful build! | |||
branches: | |||
only: | |||
- master |
@@ -1,6 +1,6 @@ | |||
# JT809协议 | |||
[](https://github.com/SmallChi/JT809/blob/master/LICENSE)[](https://travis-ci.org/SmallChi/JT809) | |||
[](https://github.com/SmallChi/JT809/blob/master/LICENSE) | |||
## 前提条件 | |||
@@ -7,8 +7,8 @@ | |||
<ItemGroup> | |||
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" /> | |||
<PackageReference Include="System.Buffers" Version="4.5.0" /> | |||
<PackageReference Include="System.Memory" Version="4.5.3" /> | |||
<PackageReference Include="System.Buffers" Version="4.5.1" /> | |||
<PackageReference Include="System.Memory" Version="4.5.4" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
@@ -11,8 +11,8 @@ | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.3" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
@@ -26,5 +26,39 @@ namespace JT809.Protocol.Test.MessagePack | |||
jT809MessagePackReader.FullDecode(); | |||
Assert.Equal("5B 00 5A 48 5E 5E 00 5D".ToHexBytes(), jT809MessagePackReader.Reader.ToArray()); | |||
} | |||
[Fact] | |||
public void DecodeTest1() | |||
{ | |||
//5B | |||
//0000006E00000002140000000000010000000000000014020000004E31323334353637383931320001000000005E7B1E28000000005E7B1E28000000005E7B1E28B4A8413132333435000000000000000000000000000131323334353637383931320000007B00000000 | |||
//00 5A 02 4A | |||
//5D | |||
var data = "5B0000006E00000002140000000000010000000000000014020000004E31323334353637383931320001000000005E7B1E28000000005E7B1E28000000005E7B1E28B4A8413132333435000000000000000000000000000131323334353637383931320000007B000000005A024A5D".ToHexBytes(); | |||
JT809MessagePackReader jT809MessagePackReader = new JT809MessagePackReader(data); | |||
jT809MessagePackReader.Decode(); | |||
Assert.True(jT809MessagePackReader.CheckXorCodeVali); | |||
Assert.Equal(jT809MessagePackReader.Reader.Length, data.Length-1); | |||
} | |||
[Fact] | |||
public void DecodeTest2() | |||
{ | |||
//手动测试 | |||
var data = "5B0000006E00000002140000000000010000000000000014020000004E31323334353637383931320001000000005E7B1E28000000005E7B1E28000000005E7B1E28B4A8413132333435000000000000000000000000000131323334353637383931320000007B000000005A025A025D".ToHexBytes(); | |||
JT809MessagePackReader jT809MessagePackReader = new JT809MessagePackReader(data); | |||
jT809MessagePackReader.Decode(); | |||
Assert.Equal(jT809MessagePackReader.Reader.Length, data.Length - 2); | |||
} | |||
[Fact] | |||
public void DecodeTest3() | |||
{ | |||
//手动测试 | |||
var data = "5B0000006E00000002140000000000010000000000000014020000004E31323334353637383931320001000000005E7B1E28000000005E7B1E28000000005E7B1E28B4A8413132333435000000000000000000000000000131323334353637383931320000007B00000000A45A025D".ToHexBytes(); | |||
JT809MessagePackReader jT809MessagePackReader = new JT809MessagePackReader(data); | |||
jT809MessagePackReader.Decode(); | |||
Assert.Equal(jT809MessagePackReader.Reader.Length, data.Length - 1); | |||
} | |||
} | |||
} |
@@ -104,16 +104,16 @@ | |||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> | |||
<PackageReference Include="Microsoft.CSharp" Version="4.6.0" /> | |||
<PackageReference Include="System.Buffers" Version="4.5.0" /> | |||
<PackageReference Include="System.Buffers" Version="4.5.1" /> | |||
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" /> | |||
<PackageReference Include="System.Memory" Version="4.5.3" /> | |||
<PackageReference Include="System.Memory" Version="4.5.4" /> | |||
<PackageReference Include="System.Reflection.Extensions" Version="4.3.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> | |||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" /> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" /> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.3" /> | |||
</ItemGroup> | |||
@@ -63,42 +63,77 @@ namespace JT809.Protocol.MessagePack | |||
int len = SrcBuffer.Length; | |||
allocateBuffer[offset++] = SrcBuffer[0]; | |||
// 取出校验码看是否需要转义 | |||
ReadOnlySpan<byte> checkCodeBufferSpan1 = SrcBuffer.Slice(len - 3, 2); | |||
int checkCodeLen = 0; | |||
if (TryDecode(checkCodeBufferSpan1, out byte value1)) | |||
// 正常的 4A 4A 5D | |||
// 单个转义1 00 5A 02 4A 5D | |||
// 单个转义2 00 4A 5A 02 5D | |||
// 两个转义 5A 02 5A 02 5D | |||
// 两个转义 5A 02 02 5A 02 5D | |||
ReadOnlySpan<byte> checkCodeBufferSpan1 = SrcBuffer.Slice(len - 5, 4); | |||
byte checkCodeLen = 0; | |||
byte crcIndex = 0; | |||
(int Index, byte Value) Crc1 =(-1,0); | |||
(int Index, byte Value) Crc2 =(-1,0); | |||
for (int i = 0; i < checkCodeBufferSpan1.Length; i++) | |||
{ | |||
//最后两位是转义的 | |||
byte[] tmpCrc2 = new byte[2]; | |||
checkCodeLen += 2; | |||
tmpCrc2[1] = value1; | |||
//从最后往前在取两位进行转义 | |||
ReadOnlySpan<byte> checkCodeBufferSpan2 = SrcBuffer.Slice(len - 5, 2); | |||
if (TryDecode(checkCodeBufferSpan2, out byte value2)) | |||
if ((checkCodeBufferSpan1.Length - i) >= 2) | |||
{ | |||
//转义成功 | |||
tmpCrc2[0] = value2; | |||
checkCodeLen += 2; | |||
if (TryDecode(checkCodeBufferSpan1.Slice(i, 2), out byte tmp)) | |||
{ | |||
if (crcIndex > 0) | |||
{ | |||
Crc2.Index = i; | |||
Crc2.Value = tmp; | |||
} | |||
else | |||
{ | |||
Crc1.Index = i; | |||
Crc1.Value = tmp; | |||
} | |||
crcIndex++; | |||
i++; | |||
} | |||
} | |||
} | |||
if (Crc1.Index >= 0 && Crc2.Index > 0) | |||
{ | |||
byte[] crc = new byte[2]; | |||
//有两个需要转义的 | |||
crc[0] = Crc1.Value; | |||
crc[1] = Crc2.Value; | |||
checkCodeLen += 4; | |||
_realCheckCRCCode = ReadUInt16(crc); | |||
} | |||
else if(Crc1.Index >= 0 && Crc2.Index == -1) | |||
{ | |||
byte[] crc = new byte[2]; | |||
if ((checkCodeBufferSpan1.Length - Crc1.Index) > 2) | |||
{ | |||
//最开始有一个需要转义的 | |||
crc[0] = Crc1.Value; | |||
crc[1] = checkCodeBufferSpan1.Slice(Crc1.Index+2, 1)[0]; | |||
} | |||
else | |||
{ | |||
//转义不成功取当前最后一位 | |||
tmpCrc2[0] = checkCodeBufferSpan2[1]; | |||
checkCodeLen += 1; | |||
//最末尾有一个需要转义的 | |||
crc[0] = checkCodeBufferSpan1.Slice(Crc1.Index-1, 1)[0]; | |||
crc[1] = Crc1.Value; | |||
} | |||
_realCheckCRCCode = ReadUInt16(tmpCrc2); | |||
_realCheckCRCCode = ReadUInt16(crc); | |||
//存在一个转义的 | |||
checkCodeLen += 3; | |||
} | |||
else | |||
{ | |||
{ | |||
//最后两位不是转义的 | |||
_realCheckCRCCode=ReadUInt16(checkCodeBufferSpan1); | |||
checkCodeLen += 2; | |||
_realCheckCRCCode=ReadUInt16(SrcBuffer.Slice(len - 3, 2)); | |||
} | |||
//转义数据长度 | |||
//转义数据长度=len-校验码长度-头-尾 | |||
len = len - checkCodeLen - 1 - 1; | |||
ReadOnlySpan<byte> tmpBufferSpan = SrcBuffer.Slice(1, len); | |||
for (int i = 0; i < tmpBufferSpan.Length; i++) | |||
{ | |||
byte tmp = 0; | |||
byte tmp; | |||
if ((tmpBufferSpan.Length - i) >= 2) | |||
{ | |||
if (TryDecode(tmpBufferSpan.Slice(i, 2), out tmp)) | |||
@@ -115,7 +150,7 @@ namespace JT809.Protocol.MessagePack | |||
} | |||
allocateBuffer[offset++] = (byte)(_calculateCheckCRCCode >> 8); | |||
allocateBuffer[offset++] = (byte)_calculateCheckCRCCode; | |||
allocateBuffer[offset++] = SrcBuffer[SrcBuffer.Length- 1]; | |||
allocateBuffer[offset++] = SrcBuffer[SrcBuffer.Length - 1]; | |||
_checkCRCCodeVali = (_calculateCheckCRCCode == _realCheckCRCCode); | |||
Reader = allocateBuffer.Slice(0, offset); | |||
_decoded = true; | |||
@@ -128,7 +163,7 @@ namespace JT809.Protocol.MessagePack | |||
int len = SrcBuffer.Length; | |||
for (int i = 0; i < len; i++) | |||
{ | |||
byte tmp = 0; | |||
byte tmp; | |||
if ((SrcBuffer.Length - i) >= 2) | |||
{ | |||
if (TryDecode(SrcBuffer.Slice(i, 2), out tmp)) | |||