@@ -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协议 | # 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> | <ItemGroup> | ||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" /> | <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> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -11,8 +11,8 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<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" Version="2.4.1" /> | ||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | ||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
@@ -26,5 +26,39 @@ namespace JT809.Protocol.Test.MessagePack | |||||
jT809MessagePackReader.FullDecode(); | jT809MessagePackReader.FullDecode(); | ||||
Assert.Equal("5B 00 5A 48 5E 5E 00 5D".ToHexBytes(), jT809MessagePackReader.Reader.ToArray()); | 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' "> | <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> | ||||
<PackageReference Include="Microsoft.CSharp" Version="4.6.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.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" /> | <PackageReference Include="System.Reflection.Extensions" Version="4.3.0" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> | <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> | ||||
<PackageReference Include="System.Text.Encoding.CodePages" 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> | </ItemGroup> | ||||
@@ -63,42 +63,77 @@ namespace JT809.Protocol.MessagePack | |||||
int len = SrcBuffer.Length; | int len = SrcBuffer.Length; | ||||
allocateBuffer[offset++] = SrcBuffer[0]; | 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 | 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 | else | ||||
{ | |||||
{ | |||||
//最后两位不是转义的 | //最后两位不是转义的 | ||||
_realCheckCRCCode=ReadUInt16(checkCodeBufferSpan1); | |||||
checkCodeLen += 2; | checkCodeLen += 2; | ||||
_realCheckCRCCode=ReadUInt16(SrcBuffer.Slice(len - 3, 2)); | |||||
} | } | ||||
//转义数据长度 | |||||
//转义数据长度=len-校验码长度-头-尾 | |||||
len = len - checkCodeLen - 1 - 1; | len = len - checkCodeLen - 1 - 1; | ||||
ReadOnlySpan<byte> tmpBufferSpan = SrcBuffer.Slice(1, len); | ReadOnlySpan<byte> tmpBufferSpan = SrcBuffer.Slice(1, len); | ||||
for (int i = 0; i < tmpBufferSpan.Length; i++) | for (int i = 0; i < tmpBufferSpan.Length; i++) | ||||
{ | { | ||||
byte tmp = 0; | |||||
byte tmp; | |||||
if ((tmpBufferSpan.Length - i) >= 2) | if ((tmpBufferSpan.Length - i) >= 2) | ||||
{ | { | ||||
if (TryDecode(tmpBufferSpan.Slice(i, 2), out tmp)) | 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 >> 8); | ||||
allocateBuffer[offset++] = (byte)_calculateCheckCRCCode; | allocateBuffer[offset++] = (byte)_calculateCheckCRCCode; | ||||
allocateBuffer[offset++] = SrcBuffer[SrcBuffer.Length- 1]; | |||||
allocateBuffer[offset++] = SrcBuffer[SrcBuffer.Length - 1]; | |||||
_checkCRCCodeVali = (_calculateCheckCRCCode == _realCheckCRCCode); | _checkCRCCodeVali = (_calculateCheckCRCCode == _realCheckCRCCode); | ||||
Reader = allocateBuffer.Slice(0, offset); | Reader = allocateBuffer.Slice(0, offset); | ||||
_decoded = true; | _decoded = true; | ||||
@@ -128,7 +163,7 @@ namespace JT809.Protocol.MessagePack | |||||
int len = SrcBuffer.Length; | int len = SrcBuffer.Length; | ||||
for (int i = 0; i < len; i++) | for (int i = 0; i < len; i++) | ||||
{ | { | ||||
byte tmp = 0; | |||||
byte tmp; | |||||
if ((SrcBuffer.Length - i) >= 2) | if ((SrcBuffer.Length - i) >= 2) | ||||
{ | { | ||||
if (TryDecode(SrcBuffer.Slice(i, 2), out tmp)) | if (TryDecode(SrcBuffer.Slice(i, 2), out tmp)) | ||||