diff --git a/README.md b/README.md index 77c6509..5516b31 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ ### 数据包[JT808Package] -| 头标识 | 数据头 | 数据体 | 校验码 | 尾标识 | +| 头标识 | 数据头 | 数据体/分包数据体 | 校验码 | 尾标识 | | :----: | :---------: | :---------: | :----------: | :----: | -| Begin | JT808Header | JT808Bodies |CheckCode | End | +| Begin | JT808Header | JT808Bodies/JT808SubDataBodies |CheckCode | End | | 7E | - | - | - | 7E | ### 数据头[JT808Header] @@ -244,7 +244,9 @@ JT808Serializer DT2JT808Serializer = new JT808Serializer(DT2JT808Config); 1. 第一包数据上来采用平常的方式去解析数据; -2. 当N包数据上来,采用统一分包消息体去接收数据,最后在合并成一条。 +2. 当第二包上来跟第一包的分包数据体(SubDataBodies)进行合并 + +3. 当N包数据上来,延续步骤2的方式。 > 普及知识点:一般行业分包是按256的整数倍,太多不行,太少也不行,必须刚刚好。 diff --git a/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj index 46d22f7..f06d108 100644 --- a/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj +++ b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj @@ -1,7 +1,7 @@  - net5 + net5.0 false 9.0 diff --git a/src/JT808.Protocol.Test/JT808HeaderPackageTest.cs b/src/JT808.Protocol.Test/JT808HeaderPackageTest.cs new file mode 100644 index 0000000..6a7ba34 --- /dev/null +++ b/src/JT808.Protocol.Test/JT808HeaderPackageTest.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace JT808.Protocol.Test +{ + public class JT808HeaderPackageTest + { + JT808Serializer JT808Serializer = new JT808Serializer(); + + [Fact] + public void Test1() + { + var data1 = JT808Serializer.HeaderDeserialize("7E120523A204066657506200EB00020001015A00000023012012191042052012191050190000000000000000000101064446D10120121910221720121910420500000000000000000001010F1FE8EB0120121910023420121910221700000000000000000001010F182D5C0120121909471120121910015500000000000000000001010B38F2430120121909274020121909471100000000000000000001010F056DB40120121909080920121909274000000000000000000001010F0724380120121908483820121909080900000000000000000001010F0530AB0120121908290720121908483800000000000000000001010F05896C0120121908093720121908290700000000000000000001010F02CD3B0120121907500520121908093700000000000000000001010F056FEF0120121907303420121907500500000000000000000001010F043C3401201219072541201219073034000000000000000000010103C26C5F0120121907061120121907254100000000000000000001010F03F0C10120121906464220121907061100000000000000000001010F02F6330120121906271220121906464200000000000000000001010F02E43B0120121906074220121906271200000000000000000001010F033D670120121905481120121906074200000000000000000001010F088BF20120121905284120121905481100000000000000000001010F03F9FE0120121905091020121905284100000000000000000001010F05B1040120121904494020121905091000000000000000000001010F02B3540120121904301020121904494000000000000000000001010F0417B00120121904103920121904301000000000000000000001010F0538970120121903510820121904103900000000000000000001010F054E9E0120121903313820121903510800000000000000000001010F016ECB0120121903120820121903313800000000000000000001010F0333C00120121902523820121903120700000000000000000001010F029D230120121902330720121902523700000000000000000001010F0354E40120121902133720121902330700000000000000000001010F03303D0120121901540720121902133700000000000000000001010F04981E0120121901343720121901540700000000000000000001010F02AD940120121901150820121901343700000000000000000001010EFFD7CF0120121900553720121901150800000000000000000001010F07D9330120121900360720121900553700000000000000000001010F040E740C7E".ToHexBytes()); + var data1_1 = data1.Bodies; + var data2 = JT808Serializer.HeaderDeserialize("7E1205203804066657506200EC000200020120121900163320121900360700000000000000000001010F0CE4CD0120121900002220121900163300000000000000000001010C6F9E7B5D7E".ToHexBytes()); + var data2_1 = data2.Bodies; + Assert.Equal(data1.Bodies.ToArray(), data1_1); + Assert.Equal(data2.Bodies.ToArray(), data2_1); + var realBody = data1.Bodies.ToArray().Concat(data2.Bodies.ToArray()).ToArray(); + } + + [Fact] + public void Test2() + { + var json1 = JT808Serializer.Analyze("7E120523A204066657506200EB00020001015A00000023012012191042052012191050190000000000000000000101064446D10120121910221720121910420500000000000000000001010F1FE8EB0120121910023420121910221700000000000000000001010F182D5C0120121909471120121910015500000000000000000001010B38F2430120121909274020121909471100000000000000000001010F056DB40120121909080920121909274000000000000000000001010F0724380120121908483820121909080900000000000000000001010F0530AB0120121908290720121908483800000000000000000001010F05896C0120121908093720121908290700000000000000000001010F02CD3B0120121907500520121908093700000000000000000001010F056FEF0120121907303420121907500500000000000000000001010F043C3401201219072541201219073034000000000000000000010103C26C5F0120121907061120121907254100000000000000000001010F03F0C10120121906464220121907061100000000000000000001010F02F6330120121906271220121906464200000000000000000001010F02E43B0120121906074220121906271200000000000000000001010F033D670120121905481120121906074200000000000000000001010F088BF20120121905284120121905481100000000000000000001010F03F9FE0120121905091020121905284100000000000000000001010F05B1040120121904494020121905091000000000000000000001010F02B3540120121904301020121904494000000000000000000001010F0417B00120121904103920121904301000000000000000000001010F0538970120121903510820121904103900000000000000000001010F054E9E0120121903313820121903510800000000000000000001010F016ECB0120121903120820121903313800000000000000000001010F0333C00120121902523820121903120700000000000000000001010F029D230120121902330720121902523700000000000000000001010F0354E40120121902133720121902330700000000000000000001010F03303D0120121901540720121902133700000000000000000001010F04981E0120121901343720121901540700000000000000000001010F02AD940120121901150820121901343700000000000000000001010EFFD7CF0120121900553720121901150800000000000000000001010F07D9330120121900360720121900553700000000000000000001010F040E740C7E".ToHexBytes()); + var json2 = JT808Serializer.Analyze("7E1205203804066657506200EC000200020120121900163320121900360700000000000000000001010F0CE4CD0120121900002220121900163300000000000000000001010C6F9E7B5D7E".ToHexBytes()); + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo5.cs b/src/JT808.Protocol.Test/Simples/Demo5.cs index 3e15018..2a2ee54 100644 --- a/src/JT808.Protocol.Test/Simples/Demo5.cs +++ b/src/JT808.Protocol.Test/Simples/Demo5.cs @@ -5,6 +5,8 @@ using System.Reflection; using Xunit; using System.Linq; using JT808.Protocol.Internal; +using System.IO; +using System.Drawing; namespace JT808.Protocol.Test.Simples { @@ -95,28 +97,18 @@ namespace JT808.Protocol.Test.Simples Assert.Equal(10, jT808_0X0801_10.Header.PackageIndex); Assert.Equal(10, jT808_0X0801_10.Header.PackgeCount); - - var jT808_0X0801_body_1 = jT808_0X0801_1.Bodies as JT808_0x0801; - var jT808_0X0801_body_2 = jT808_0X0801_2.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_3 = jT808_0X0801_3.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_4 = jT808_0X0801_4.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_5 = jT808_0X0801_5.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_6 = jT808_0X0801_6.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_7 = jT808_0X0801_7.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_8 = jT808_0X0801_8.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_9 = jT808_0X0801_9.Bodies as JT808SplitPackageBodies; - var jT808_0X0801_body_10 = jT808_0X0801_10.Bodies as JT808SplitPackageBodies; - var imageBytes = jT808_0X0801_body_1.MultimediaDataPackage - .Concat(jT808_0X0801_body_2.Data) - .Concat(jT808_0X0801_body_3.Data) - .Concat(jT808_0X0801_body_4.Data) - .Concat(jT808_0X0801_body_5.Data) - .Concat(jT808_0X0801_body_6.Data) - .Concat(jT808_0X0801_body_7.Data) - .Concat(jT808_0X0801_body_8.Data) - .Concat(jT808_0X0801_body_9.Data) - .Concat(jT808_0X0801_body_10.Data).ToArray(); - //using (MemoryStream ms = new MemoryStream(imageBytes)) + var SplitBodyDataTotal = jT808_0X0801_1.SubDataBodies + .Concat(jT808_0X0801_2.SubDataBodies) + .Concat(jT808_0X0801_3.SubDataBodies) + .Concat(jT808_0X0801_4.SubDataBodies) + .Concat(jT808_0X0801_5.SubDataBodies) + .Concat(jT808_0X0801_6.SubDataBodies) + .Concat(jT808_0X0801_7.SubDataBodies) + .Concat(jT808_0X0801_8.SubDataBodies) + .Concat(jT808_0X0801_9.SubDataBodies) + .Concat(jT808_0X0801_10.SubDataBodies).ToArray(); + JT808_0x0801 jT808_0x0801 = JT808Serializer.Deserialize(SplitBodyDataTotal); + //using (MemoryStream ms = new MemoryStream(jT808_0x0801.MultimediaDataPackage)) //{ // Image image = Image.FromStream(ms); // image.Save("test.jpeg"); diff --git a/src/JT808.Protocol/JT808.Protocol.csproj b/src/JT808.Protocol/JT808.Protocol.csproj index fef3271..1fa9577 100644 --- a/src/JT808.Protocol/JT808.Protocol.csproj +++ b/src/JT808.Protocol/JT808.Protocol.csproj @@ -17,10 +17,14 @@ false 2.3.2 LICENSE - 5.0 + latest true true + + false + true + diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 0527e63..1ae4886 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -3408,6 +3408,11 @@ 终止符 + + + 808版本号 + + 原数据 @@ -3443,6 +3448,11 @@ 数据体 + + + 分包数据体 + + 校验码 @@ -3467,11 +3477,6 @@ - - - 统一分包数据体 - - 采集记录仪执行标准版本 diff --git a/src/JT808.Protocol/JT808HeaderPackage.cs b/src/JT808.Protocol/JT808HeaderPackage.cs index 0a9f9bf..07ba465 100644 --- a/src/JT808.Protocol/JT808HeaderPackage.cs +++ b/src/JT808.Protocol/JT808HeaderPackage.cs @@ -1,16 +1,13 @@ -using JT808.Protocol.Attributes; -using JT808.Protocol.Enums; +using JT808.Protocol.Enums; using JT808.Protocol.Exceptions; -using JT808.Protocol.Formatters; using JT808.Protocol.MessagePack; -using System; namespace JT808.Protocol { /// /// JT808头部数据包 /// - public ref struct JT808HeaderPackage + public record JT808HeaderPackage { /// /// 起始符 @@ -23,7 +20,7 @@ namespace JT808.Protocol /// /// 数据体 /// - public ReadOnlySpan Bodies { get; set; } + public byte[] Bodies { get; set; } /// /// 校验码 /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 @@ -33,7 +30,10 @@ namespace JT808.Protocol /// 终止符 /// public byte End { get; set; } - public JT808Version Version + /// + /// 808版本号 + /// + public JT808Version Version { get { if (Header != null) @@ -63,9 +63,9 @@ namespace JT808.Protocol /// /// 原数据 /// - public ReadOnlySpan OriginalData { get; set; } + public byte[] OriginalData { get; set; } - public JT808HeaderPackage(ref JT808MessagePackReader reader, IJT808Config config) + public JT808HeaderPackage(ref JT808MessagePackReader reader, IJT808Config config) { // 1. 验证校验和 if (!config.SkipCRCCode) @@ -115,18 +115,18 @@ namespace JT808.Protocol // 4.1.判断有无数据体 if (this.Header.MessageBodyProperty.DataLength > 0) { - this.Bodies = reader.ReadContent(); + this.Bodies = reader.ReadContent().ToArray(); } else { - this.Bodies = ReadOnlySpan.Empty; + this.Bodies = default; } // 5.读取校验码 this.CheckCode = reader.ReadByte(); // 6.读取终止位置 this.End = reader.ReadEnd(); // ---------------解包完成-------------- - this.OriginalData = reader.SrcBuffer; + this.OriginalData = reader.SrcBuffer.ToArray(); } } } diff --git a/src/JT808.Protocol/JT808Package.cs b/src/JT808.Protocol/JT808Package.cs index bff54fa..9896b53 100644 --- a/src/JT808.Protocol/JT808Package.cs +++ b/src/JT808.Protocol/JT808Package.cs @@ -5,7 +5,6 @@ using JT808.Protocol.Formatters; using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; using System; -using System.Runtime.InteropServices; using System.Text.Json; namespace JT808.Protocol @@ -36,6 +35,10 @@ namespace JT808.Protocol /// public JT808Bodies Bodies { get; set; } /// + /// 分包数据体 + /// + public byte[] SubDataBodies { get; set; } + /// /// 校验码 /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 /// @@ -128,32 +131,14 @@ namespace JT808.Protocol { if (jT808Package.Header.MessageBodyProperty.IsPackage) { - if (jT808Package.Header.PackageIndex > 1) + //读取分包的数据体 + try { - try - { - //4.2处理第二包之后的分包数据消息体 - JT808SplitPackageBodies jT808SplitPackageBodies = new JT808SplitPackageBodies(); - jT808Package.Bodies = jT808SplitPackageBodies.Deserialize(ref reader, config); - } - catch (Exception ex) - { - throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); - } + jT808Package.SubDataBodies = reader.ReadArray(jT808Package.Header.MessageBodyProperty.DataLength).ToArray(); } - else + catch (Exception ex) { - try - { - //4.2.处理消息体 - jT808Package.Bodies = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize( - instance, - ref reader, config); - } - catch (Exception ex) - { - throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); - } + throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); } } else @@ -225,14 +210,25 @@ namespace JT808.Protocol writer.WriteUInt16(value.Header.PackageIndex); } int headerLength = writer.GetCurrentPosition(); - // 3.处理数据体部分 - if (value.Bodies != null) + if (value.Header.MessageBodyProperty.IsPackage) + { + if (value.SubDataBodies != null) + { + //2.5.3.写入分包数据 + writer.WriteArray(value.SubDataBodies); + } + } + else { - if (!value.Bodies.SkipSerialization) + // 3.处理数据体部分 + if (value.Bodies != null) { - JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(value.Bodies, - ref writer, value.Bodies, - config); + if (!value.Bodies.SkipSerialization) + { + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(value.Bodies, + ref writer, value.Bodies, + config); + } } } // 3.1.处理数据体长度 @@ -318,58 +314,38 @@ namespace JT808.Protocol // 4.1.判断有无数据体 if (headerMessageBodyProperty.DataLength > 0) { - if (config.MsgIdFactory.TryGetValue(msgid, out object instance)) + //数据体属性对象 开始 + writer.WriteStartObject("数据体对象"); + string description = "数据体"; + if (headerMessageBodyProperty.IsPackage) { - //数据体属性对象 开始 - writer.WriteStartObject("数据体对象"); - string description = "数据体"; - if (instance is IJT808Description jT808Description) + //读取分包的数据体 + try { - //4.2.处理消息体 - description = jT808Description.Description; + writer.WriteString($"[分包]数据体", reader.ReadArray(reader.ReadCurrentRemainContentLength()).ToArray().ToHexString()); } - if (headerMessageBodyProperty.IsPackage) + catch (IndexOutOfRangeException ex) { - if (packageIndex > 1) - { - try - { - //4.2处理第二包之后的分包数据消息体 - writer.WriteString($"[分包]数据体", reader.ReadContent().ToArray().ToHexString()); - } - catch (Exception ex) - { - writer.WriteString($"[分包]数据体异常", ex.StackTrace); - } - } - else - { - try - { - //数据体长度正常 - writer.WriteString($"[分包]{description}", reader.ReadVirtualArray(reader.ReadCurrentRemainContentLength()).ToArray().ToHexString()); - if (instance is IJT808Analyze analyze) - { - //4.2.处理消息体 - analyze.Analyze(ref reader, writer, config); - } - } - catch (IndexOutOfRangeException ex) - { - writer.WriteString($"数据体解析异常,无可用数据体进行解析", ex.StackTrace); - } - catch (ArgumentOutOfRangeException ex) - { - writer.WriteString($"[分包]数据体解析异常,无可用数据体进行解析", ex.StackTrace); - } - catch (Exception ex) - { - writer.WriteString($"[分包]数据体异常", ex.StackTrace); - } - } + writer.WriteString($"数据体解析异常,无可用数据体进行解析", ex.StackTrace); } - else + catch (ArgumentOutOfRangeException ex) + { + writer.WriteString($"[分包]数据体解析异常,无可用数据体进行解析", ex.StackTrace); + } + catch (Exception ex) + { + writer.WriteString($"[分包]数据体异常", ex.StackTrace); + } + } + else + { + if (config.MsgIdFactory.TryGetValue(msgid, out object instance)) { + if (instance is IJT808Description jT808Description) + { + //4.2.处理消息体 + description = jT808Description.Description; + } try { //数据体长度正常 @@ -380,7 +356,7 @@ namespace JT808.Protocol analyze.Analyze(ref reader, writer, config); } } - catch(IndexOutOfRangeException ex) + catch (IndexOutOfRangeException ex) { writer.WriteString($"数据体解析异常,无可用数据体进行解析", ex.StackTrace); } @@ -393,13 +369,13 @@ namespace JT808.Protocol writer.WriteString($"数据体异常", ex.StackTrace); } } - //数据体属性对象 结束 - writer.WriteEndObject(); - } - else - { - writer.WriteNull($"[Null]数据体"); + else + { + writer.WriteString($"[未知]数据体", reader.ReadArray(reader.ReadCurrentRemainContentLength()).ToArray().ToHexString()); + } } + //数据体属性对象 结束 + writer.WriteEndObject(); } else { diff --git a/src/JT808.Protocol/JT808SplitPackageBodies.cs b/src/JT808.Protocol/JT808SplitPackageBodies.cs deleted file mode 100644 index 1a81e3c..0000000 --- a/src/JT808.Protocol/JT808SplitPackageBodies.cs +++ /dev/null @@ -1,33 +0,0 @@ -using JT808.Protocol.Attributes; -using JT808.Protocol.Formatters; -using JT808.Protocol.MessagePack; - -namespace JT808.Protocol -{ - /// - /// 统一分包数据体 - /// - public class JT808SplitPackageBodies : JT808Bodies, IJT808MessagePackFormatter - { - - public byte[] Data { get; set; } - - public override ushort MsgId => 0xFFFF; - - public override string Description => "统一分包数据体"; - - public JT808SplitPackageBodies Deserialize(ref JT808MessagePackReader reader, IJT808Config config) - { - JT808SplitPackageBodies jT808SplitPackageBodies = new JT808SplitPackageBodies - { - Data = reader.ReadContent().ToArray() - }; - return jT808SplitPackageBodies; - } - - public void Serialize(ref JT808MessagePackWriter writer, JT808SplitPackageBodies value, IJT808Config config) - { - writer.WriteArray(value.Data); - } - } -}