@@ -268,6 +268,18 @@ JT808Serializer DT2JT808Serializer = new JT808Serializer(DT2JT808Config); | |||||
[可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) | [可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) | ||||
### 举个栗子7 | |||||
如何兼容2019版本 | |||||
> 最新协议文档已经写好了如何做兼容,就是在消息体属性中第14位为版本标识。 | |||||
1. 当第14位为0时,标识协议为2011年的版本; | |||||
2. 当第14位为1时,标识协议为2019年的版本。 | |||||
[可以参考Simples的Demo7](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo7.cs) | |||||
## NuGet安装 | ## NuGet安装 | ||||
| Package Name | Version | Downloads | | | Package Name | Version | Downloads | | ||||
@@ -367,9 +379,9 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0 | |||||
| 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | | | 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | | ||||
| 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | | | 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | | ||||
| 59 | 0x8804 | √ | √ | 录音开始命令 | | | 59 | 0x8804 | √ | √ | 录音开始命令 | | ||||
| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 | | |||||
| 61 | 0x8900 | √ | √ | 数据下行透传 | | |||||
| 62 | 0x0900 | √ | √ | 数据上行透传 | | |||||
| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 |修改| | |||||
| 61 | 0x8900 | √ | √ | 数据下行透传 |修改| | |||||
| 62 | 0x0900 | √ | √ | 数据上行透传 |修改| | |||||
| 63 | 0x0901 | √ | √ | 数据压缩上报 | | | 63 | 0x0901 | √ | √ | 数据压缩上报 | | ||||
| 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | | | 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | | ||||
| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | | | 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | | ||||
@@ -381,3 +393,5 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0 | |||||
| 71 | 0x8204 | √ | √ | 链路检测 |新增| | | 71 | 0x8204 | √ | √ | 链路检测 |新增| | ||||
| 72 | 0x8608 | √ | √ | 查询区域或线路数据 |新增| | | 72 | 0x8608 | √ | √ | 查询区域或线路数据 |新增| | ||||
| 73 | 0x0608 | √ | √ | 查询区域或线路数据应答 |新增| | | 73 | 0x0608 | √ | √ | 查询区域或线路数据应答 |新增| | ||||
| 74 | 0xE000~0xEFFF | 保留 | 保留 | 厂商自定义上行消息 |新增| | |||||
| 75 | 0xF000~0xFFFF | 保留 | 保留 | 厂商自定义下行消息 |新增| |
@@ -40,7 +40,8 @@ namespace JT808.Protocol.Test | |||||
{ | { | ||||
MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | ||||
MsgNum = 1203, | MsgNum = 1203, | ||||
TerminalPhoneNo = "012345678900" | |||||
TerminalPhoneNo = "012345678900", | |||||
MessageBodyProperty=new JT808HeaderMessageBodyProperty() | |||||
}, | }, | ||||
Bodies = new JT808_0x0001 | Bodies = new JT808_0x0001 | ||||
{ | { | ||||
@@ -61,7 +62,7 @@ namespace JT808.Protocol.Test | |||||
{ | { | ||||
if (i % 2 == 0) | if (i % 2 == 0) | ||||
{ | { | ||||
defaultGlobalConfigs.Add(new DefaultGlobalConfig(i.ToString(), JT808Version.JTT2019)); | |||||
defaultGlobalConfigs.Add(new DefaultGlobalConfig(i.ToString())); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -17,7 +17,7 @@ namespace JT808.Protocol.Test.MessageBody | |||||
{ | { | ||||
MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | ||||
MsgNum = 1203, | MsgNum = 1203, | ||||
TerminalPhoneNo = "012345678900" | |||||
TerminalPhoneNo = "012345678900", | |||||
}, | }, | ||||
Bodies = new JT808_0x0001 | Bodies = new JT808_0x0001 | ||||
{ | { | ||||
@@ -88,7 +88,7 @@ namespace JT808.Protocol.Test.MessageBody | |||||
public void Package3() | public void Package3() | ||||
{ | { | ||||
byte[] bytes = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); | byte[] bytes = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); | ||||
JT808HeaderPackage jT808_0X0801 = JT808Serializer.Deserialize<JT808HeaderPackage>(bytes); | |||||
JT808HeaderPackage jT808_0X0801 = JT808Serializer.HeaderDeserialize(bytes); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -13,23 +13,23 @@ namespace JT808.Protocol.Test.MessageBody | |||||
{ | { | ||||
JT808_0x0805 jT808_0X0805 = new JT808_0x0805(); | JT808_0x0805 jT808_0X0805 = new JT808_0x0805(); | ||||
jT808_0X0805.ReplyMsgNum = 12456; | jT808_0X0805.ReplyMsgNum = 12456; | ||||
jT808_0X0805.Result = 1; | |||||
jT808_0X0805.Result = 0; | |||||
jT808_0X0805.MultimediaIds = new List<uint>() | jT808_0X0805.MultimediaIds = new List<uint>() | ||||
{ | { | ||||
12306, | 12306, | ||||
12580 | 12580 | ||||
}; | }; | ||||
string hex = JT808Serializer.Serialize(jT808_0X0805).ToHexString(); | string hex = JT808Serializer.Serialize(jT808_0X0805).ToHexString(); | ||||
Assert.Equal("30A80100020000301200003124", hex); | |||||
Assert.Equal("30A80000020000301200003124", hex); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
byte[] bytes = "30A80100020000301200003124".ToHexBytes(); | |||||
byte[] bytes = "30A80000020000301200003124".ToHexBytes(); | |||||
JT808_0x0805 jT808_0X0805 = JT808Serializer.Deserialize<JT808_0x0805>(bytes); | JT808_0x0805 jT808_0X0805 = JT808Serializer.Deserialize<JT808_0x0805>(bytes); | ||||
Assert.Equal(12456, jT808_0X0805.ReplyMsgNum); | Assert.Equal(12456, jT808_0X0805.ReplyMsgNum); | ||||
Assert.Equal(1, jT808_0X0805.Result); | |||||
Assert.Equal(0, jT808_0X0805.Result); | |||||
Assert.Equal(2, jT808_0X0805.MultimediaIdCount); | Assert.Equal(2, jT808_0X0805.MultimediaIdCount); | ||||
Assert.Equal(new List<uint>() | Assert.Equal(new List<uint>() | ||||
{ | { | ||||
@@ -1,84 +1,48 @@ | |||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.Internal; | |||||
using JT808.Protocol.Extensions; | |||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
using Xunit; | using Xunit; | ||||
using JT808.Protocol.MessageBody; | |||||
namespace JT808.Protocol.Test.Simples | namespace JT808.Protocol.Test.Simples | ||||
{ | { | ||||
public class Demo7 | public class Demo7 | ||||
{ | { | ||||
/// <summary> | |||||
/// 单个 | |||||
/// </summary> | |||||
[Fact] | |||||
public void Test1() | |||||
public JT808Serializer JT808Serializer; | |||||
public Demo7() | |||||
{ | { | ||||
IServiceCollection serviceDescriptors1 = new ServiceCollection(); | |||||
serviceDescriptors1.AddJT808Configure(new DefaultConfig()); | |||||
var serviceProvider1 = serviceDescriptors1.BuildServiceProvider(); | |||||
var config = serviceProvider1.GetRequiredService<IJT808Config>(); | |||||
var defaultConfig = (DefaultConfig)config; | |||||
Assert.Equal("test", defaultConfig.ConfigId); | |||||
Assert.Equal("smallchi", defaultConfig.Test()); | |||||
IJT808Config jT808Config = new DefaultGlobalConfig(); | |||||
JT808Serializer = new JT808Serializer(jT808Config); | |||||
} | } | ||||
/// <summary> | |||||
/// 多个 | |||||
/// </summary> | |||||
[Fact] | [Fact] | ||||
public void Test2() | |||||
public void Test1() | |||||
{ | { | ||||
IServiceCollection serviceDescriptors2 = new ServiceCollection(); | |||||
serviceDescriptors2.AddJT808Configure(new Config1()); | |||||
serviceDescriptors2.AddJT808Configure(new Config2()); | |||||
serviceDescriptors2.AddSingleton(factory => | |||||
JT808Package jT808Package = JT808MsgId.查询服务器时间应答.Create_查询服务器时间应答_2019("123456789012", | |||||
new JT808_0x8004 | |||||
{ | { | ||||
Func<string, IJT808Config> accesor = key => | |||||
{ | |||||
if (key.Equals("Config1")) | |||||
{ | |||||
return factory.GetService<Config1>(); | |||||
} | |||||
else if (key.Equals("Config2")) | |||||
{ | |||||
return factory.GetService<Config2>(); | |||||
} | |||||
else | |||||
{ | |||||
throw new ArgumentException($"Not Support key : {key}"); | |||||
} | |||||
}; | |||||
return accesor; | |||||
Time = DateTime.Parse("2019-12-02 10:10:10"), | |||||
}); | }); | ||||
var ServiceProvider2 = serviceDescriptors2.BuildServiceProvider(); | |||||
var config1 = ServiceProvider2.GetRequiredService<Func<string, IJT808Config>>()("Config1"); | |||||
Assert.Equal("Config1", config1.ConfigId); | |||||
Assert.Equal("Config1", config1.GetSerializer().SerializerId); | |||||
var config2 = ServiceProvider2.GetRequiredService<Func<string, IJT808Config>>()("Config2"); | |||||
Assert.Equal("Config2", config2.ConfigId); | |||||
Assert.Equal("Config2", config2.GetSerializer().SerializerId); | |||||
} | |||||
public class DefaultConfig : GlobalConfigBase | |||||
{ | |||||
public override string ConfigId { get; protected set; } = "test"; | |||||
public string Test() | |||||
{ | |||||
return "smallchi"; | |||||
} | |||||
jT808Package.Header.MsgNum = 1; | |||||
byte[] data = JT808Serializer.Serialize(jT808Package); | |||||
var hex = data.ToHexString(); | |||||
Assert.Equal("7E8004400601000000001234567890120001191202101010517E", hex); | |||||
} | } | ||||
public class Config1 : GlobalConfigBase | |||||
{ | |||||
public override string ConfigId { get; protected set; } = "Config1"; | |||||
} | |||||
public class Config2 : GlobalConfigBase | |||||
[Fact] | |||||
public void Test2() | |||||
{ | { | ||||
public override string ConfigId { get; protected set; } = "Config2"; | |||||
var data = "7E8004400601000000001234567890120001191202101010517E".ToHexBytes(); | |||||
JT808Package jT808Package = JT808Serializer.Deserialize(data); | |||||
Assert.Equal(JT808MsgId.查询服务器时间应答.ToUInt16Value(), jT808Package.Header.MsgId); | |||||
Assert.Equal(JT808Version.JTT2019, jT808Package.Version); | |||||
Assert.True(jT808Package.Header.MessageBodyProperty.VersionFlag); | |||||
Assert.Equal(DateTime.Parse("2019-12-02 10:10:10"), ((JT808_0x8004)jT808Package.Bodies).Time); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -456,5 +456,47 @@ namespace JT808.Protocol.Enums | |||||
[JT808BodiesType(typeof(JT808_0x0A00))] | [JT808BodiesType(typeof(JT808_0x0A00))] | ||||
[JT808MsgIdDescription("0x0A00", "终端RSA公钥")] | [JT808MsgIdDescription("0x0A00", "终端RSA公钥")] | ||||
终端RSA公钥 = 0x0A00, | 终端RSA公钥 = 0x0A00, | ||||
/// <summary> | |||||
/// 查询服务器时间请求 | |||||
/// 0x0004 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x0004))] | |||||
[JT808MsgIdDescription("0x0004", "查询服务器时间请求")] | |||||
查询服务器时间请求 = 0x0004, | |||||
/// <summary> | |||||
/// 查询服务器时间应答 | |||||
/// 0x8004 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x8004))] | |||||
[JT808MsgIdDescription("0x8004", "查询服务器时间应答")] | |||||
查询服务器时间应答 = 0x8004, | |||||
/// <summary> | |||||
/// 终端补传分包请求 | |||||
/// 0x0005 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x0005))] | |||||
[JT808MsgIdDescription("0x0005", "终端补传分包请求")] | |||||
终端补传分包请求 = 0x0005, | |||||
/// <summary> | |||||
/// 链路检测 | |||||
/// 0x8204 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x8204))] | |||||
[JT808MsgIdDescription("0x8204", "链路检测")] | |||||
链路检测 = 0x8204, | |||||
/// <summary> | |||||
/// 查询区域或线路数据 | |||||
/// 0x8608 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x8608))] | |||||
[JT808MsgIdDescription("0x8608", "查询区域或线路数据")] | |||||
查询区域或线路数据 = 0x8608, | |||||
/// <summary> | |||||
/// 查询区域或线路数据应答 | |||||
/// 0x0608 | |||||
/// </summary> | |||||
[JT808BodiesType(typeof(JT808_0x0608))] | |||||
[JT808MsgIdDescription("0x0608", "查询区域或线路数据应答")] | |||||
查询区域或线路数据应答 = 0x0608, | |||||
} | } | ||||
} | } |
@@ -12,7 +12,7 @@ namespace JT808.Protocol.Extensions | |||||
Header = new JT808Header | Header = new JT808Header | ||||
{ | { | ||||
MsgId = (ushort)msgId, | MsgId = (ushort)msgId, | ||||
TerminalPhoneNo = terminalPhoneNo | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
}, | }, | ||||
Bodies = bodies | Bodies = bodies | ||||
}; | }; | ||||
@@ -26,7 +26,7 @@ namespace JT808.Protocol.Extensions | |||||
Header = new JT808Header | Header = new JT808Header | ||||
{ | { | ||||
MsgId = (ushort)msgId, | MsgId = (ushort)msgId, | ||||
TerminalPhoneNo = terminalPhoneNo | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
} | } | ||||
}; | }; | ||||
return jT808Package; | return jT808Package; | ||||
@@ -59,5 +59,65 @@ namespace JT808.Protocol.Extensions | |||||
}; | }; | ||||
return jT808Package; | return jT808Package; | ||||
} | } | ||||
public static JT808Package Create2019<TJT808Bodies>(this JT808MsgId msgId, string terminalPhoneNo, TJT808Bodies bodies) | |||||
where TJT808Bodies : JT808Bodies | |||||
{ | |||||
JT808Package jT808Package = new JT808Package | |||||
{ | |||||
Header = new JT808Header | |||||
{ | |||||
MsgId = (ushort)msgId, | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
}, | |||||
Bodies = bodies | |||||
}; | |||||
jT808Package.Header.MessageBodyProperty.VersionFlag = true; | |||||
return jT808Package; | |||||
} | |||||
public static JT808Package Create2019(this JT808MsgId msgId, string terminalPhoneNo) | |||||
{ | |||||
JT808Package jT808Package = new JT808Package | |||||
{ | |||||
Header = new JT808Header | |||||
{ | |||||
MsgId = (ushort)msgId, | |||||
TerminalPhoneNo = terminalPhoneNo, | |||||
} | |||||
}; | |||||
jT808Package.Header.MessageBodyProperty.VersionFlag = true; | |||||
return jT808Package; | |||||
} | |||||
public static JT808Package CreateCustomMsgId2019<TJT808Bodies>(this ushort msgId, string terminalPhoneNo, TJT808Bodies bodies) | |||||
where TJT808Bodies : JT808Bodies | |||||
{ | |||||
JT808Package jT808Package = new JT808Package | |||||
{ | |||||
Header = new JT808Header | |||||
{ | |||||
MsgId = msgId, | |||||
TerminalPhoneNo = terminalPhoneNo | |||||
}, | |||||
Bodies = bodies | |||||
}; | |||||
jT808Package.Header.MessageBodyProperty.VersionFlag = true; | |||||
return jT808Package; | |||||
} | |||||
public static JT808Package CreateCustomMsgId2019(this ushort msgId, string terminalPhoneNo) | |||||
{ | |||||
JT808Package jT808Package = new JT808Package | |||||
{ | |||||
Header = new JT808Header | |||||
{ | |||||
MsgId = msgId, | |||||
TerminalPhoneNo = terminalPhoneNo | |||||
} | |||||
}; | |||||
jT808Package.Header.MessageBodyProperty.VersionFlag = true; | |||||
return jT808Package; | |||||
} | |||||
} | } | ||||
} | } |
@@ -46,6 +46,24 @@ namespace JT808.Protocol.Extensions | |||||
{ | { | ||||
return Create<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); | return Create<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); | ||||
} | } | ||||
/// <summary> | |||||
/// <#= jT808MsgIdDescriptionAttribute.Code #> - <#= jT808MsgIdDescriptionAttribute.Name #> | |||||
/// auto-generated 2019 version | |||||
/// </summary> | |||||
public static JT808Package Create_<#= jT808MsgIdDescriptionAttribute.Name #>_2019(this JT808MsgId msgId, string terminalPhoneNo,<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName #> bodies) | |||||
{ | |||||
return Create2019<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); | |||||
} | |||||
/// <summary> | |||||
/// <#= jT808MsgIdDescriptionAttribute.Code #> - <#= jT808MsgIdDescriptionAttribute.Name #> | |||||
/// auto-generated 2019 version | |||||
/// </summary> | |||||
public static JT808Package Create2019(this JT808MsgId msgId, string terminalPhoneNo,<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName #> bodies) | |||||
{ | |||||
return Create2019<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); | |||||
} | |||||
<# | <# | ||||
} | } | ||||
#> | #> | ||||
@@ -25,10 +25,8 @@ namespace JT808.Protocol.Interfaces | |||||
JT808_0X8103_Factory = new JT808_0x8103_Factory(); | JT808_0X8103_Factory = new JT808_0x8103_Factory(); | ||||
TerminalPhoneNoLength = 12; | TerminalPhoneNoLength = 12; | ||||
Trim = true; | Trim = true; | ||||
Version = JT808Version.JTT2013; | |||||
} | } | ||||
public abstract string ConfigId { get; protected set; } | public abstract string ConfigId { get; protected set; } | ||||
public virtual JT808Version Version { get; protected set; } | |||||
public virtual IJT808MsgSNDistributed MsgSNDistributed { get; set; } | public virtual IJT808MsgSNDistributed MsgSNDistributed { get; set; } | ||||
public virtual IJT808Compress Compress { get; set; } | public virtual IJT808Compress Compress { get; set; } | ||||
public virtual IJT808SplitPackageStrategy SplitPackageStrategy { get; set; } | public virtual IJT808SplitPackageStrategy SplitPackageStrategy { get; set; } | ||||
@@ -10,8 +10,6 @@ namespace JT808.Protocol | |||||
{ | { | ||||
public interface IJT808Config | public interface IJT808Config | ||||
{ | { | ||||
[Obsolete("目前没用")] | |||||
JT808Version Version { get;} | |||||
string ConfigId { get; } | string ConfigId { get; } | ||||
/// <summary> | /// <summary> | ||||
/// 消息流水号 | /// 消息流水号 | ||||
@@ -11,11 +11,9 @@ namespace JT808.Protocol.Internal | |||||
class DefaultGlobalConfig : GlobalConfigBase | class DefaultGlobalConfig : GlobalConfigBase | ||||
{ | { | ||||
public override string ConfigId { get; protected set; } | public override string ConfigId { get; protected set; } | ||||
public override JT808Version Version { get ; protected set; } | |||||
public DefaultGlobalConfig(string configId= "Default", JT808Version jT808Version= JT808Version.JTT2013) | |||||
public DefaultGlobalConfig(string configId= "Default") | |||||
{ | { | ||||
ConfigId = configId; | ConfigId = configId; | ||||
Version = jT808Version; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -16,7 +16,7 @@ namespace JT808.Protocol | |||||
/// <summary> | /// <summary> | ||||
/// 消息体属性 | /// 消息体属性 | ||||
/// </summary> | /// </summary> | ||||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } | |||||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } = new JT808HeaderMessageBodyProperty(); | |||||
/// <summary> | /// <summary> | ||||
/// 协议版本号(2019版本) | /// 协议版本号(2019版本) | ||||
/// </summary> | /// </summary> | ||||
@@ -5,7 +5,7 @@ using System; | |||||
namespace JT808.Protocol | namespace JT808.Protocol | ||||
{ | { | ||||
public struct JT808HeaderMessageBodyProperty | |||||
public class JT808HeaderMessageBodyProperty | |||||
{ | { | ||||
public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, bool versionFlag= false, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None) | public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, bool versionFlag= false, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None) | ||||
{ | { | ||||
@@ -30,7 +30,7 @@ namespace JT808.Protocol | |||||
DataLength = 0; | DataLength = 0; | ||||
VersionFlag = versionFlag; | VersionFlag = versionFlag; | ||||
} | } | ||||
public JT808HeaderMessageBodyProperty(){} | |||||
public JT808HeaderMessageBodyProperty(ushort value) | public JT808HeaderMessageBodyProperty(ushort value) | ||||
{ | { | ||||
VersionFlag = (value >> 14 & 0x01) == 1; | VersionFlag = (value >> 14 & 0x01) == 1; | ||||
@@ -52,27 +52,26 @@ namespace JT808.Protocol | |||||
/// <summary> | /// <summary> | ||||
/// 版本标识(默认为1=true) | /// 版本标识(默认为1=true) | ||||
/// </summary> | /// </summary> | ||||
public bool VersionFlag { get; set; } | |||||
public bool VersionFlag { get; set; } = false; | |||||
/// <summary> | /// <summary> | ||||
/// 是否分包 | /// 是否分包 | ||||
/// true-1 表示消息体为长消息,进行分包发送处理 | /// true-1 表示消息体为长消息,进行分包发送处理 | ||||
/// false-0 消息头中无消息包封装项字段。 | /// false-0 消息头中无消息包封装项字段。 | ||||
/// </summary> | /// </summary> | ||||
public bool IsPackage { get; set; } | |||||
public bool IsPackage { get; set; } = false; | |||||
/// <summary> | /// <summary> | ||||
/// 加密标识,0为不加密 | /// 加密标识,0为不加密 | ||||
/// 当此三位都为 0,表示消息体不加密; | /// 当此三位都为 0,表示消息体不加密; | ||||
/// 当第 10 位为 1,表示消息体经过 RSA 算法加密; | /// 当第 10 位为 1,表示消息体经过 RSA 算法加密; | ||||
/// todo:没有涉及到加密先不考虑 | /// todo:没有涉及到加密先不考虑 | ||||
/// </summary> | /// </summary> | ||||
public JT808EncryptMethod Encrypt { get; set; } | |||||
public JT808EncryptMethod Encrypt { get; set; } = JT808EncryptMethod.None; | |||||
/// <summary> | /// <summary> | ||||
/// 消息体长度 | /// 消息体长度 | ||||
/// </summary> | /// </summary> | ||||
public int DataLength { get; set; } | |||||
public int DataLength { get; set; } = 0; | |||||
public ushort Wrap() | public ushort Wrap() | ||||
{ | { | ||||
// 1.是否分包 | // 1.是否分包 | ||||
int tmpIsPacke = 0; | int tmpIsPacke = 0; | ||||
if (IsPackage) | if (IsPackage) | ||||
@@ -100,7 +99,7 @@ namespace JT808.Protocol | |||||
// 判断有无数据体长度 | // 判断有无数据体长度 | ||||
DataLength = 0; | DataLength = 0; | ||||
} | } | ||||
// 3.是否分包 | |||||
// 3.版本标识 | |||||
int versionFlag = 0; | int versionFlag = 0; | ||||
if (VersionFlag) | if (VersionFlag) | ||||
{ | { | ||||
@@ -108,44 +107,5 @@ namespace JT808.Protocol | |||||
} | } | ||||
return (ushort)(versionFlag|tmpIsPacke | tmpEncrypt | DataLength); | return (ushort)(versionFlag|tmpIsPacke | tmpEncrypt | DataLength); | ||||
} | } | ||||
public ushort Wrap(int dataLength) | |||||
{ | |||||
// 1.是否分包 | |||||
int tmpIsPacke = 0; | |||||
if (IsPackage) | |||||
{ | |||||
tmpIsPacke = 1 << 13; | |||||
} | |||||
// 2.是否加密 | |||||
int tmpEncrypt; | |||||
// 2.3.数据加密方式 | |||||
switch (Encrypt) | |||||
{ | |||||
case JT808EncryptMethod.None: | |||||
tmpEncrypt = 0; | |||||
break; | |||||
case JT808EncryptMethod.RSA: | |||||
tmpEncrypt = 1 << 10; | |||||
break; | |||||
default: | |||||
tmpEncrypt = 0; | |||||
break; | |||||
} | |||||
// 2.4.数据长度 | |||||
DataLength = dataLength; | |||||
if (dataLength <= 0) | |||||
{ | |||||
// 判断有无数据体长度 | |||||
dataLength = 0; | |||||
} | |||||
// 3.是否分包 | |||||
int versionFlag = 0; | |||||
if (VersionFlag) | |||||
{ | |||||
versionFlag = 1 << 14; | |||||
} | |||||
return (ushort)(versionFlag | tmpIsPacke | tmpEncrypt | dataLength); | |||||
} | |||||
} | } | ||||
} | } |
@@ -10,7 +10,7 @@ namespace JT808.Protocol | |||||
/// <summary> | /// <summary> | ||||
/// JT808头部数据包 | /// JT808头部数据包 | ||||
/// </summary> | /// </summary> | ||||
public class JT808HeaderPackage: IJT808MessagePackFormatter<JT808HeaderPackage> | |||||
public ref struct JT808HeaderPackage | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// 起始符 | /// 起始符 | ||||
@@ -23,7 +23,7 @@ namespace JT808.Protocol | |||||
/// <summary> | /// <summary> | ||||
/// 数据体 | /// 数据体 | ||||
/// </summary> | /// </summary> | ||||
public byte[] Bodies { get; set; } | |||||
public ReadOnlySpan<byte> Bodies { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// 校验码 | /// 校验码 | ||||
/// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 | /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 | ||||
@@ -33,7 +33,6 @@ namespace JT808.Protocol | |||||
/// 终止符 | /// 终止符 | ||||
/// </summary> | /// </summary> | ||||
public byte End { get; set; } | public byte End { get; set; } | ||||
public JT808Version Version | public JT808Version Version | ||||
{ | { | ||||
get { | get { | ||||
@@ -61,8 +60,12 @@ namespace JT808.Protocol | |||||
} | } | ||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 原数据 | |||||
/// </summary> | |||||
public ReadOnlySpan<byte> OriginalData { get; set; } | |||||
public JT808HeaderPackage Deserialize(ref JT808MessagePackReader reader, IJT808Config config) | |||||
public JT808HeaderPackage(ref JT808MessagePackReader reader, IJT808Config config) | |||||
{ | { | ||||
// 1. 验证校验和 | // 1. 验证校验和 | ||||
if (!config.SkipCRCCode) | if (!config.SkipCRCCode) | ||||
@@ -72,60 +75,58 @@ namespace JT808.Protocol | |||||
throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}"); | throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}"); | ||||
} | } | ||||
} | } | ||||
JT808HeaderPackage jT808Package = new JT808HeaderPackage(); | |||||
// ---------------开始解包-------------- | // ---------------开始解包-------------- | ||||
// 2.读取起始位置 | // 2.读取起始位置 | ||||
jT808Package.Begin = reader.ReadStart(); | |||||
this.Begin = reader.ReadStart(); | |||||
// 3.读取头部信息 | // 3.读取头部信息 | ||||
jT808Package.Header = new JT808Header(); | |||||
this.Header = new JT808Header(); | |||||
// 3.1.读取消息Id | // 3.1.读取消息Id | ||||
jT808Package.Header.MsgId = reader.ReadUInt16(); | |||||
this.Header.MsgId = reader.ReadUInt16(); | |||||
// 3.2.读取消息体属性 | // 3.2.读取消息体属性 | ||||
ushort messageBodyPropertyValue = reader.ReadUInt16(); | ushort messageBodyPropertyValue = reader.ReadUInt16(); | ||||
// 3.2.1.解包消息体属性 | // 3.2.1.解包消息体属性 | ||||
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(messageBodyPropertyValue); | |||||
if (jT808Package.Header.MessageBodyProperty.VersionFlag) | |||||
this.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(messageBodyPropertyValue); | |||||
if (this.Header.MessageBodyProperty.VersionFlag) | |||||
{ | { | ||||
//2019版本 | //2019版本 | ||||
// 3.3.读取协议版本号 | // 3.3.读取协议版本号 | ||||
jT808Package.Header.ProtocolVersion = reader.ReadByte(); | |||||
this.Header.ProtocolVersion = reader.ReadByte(); | |||||
// 3.4.读取终端手机号 | // 3.4.读取终端手机号 | ||||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim); | |||||
this.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim); | |||||
reader.Version = JT808Version.JTT2019; | reader.Version = JT808Version.JTT2019; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
//2013版本 | //2013版本 | ||||
// 3.3.读取终端手机号 | // 3.3.读取终端手机号 | ||||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim); | |||||
this.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim); | |||||
} | } | ||||
// 3.4.读取消息流水号 | // 3.4.读取消息流水号 | ||||
jT808Package.Header.MsgNum = reader.ReadUInt16(); | |||||
this.Header.MsgNum = reader.ReadUInt16(); | |||||
// 3.5.判断有无分包 | // 3.5.判断有无分包 | ||||
if (jT808Package.Header.MessageBodyProperty.IsPackage) | |||||
if (this.Header.MessageBodyProperty.IsPackage) | |||||
{ | { | ||||
//3.5.1.读取消息包总数 | //3.5.1.读取消息包总数 | ||||
jT808Package.Header.PackgeCount = reader.ReadUInt16(); | |||||
this.Header.PackgeCount = reader.ReadUInt16(); | |||||
//3.5.2.读取消息包序号 | //3.5.2.读取消息包序号 | ||||
jT808Package.Header.PackageIndex = reader.ReadUInt16(); | |||||
this.Header.PackageIndex = reader.ReadUInt16(); | |||||
} | } | ||||
// 4.处理数据体 | // 4.处理数据体 | ||||
// 4.1.判断有无数据体 | // 4.1.判断有无数据体 | ||||
if (jT808Package.Header.MessageBodyProperty.DataLength > 0) | |||||
if (this.Header.MessageBodyProperty.DataLength > 0) | |||||
{ | { | ||||
jT808Package.Bodies = reader.ReadContent().ToArray(); | |||||
this.Bodies = reader.ReadContent(); | |||||
} | |||||
else | |||||
{ | |||||
this.Bodies = ReadOnlySpan<byte>.Empty; | |||||
} | } | ||||
// 5.读取校验码 | // 5.读取校验码 | ||||
jT808Package.CheckCode = reader.ReadByte(); | |||||
this.CheckCode = reader.ReadByte(); | |||||
// 6.读取终止位置 | // 6.读取终止位置 | ||||
jT808Package.End = reader.ReadEnd(); | |||||
this.End = reader.ReadEnd(); | |||||
// ---------------解包完成-------------- | // ---------------解包完成-------------- | ||||
return jT808Package; | |||||
} | |||||
public void Serialize(ref JT808MessagePackWriter writer, JT808HeaderPackage value, IJT808Config config) | |||||
{ | |||||
throw new NotImplementedException("只适用反序列化"); | |||||
this.OriginalData = reader.SrcBuffer; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -228,7 +228,8 @@ namespace JT808.Protocol | |||||
} | } | ||||
// 3.1.处理数据体长度 | // 3.1.处理数据体长度 | ||||
// 2.2.回写消息体属性 | // 2.2.回写消息体属性 | ||||
writer.WriteUInt16Return(value.Header.MessageBodyProperty.Wrap((writer.GetCurrentPosition() - headerLength)), msgBodiesPropertyPosition); | |||||
value.Header.MessageBodyProperty.DataLength = (writer.GetCurrentPosition() - headerLength); | |||||
writer.WriteUInt16Return(value.Header.MessageBodyProperty.Wrap(), msgBodiesPropertyPosition); | |||||
// 4.校验码 | // 4.校验码 | ||||
writer.WriteXor(); | writer.WriteXor(); | ||||
// 5.终止符 | // 5.终止符 | ||||
@@ -10,8 +10,6 @@ namespace JT808.Protocol | |||||
{ | { | ||||
public class JT808Serializer | public class JT808Serializer | ||||
{ | { | ||||
private readonly static JT808HeaderPackage jT808HeaderPackage = new JT808HeaderPackage(); | |||||
private readonly static JT808Package jT808Package = new JT808Package(); | private readonly static JT808Package jT808Package = new JT808Package(); | ||||
public JT808Serializer(IJT808Config jT808Config) | public JT808Serializer(IJT808Config jT808Config) | ||||
@@ -140,7 +138,7 @@ namespace JT808.Protocol | |||||
{ | { | ||||
JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version); | JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version); | ||||
jT808MessagePackReader.Decode(buffer); | jT808MessagePackReader.Decode(buffer); | ||||
return jT808HeaderPackage.Deserialize(ref jT808MessagePackReader,jT808Config); | |||||
return new JT808HeaderPackage(ref jT808MessagePackReader,jT808Config); | |||||
} | } | ||||
finally | finally | ||||
{ | { | ||||
@@ -1,4 +1,5 @@ | |||||
using JT808.Protocol.Formatters; | using JT808.Protocol.Formatters; | ||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.MessagePack; | using JT808.Protocol.MessagePack; | ||||
using JT808.Protocol.Metadata; | using JT808.Protocol.Metadata; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
@@ -9,7 +10,7 @@ namespace JT808.Protocol.MessageBody | |||||
/// 存储多媒体数据检索应答 | /// 存储多媒体数据检索应答 | ||||
/// 0x0802 | /// 0x0802 | ||||
/// </summary> | /// </summary> | ||||
public class JT808_0x0802 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x0802> | |||||
public class JT808_0x0802 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x0802>, IJT808_2019_Version | |||||
{ | { | ||||
public override ushort MsgId { get; } = 0x0802; | public override ushort MsgId { get; } = 0x0802; | ||||
/// <summary> | /// <summary> | ||||
@@ -1,6 +1,7 @@ | |||||
using JT808.Protocol.Attributes; | using JT808.Protocol.Attributes; | ||||
using JT808.Protocol.Extensions; | using JT808.Protocol.Extensions; | ||||
using JT808.Protocol.Formatters; | using JT808.Protocol.Formatters; | ||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.MessagePack; | using JT808.Protocol.MessagePack; | ||||
namespace JT808.Protocol.MessageBody | namespace JT808.Protocol.MessageBody | ||||
@@ -8,7 +9,7 @@ namespace JT808.Protocol.MessageBody | |||||
/// <summary> | /// <summary> | ||||
/// 数据上行透传 | /// 数据上行透传 | ||||
/// </summary> | /// </summary> | ||||
public class JT808_0x0900 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x0900> | |||||
public class JT808_0x0900 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x0900>, IJT808_2019_Version | |||||
{ | { | ||||
public override ushort MsgId { get; } = 0x0900; | public override ushort MsgId { get; } = 0x0900; | ||||
/// <summary> | /// <summary> | ||||
@@ -1,4 +1,5 @@ | |||||
using JT808.Protocol.Formatters; | using JT808.Protocol.Formatters; | ||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.MessagePack; | using JT808.Protocol.MessagePack; | ||||
namespace JT808.Protocol.MessageBody | namespace JT808.Protocol.MessageBody | ||||
@@ -6,7 +7,7 @@ namespace JT808.Protocol.MessageBody | |||||
/// <summary> | /// <summary> | ||||
/// 单条存储多媒体数据检索上传命令 | /// 单条存储多媒体数据检索上传命令 | ||||
/// </summary> | /// </summary> | ||||
public class JT808_0x8805 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x8805> | |||||
public class JT808_0x8805 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x8805>,IJT808_2019_Version | |||||
{ | { | ||||
public override ushort MsgId { get; } = 0x8805; | public override ushort MsgId { get; } = 0x8805; | ||||
/// <summary> | /// <summary> | ||||
@@ -1,5 +1,6 @@ | |||||
using JT808.Protocol.Extensions; | using JT808.Protocol.Extensions; | ||||
using JT808.Protocol.Formatters; | using JT808.Protocol.Formatters; | ||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.MessagePack; | using JT808.Protocol.MessagePack; | ||||
namespace JT808.Protocol.MessageBody | namespace JT808.Protocol.MessageBody | ||||
@@ -7,7 +8,7 @@ namespace JT808.Protocol.MessageBody | |||||
/// <summary> | /// <summary> | ||||
/// 数据下行透传 | /// 数据下行透传 | ||||
/// </summary> | /// </summary> | ||||
public class JT808_0x8900 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x8900> | |||||
public class JT808_0x8900 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x8900>, IJT808_2019_Version | |||||
{ | { | ||||
public override ushort MsgId { get; } = 0x8900; | public override ushort MsgId { get; } = 0x8900; | ||||
/// <summary> | /// <summary> | ||||