@@ -20,13 +20,32 @@ namespace JT809.Protocol.Test.JT809MessageBody | |||
jT809_0X1001.DownLinkIP = "127.0.0.1"; | |||
jT809_0X1001.DownLinkPort = 809; | |||
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] | |||
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); | |||
Assert.Equal((uint)20180920, jT809_0X1001.UserId); | |||
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 object JT808BinaryExtensions { get; private set; } | |||
public JT809Package Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | |||
{ | |||
int offset = 0; | |||
@@ -42,16 +44,6 @@ namespace JT809.Protocol.JT809Formatters | |||
throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{offset.ToString()}", ex); | |||
} | |||
offset += readSize; | |||
// 4.是否加密 | |||
switch (jT809Package.Header.EncryptFlag) | |||
{ | |||
case JT809Header_Encrypt.None: | |||
break; | |||
case JT809Header_Encrypt.Common: | |||
#warning 加密尚未实现 | |||
break; | |||
} | |||
// 5.数据体处理 | |||
// 5.1 判断是否有数据体(总长度-固定长度)> 0 | |||
if ((jT809Package.Header.MsgLength - JT809Package.FixedByteLength) > 0) | |||
@@ -62,10 +54,18 @@ namespace JT809.Protocol.JT809Formatters | |||
{ | |||
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) | |||
{ | |||
@@ -94,18 +94,16 @@ namespace JT809.Protocol.JT809Formatters | |||
byte[] messageBodyData=null; | |||
if (messageBodyOffset != 0) | |||
{ | |||
messageBodyData = memoryOwner.Memory.Slice(0, messageBodyOffset).Span.ToArray(); | |||
// 1.2 数据加密 | |||
switch (value.Header.EncryptFlag) | |||
{ | |||
case JT809Header_Encrypt.None: | |||
break; | |||
case JT809Header_Encrypt.Common: | |||
#warning 加密尚未实现 | |||
messageBodyData = JT809GlobalConfig.Instance.JT809Encrypt.Encrypt(messageBodyData); | |||
break; | |||
} | |||
// 1.3 数据内容进行转义 | |||
messageBodyData = JT809Escape(memoryOwner.Memory.Slice(0, messageBodyOffset).Span); | |||
} | |||
// ------------------------------------开始组包 | |||
// 1.起始符 | |||
@@ -132,7 +130,11 @@ namespace JT809.Protocol.JT809Formatters | |||
offset += JT809BinaryExtensions.WriteUInt16Little(memoryOwner, offset, memoryOwner.Memory.Span.ToCRC16_CCITT(1, offset)); | |||
// 5.终止符 | |||
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) | |||
@@ -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; | |||
} | |||
} | |||
} |