@@ -20,13 +20,32 @@ namespace JT809.Protocol.Test.JT809MessageBody | |||||
jT809_0X1001.DownLinkIP = "127.0.0.1"; | jT809_0X1001.DownLinkIP = "127.0.0.1"; | ||||
jT809_0X1001.DownLinkPort = 809; | jT809_0X1001.DownLinkPort = 809; | ||||
var hex = JT809Serializer.Serialize(jT809_0X1001).ToHexString(); | var hex = JT809Serializer.Serialize(jT809_0X1001).ToHexString(); | ||||
//"01 33 EF B8 32 30 31 38 30 39 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 32 37 2E 30 2E 30 2E 31 03 29" | |||||
//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 EF B8 | |||||
//32 30 31 38 30 39 32 30 | |||||
//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 | |||||
//C3 0D | |||||
//5D | |||||
//"01 33 EF B8 | |||||
//32 30 31 38 30 39 32 30 | |||||
//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" | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
var bytes = "01 33 EF B8 32 30 31 38 30 39 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 32 37 2E 30 2E 30 2E 31 03 29".ToHexBytes(); | |||||
var bytes = "01 33 EF B8 32 30 31 38 30 39 32 30 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".ToHexBytes(); | |||||
JT809_0x1001 jT809_0X1001 = JT809Serializer.Deserialize<JT809_0x1001>(bytes); | JT809_0x1001 jT809_0X1001 = JT809Serializer.Deserialize<JT809_0x1001>(bytes); | ||||
Assert.Equal((uint)20180920, jT809_0X1001.UserId); | Assert.Equal((uint)20180920, jT809_0X1001.UserId); | ||||
Assert.Equal("20180920", jT809_0X1001.Password); | Assert.Equal("20180920", jT809_0X1001.Password); | ||||
@@ -0,0 +1,67 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JT809.Protocol; | |||||
using JT809.Protocol.JT809Extensions; | |||||
using JT809.Protocol.JT809MessageBody; | |||||
using JT809.Protocol.JT809Encrypt; | |||||
namespace JT809.Protocol.Test.JT809Packages | |||||
{ | |||||
public class JT809_0x1001EncryptPackageTest | |||||
{ | |||||
public JT809_0x1001EncryptPackageTest() | |||||
{ | |||||
JT809GlobalConfig.Instance.SetJT809Encrypt(new JT809EncryptImpl(new JT809Configs.JT809EncryptOptions() | |||||
{ | |||||
IA1 = 20000000, | |||||
IC1 = 20000000, | |||||
M1 = 30000000, | |||||
Key = 256178, | |||||
})); | |||||
} | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JT809Package jT809Package = new JT809Package(); | |||||
jT809Package.Header = new JT809Header | |||||
{ | |||||
EncryptFlag= JT809Header_Encrypt.Common, | |||||
MsgSN= 133, | |||||
EncryptKey=5819, | |||||
MsgID= JT809Enums.JT809BusinessType.UP_CONNECT_REQ, | |||||
MsgGNSSCENTERID= 20180920, | |||||
}; | |||||
JT809_0x1001 jT809_0X1001 = new JT809_0x1001(); | |||||
jT809_0X1001.UserId = 20180920; | |||||
jT809_0X1001.Password = "20180920"; | |||||
jT809_0X1001.DownLinkIP = "127.0.0.1"; | |||||
jT809_0X1001.DownLinkPort = 809; | |||||
jT809Package.Bodies = jT809_0X1001; | |||||
var hex = JT809Serializer.Serialize(jT809Package).ToHexString(); | |||||
//"5B 00 00 00 48 00 00 00 85 10 01 01 33 EF B8 01 00 00 01 00 00 16 BB D3 7D 9C C4 90 0C 77 DC 78 F8 67 65 27 D8 AE 12 24 3C FB 64 CC 2F BA 61 9A EF AD 33 AC CB 32 56 F6 7B FF 19 DF 33 09 78 41 09 86 65 70 3F 2E B5 5D" | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var bytes = "5B 00 00 00 48 00 00 00 85 10 01 01 33 EF B8 01 00 00 01 00 00 16 BB D3 7D 9C C4 90 0C 77 DC 78 F8 67 65 27 D8 AE 12 24 3C FB 64 CC 2F BA 61 9A EF AD 33 AC CB 32 56 F6 7B FF 19 DF 33 09 78 41 09 86 65 70 3F 2E B5 5D".ToHexBytes(); | |||||
JT809Package jT809Package = JT809Serializer.Deserialize(bytes); | |||||
Assert.Equal(JT809Header_Encrypt.Common, jT809Package.Header.EncryptFlag); | |||||
Assert.Equal((uint)5819, jT809Package.Header.EncryptKey); | |||||
Assert.Equal((uint)72, jT809Package.Header.MsgLength); | |||||
Assert.Equal((uint)133, jT809Package.Header.MsgSN); | |||||
Assert.Equal((uint)5819, jT809Package.Header.EncryptKey); | |||||
Assert.Equal((uint)20180920, jT809Package.Header.MsgGNSSCENTERID); | |||||
Assert.Equal(JT809Enums.JT809BusinessType.UP_CONNECT_REQ, jT809Package.Header.MsgID); | |||||
Assert.Equal(new JT809Header_Version().ToString(), jT809Package.Header.Version.ToString()); | |||||
JT809_0x1001 jT809_0X1001 = (JT809_0x1001)jT809Package.Bodies; | |||||
Assert.Equal((uint)20180920, jT809_0X1001.UserId); | |||||
Assert.Equal("20180920", jT809_0X1001.Password); | |||||
Assert.Equal("127.0.0.1", jT809_0X1001.DownLinkIP); | |||||
Assert.Equal((ushort)809, jT809_0X1001.DownLinkPort); | |||||
} | |||||
} | |||||
} |
@@ -11,6 +11,8 @@ namespace JT809.Protocol.JT809Formatters | |||||
{ | { | ||||
public class JT809PackageFormatter : IJT809Formatter<JT809Package> | public class JT809PackageFormatter : IJT809Formatter<JT809Package> | ||||
{ | { | ||||
public object JT808BinaryExtensions { get; private set; } | |||||
public JT809Package Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | public JT809Package Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | ||||
{ | { | ||||
int offset = 0; | int offset = 0; | ||||
@@ -42,16 +44,6 @@ namespace JT809.Protocol.JT809Formatters | |||||
throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{offset.ToString()}", ex); | throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{offset.ToString()}", ex); | ||||
} | } | ||||
offset += readSize; | offset += readSize; | ||||
// 4.是否加密 | |||||
switch (jT809Package.Header.EncryptFlag) | |||||
{ | |||||
case JT809Header_Encrypt.None: | |||||
break; | |||||
case JT809Header_Encrypt.Common: | |||||
#warning 加密尚未实现 | |||||
break; | |||||
} | |||||
// 5.数据体处理 | // 5.数据体处理 | ||||
// 5.1 判断是否有数据体(总长度-固定长度)> 0 | // 5.1 判断是否有数据体(总长度-固定长度)> 0 | ||||
if ((jT809Package.Header.MsgLength - JT809Package.FixedByteLength) > 0) | if ((jT809Package.Header.MsgLength - JT809Package.FixedByteLength) > 0) | ||||
@@ -62,10 +54,18 @@ namespace JT809.Protocol.JT809Formatters | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
var a = buffer.Slice(offset); | |||||
var b = buffer.Slice(offset,checkIndex - offset); | |||||
//5.2 处理消息体 | |||||
jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), buffer.Slice(offset, checkIndex - offset), out readSize); | |||||
// 5.2 是否加密 | |||||
switch (jT809Package.Header.EncryptFlag) | |||||
{ | |||||
case JT809Header_Encrypt.None: | |||||
//5.3 处理消息体 | |||||
jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), buffer.Slice(offset, checkIndex - offset), out readSize); | |||||
break; | |||||
case JT809Header_Encrypt.Common: | |||||
byte[] bodiesData = JT809GlobalConfig.Instance.JT809Encrypt.Decrypt(buffer.Slice(offset, checkIndex - offset).ToArray()); | |||||
jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), bodiesData, out readSize); | |||||
break; | |||||
} | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
@@ -94,18 +94,16 @@ namespace JT809.Protocol.JT809Formatters | |||||
byte[] messageBodyData=null; | byte[] messageBodyData=null; | ||||
if (messageBodyOffset != 0) | if (messageBodyOffset != 0) | ||||
{ | { | ||||
messageBodyData = memoryOwner.Memory.Slice(0, messageBodyOffset).Span.ToArray(); | |||||
// 1.2 数据加密 | // 1.2 数据加密 | ||||
switch (value.Header.EncryptFlag) | switch (value.Header.EncryptFlag) | ||||
{ | { | ||||
case JT809Header_Encrypt.None: | case JT809Header_Encrypt.None: | ||||
break; | break; | ||||
case JT809Header_Encrypt.Common: | case JT809Header_Encrypt.Common: | ||||
#warning 加密尚未实现 | |||||
messageBodyData = JT809GlobalConfig.Instance.JT809Encrypt.Encrypt(messageBodyData); | |||||
break; | break; | ||||
} | } | ||||
// 1.3 数据内容进行转义 | |||||
messageBodyData = JT809Escape(memoryOwner.Memory.Slice(0, messageBodyOffset).Span); | |||||
} | } | ||||
// ------------------------------------开始组包 | // ------------------------------------开始组包 | ||||
// 1.起始符 | // 1.起始符 | ||||
@@ -132,7 +130,11 @@ namespace JT809.Protocol.JT809Formatters | |||||
offset += JT809BinaryExtensions.WriteUInt16Little(memoryOwner, offset, memoryOwner.Memory.Span.ToCRC16_CCITT(1, offset)); | offset += JT809BinaryExtensions.WriteUInt16Little(memoryOwner, offset, memoryOwner.Memory.Span.ToCRC16_CCITT(1, offset)); | ||||
// 5.终止符 | // 5.终止符 | ||||
offset += JT809BinaryExtensions.WriteByteLittle(memoryOwner, offset, value.EndFlag); | offset += JT809BinaryExtensions.WriteByteLittle(memoryOwner, offset, value.EndFlag); | ||||
return offset; | |||||
// 6.转义 | |||||
byte[] temp = JT809Escape(memoryOwner.Memory.Slice(0, offset).Span); | |||||
memoryOwner.Memory.Span.Clear(); | |||||
JT809BinaryExtensions.CopyTo(temp, memoryOwner.Memory.Span, 0); | |||||
return temp.Length; | |||||
} | } | ||||
private static ReadOnlySpan<byte> JT809DeEscape(ReadOnlySpan<byte> buffer) | private static ReadOnlySpan<byte> JT809DeEscape(ReadOnlySpan<byte> buffer) | ||||
@@ -0,0 +1,29 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol | |||||
{ | |||||
public sealed class JT809GlobalConfig | |||||
{ | |||||
private static readonly Lazy<JT809GlobalConfig> instance = new Lazy<JT809GlobalConfig>(() => new JT809GlobalConfig()); | |||||
private JT809GlobalConfig(){} | |||||
public static JT809GlobalConfig Instance | |||||
{ | |||||
get | |||||
{ | |||||
return instance.Value; | |||||
} | |||||
} | |||||
public IJT809Encrypt JT809Encrypt { get; private set; } | |||||
public JT809GlobalConfig SetJT809Encrypt(IJT809Encrypt jT809Encrypt) | |||||
{ | |||||
instance.Value.JT809Encrypt = jT809Encrypt; | |||||
return instance.Value; | |||||
} | |||||
} | |||||
} |