2.修改消息体属性为引用类型 3.增加2019版本协议消息Demo7 4.将2019版本涉及的消息打上标记 5.修改文档内容tags/v2.2.0
@@ -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) | |||
### 举个栗子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安装 | |||
| Package Name | Version | Downloads | | |||
@@ -367,9 +379,9 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0 | |||
| 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | | |||
| 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | | |||
| 59 | 0x8804 | √ | √ | 录音开始命令 | | |||
| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 | | |||
| 61 | 0x8900 | √ | √ | 数据下行透传 | | |||
| 62 | 0x0900 | √ | √ | 数据上行透传 | | |||
| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 |修改| | |||
| 61 | 0x8900 | √ | √ | 数据下行透传 |修改| | |||
| 62 | 0x0900 | √ | √ | 数据上行透传 |修改| | |||
| 63 | 0x0901 | √ | √ | 数据压缩上报 | | |||
| 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | | |||
| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | | |||
@@ -381,3 +393,5 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0 | |||
| 71 | 0x8204 | √ | √ | 链路检测 |新增| | |||
| 72 | 0x8608 | √ | √ | 查询区域或线路数据 |新增| | |||
| 73 | 0x0608 | √ | √ | 查询区域或线路数据应答 |新增| | |||
| 74 | 0xE000~0xEFFF | 保留 | 保留 | 厂商自定义上行消息 |新增| | |||
| 75 | 0xF000~0xFFFF | 保留 | 保留 | 厂商自定义下行消息 |新增| |
@@ -40,7 +40,8 @@ namespace JT808.Protocol.Test | |||
{ | |||
MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | |||
MsgNum = 1203, | |||
TerminalPhoneNo = "012345678900" | |||
TerminalPhoneNo = "012345678900", | |||
MessageBodyProperty=new JT808HeaderMessageBodyProperty() | |||
}, | |||
Bodies = new JT808_0x0001 | |||
{ | |||
@@ -61,7 +62,7 @@ namespace JT808.Protocol.Test | |||
{ | |||
if (i % 2 == 0) | |||
{ | |||
defaultGlobalConfigs.Add(new DefaultGlobalConfig(i.ToString(), JT808Version.JTT2019)); | |||
defaultGlobalConfigs.Add(new DefaultGlobalConfig(i.ToString())); | |||
} | |||
else | |||
{ | |||
@@ -17,7 +17,7 @@ namespace JT808.Protocol.Test.MessageBody | |||
{ | |||
MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), | |||
MsgNum = 1203, | |||
TerminalPhoneNo = "012345678900" | |||
TerminalPhoneNo = "012345678900", | |||
}, | |||
Bodies = new JT808_0x0001 | |||
{ | |||
@@ -88,7 +88,7 @@ namespace JT808.Protocol.Test.MessageBody | |||
public void Package3() | |||
{ | |||
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.ReplyMsgNum = 12456; | |||
jT808_0X0805.Result = 1; | |||
jT808_0X0805.Result = 0; | |||
jT808_0X0805.MultimediaIds = new List<uint>() | |||
{ | |||
12306, | |||
12580 | |||
}; | |||
string hex = JT808Serializer.Serialize(jT808_0X0805).ToHexString(); | |||
Assert.Equal("30A80100020000301200003124", hex); | |||
Assert.Equal("30A80000020000301200003124", hex); | |||
} | |||
[Fact] | |||
public void Test2() | |||
{ | |||
byte[] bytes = "30A80100020000301200003124".ToHexBytes(); | |||
byte[] bytes = "30A80000020000301200003124".ToHexBytes(); | |||
JT808_0x0805 jT808_0X0805 = JT808Serializer.Deserialize<JT808_0x0805>(bytes); | |||
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(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 System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
using JT808.Protocol.MessageBody; | |||
namespace JT808.Protocol.Test.Simples | |||
{ | |||
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] | |||
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))] | |||
[JT808MsgIdDescription("0x0A00", "终端RSA公钥")] | |||
终端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 | |||
{ | |||
MsgId = (ushort)msgId, | |||
TerminalPhoneNo = terminalPhoneNo | |||
TerminalPhoneNo = terminalPhoneNo, | |||
}, | |||
Bodies = bodies | |||
}; | |||
@@ -26,7 +26,7 @@ namespace JT808.Protocol.Extensions | |||
Header = new JT808Header | |||
{ | |||
MsgId = (ushort)msgId, | |||
TerminalPhoneNo = terminalPhoneNo | |||
TerminalPhoneNo = terminalPhoneNo, | |||
} | |||
}; | |||
return jT808Package; | |||
@@ -59,5 +59,65 @@ namespace JT808.Protocol.Extensions | |||
}; | |||
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); | |||
} | |||
/// <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(); | |||
TerminalPhoneNoLength = 12; | |||
Trim = true; | |||
Version = JT808Version.JTT2013; | |||
} | |||
public abstract string ConfigId { get; protected set; } | |||
public virtual JT808Version Version { get; protected set; } | |||
public virtual IJT808MsgSNDistributed MsgSNDistributed { get; set; } | |||
public virtual IJT808Compress Compress { get; set; } | |||
public virtual IJT808SplitPackageStrategy SplitPackageStrategy { get; set; } | |||
@@ -10,8 +10,6 @@ namespace JT808.Protocol | |||
{ | |||
public interface IJT808Config | |||
{ | |||
[Obsolete("目前没用")] | |||
JT808Version Version { get;} | |||
string ConfigId { get; } | |||
/// <summary> | |||
/// 消息流水号 | |||
@@ -11,11 +11,9 @@ namespace JT808.Protocol.Internal | |||
class DefaultGlobalConfig : GlobalConfigBase | |||
{ | |||
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; | |||
Version = jT808Version; | |||
} | |||
} | |||
} |
@@ -16,7 +16,7 @@ namespace JT808.Protocol | |||
/// <summary> | |||
/// 消息体属性 | |||
/// </summary> | |||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } | |||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } = new JT808HeaderMessageBodyProperty(); | |||
/// <summary> | |||
/// 协议版本号(2019版本) | |||
/// </summary> | |||
@@ -5,7 +5,7 @@ using System; | |||
namespace JT808.Protocol | |||
{ | |||
public struct JT808HeaderMessageBodyProperty | |||
public class JT808HeaderMessageBodyProperty | |||
{ | |||
public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, bool versionFlag= false, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None) | |||
{ | |||
@@ -30,7 +30,7 @@ namespace JT808.Protocol | |||
DataLength = 0; | |||
VersionFlag = versionFlag; | |||
} | |||
public JT808HeaderMessageBodyProperty(){} | |||
public JT808HeaderMessageBodyProperty(ushort value) | |||
{ | |||
VersionFlag = (value >> 14 & 0x01) == 1; | |||
@@ -52,27 +52,26 @@ namespace JT808.Protocol | |||
/// <summary> | |||
/// 版本标识(默认为1=true) | |||
/// </summary> | |||
public bool VersionFlag { get; set; } | |||
public bool VersionFlag { get; set; } = false; | |||
/// <summary> | |||
/// 是否分包 | |||
/// true-1 表示消息体为长消息,进行分包发送处理 | |||
/// false-0 消息头中无消息包封装项字段。 | |||
/// </summary> | |||
public bool IsPackage { get; set; } | |||
public bool IsPackage { get; set; } = false; | |||
/// <summary> | |||
/// 加密标识,0为不加密 | |||
/// 当此三位都为 0,表示消息体不加密; | |||
/// 当第 10 位为 1,表示消息体经过 RSA 算法加密; | |||
/// todo:没有涉及到加密先不考虑 | |||
/// </summary> | |||
public JT808EncryptMethod Encrypt { get; set; } | |||
public JT808EncryptMethod Encrypt { get; set; } = JT808EncryptMethod.None; | |||
/// <summary> | |||
/// 消息体长度 | |||
/// </summary> | |||
public int DataLength { get; set; } | |||
public int DataLength { get; set; } = 0; | |||
public ushort Wrap() | |||
{ | |||
// 1.是否分包 | |||
int tmpIsPacke = 0; | |||
if (IsPackage) | |||
@@ -100,7 +99,7 @@ namespace JT808.Protocol | |||
// 判断有无数据体长度 | |||
DataLength = 0; | |||
} | |||
// 3.是否分包 | |||
// 3.版本标识 | |||
int versionFlag = 0; | |||
if (VersionFlag) | |||
{ | |||
@@ -108,44 +107,5 @@ namespace JT808.Protocol | |||
} | |||
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> | |||
/// JT808头部数据包 | |||
/// </summary> | |||
public class JT808HeaderPackage: IJT808MessagePackFormatter<JT808HeaderPackage> | |||
public ref struct JT808HeaderPackage | |||
{ | |||
/// <summary> | |||
/// 起始符 | |||
@@ -23,7 +23,7 @@ namespace JT808.Protocol | |||
/// <summary> | |||
/// 数据体 | |||
/// </summary> | |||
public byte[] Bodies { get; set; } | |||
public ReadOnlySpan<byte> Bodies { get; set; } | |||
/// <summary> | |||
/// 校验码 | |||
/// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 | |||
@@ -33,7 +33,6 @@ namespace JT808.Protocol | |||
/// 终止符 | |||
/// </summary> | |||
public byte End { get; set; } | |||
public JT808Version Version | |||
{ | |||
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. 验证校验和 | |||
if (!config.SkipCRCCode) | |||
@@ -72,60 +75,58 @@ namespace JT808.Protocol | |||
throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}"); | |||
} | |||
} | |||
JT808HeaderPackage jT808Package = new JT808HeaderPackage(); | |||
// ---------------开始解包-------------- | |||
// 2.读取起始位置 | |||
jT808Package.Begin = reader.ReadStart(); | |||
this.Begin = reader.ReadStart(); | |||
// 3.读取头部信息 | |||
jT808Package.Header = new JT808Header(); | |||
this.Header = new JT808Header(); | |||
// 3.1.读取消息Id | |||
jT808Package.Header.MsgId = reader.ReadUInt16(); | |||
this.Header.MsgId = reader.ReadUInt16(); | |||
// 3.2.读取消息体属性 | |||
ushort messageBodyPropertyValue = reader.ReadUInt16(); | |||
// 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版本 | |||
// 3.3.读取协议版本号 | |||
jT808Package.Header.ProtocolVersion = reader.ReadByte(); | |||
this.Header.ProtocolVersion = reader.ReadByte(); | |||
// 3.4.读取终端手机号 | |||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim); | |||
this.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim); | |||
reader.Version = JT808Version.JTT2019; | |||
} | |||
else | |||
{ | |||
//2013版本 | |||
// 3.3.读取终端手机号 | |||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim); | |||
this.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim); | |||
} | |||
// 3.4.读取消息流水号 | |||
jT808Package.Header.MsgNum = reader.ReadUInt16(); | |||
this.Header.MsgNum = reader.ReadUInt16(); | |||
// 3.5.判断有无分包 | |||
if (jT808Package.Header.MessageBodyProperty.IsPackage) | |||
if (this.Header.MessageBodyProperty.IsPackage) | |||
{ | |||
//3.5.1.读取消息包总数 | |||
jT808Package.Header.PackgeCount = reader.ReadUInt16(); | |||
this.Header.PackgeCount = reader.ReadUInt16(); | |||
//3.5.2.读取消息包序号 | |||
jT808Package.Header.PackageIndex = reader.ReadUInt16(); | |||
this.Header.PackageIndex = reader.ReadUInt16(); | |||
} | |||
// 4.处理数据体 | |||
// 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.读取校验码 | |||
jT808Package.CheckCode = reader.ReadByte(); | |||
this.CheckCode = reader.ReadByte(); | |||
// 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.处理数据体长度 | |||
// 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.校验码 | |||
writer.WriteXor(); | |||
// 5.终止符 | |||
@@ -10,8 +10,6 @@ namespace JT808.Protocol | |||
{ | |||
public class JT808Serializer | |||
{ | |||
private readonly static JT808HeaderPackage jT808HeaderPackage = new JT808HeaderPackage(); | |||
private readonly static JT808Package jT808Package = new JT808Package(); | |||
public JT808Serializer(IJT808Config jT808Config) | |||
@@ -140,7 +138,7 @@ namespace JT808.Protocol | |||
{ | |||
JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version); | |||
jT808MessagePackReader.Decode(buffer); | |||
return jT808HeaderPackage.Deserialize(ref jT808MessagePackReader,jT808Config); | |||
return new JT808HeaderPackage(ref jT808MessagePackReader,jT808Config); | |||
} | |||
finally | |||
{ | |||
@@ -1,4 +1,5 @@ | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.MessagePack; | |||
using JT808.Protocol.Metadata; | |||
using System.Collections.Generic; | |||
@@ -9,7 +10,7 @@ namespace JT808.Protocol.MessageBody | |||
/// 存储多媒体数据检索应答 | |||
/// 0x0802 | |||
/// </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; | |||
/// <summary> | |||
@@ -1,6 +1,7 @@ | |||
using JT808.Protocol.Attributes; | |||
using JT808.Protocol.Extensions; | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.MessagePack; | |||
namespace JT808.Protocol.MessageBody | |||
@@ -8,7 +9,7 @@ namespace JT808.Protocol.MessageBody | |||
/// <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; | |||
/// <summary> | |||
@@ -1,4 +1,5 @@ | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.MessagePack; | |||
namespace JT808.Protocol.MessageBody | |||
@@ -6,7 +7,7 @@ namespace JT808.Protocol.MessageBody | |||
/// <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; | |||
/// <summary> | |||
@@ -1,5 +1,6 @@ | |||
using JT808.Protocol.Extensions; | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.MessagePack; | |||
namespace JT808.Protocol.MessageBody | |||
@@ -7,7 +8,7 @@ namespace JT808.Protocol.MessageBody | |||
/// <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; | |||
/// <summary> | |||