diff --git a/README.md b/README.md index 05ffdd2..a673d6d 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,13 @@ JT808Serializer DT2JT808Serializer = new JT808Serializer(DT2JT808Config); [可以参考Simples的Demo10](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo10.cs) +### 举个栗子11 + +场景: +有些设备,补报的定位数据有异常数据包内容长度跟原始的内容长度不一致导致整包的数据的解析出错,再设备不升级,改不了的情况下,尽量能解析多少补报的数据量,就解析多少。 + +[可以参考Simples的Demo11](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo11.cs) + ## NuGet安装 | Package Name | Version | Downloads | diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs index b54e028..4fb1fec 100644 --- a/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs @@ -1,4 +1,5 @@ using JT808.Protocol.Extensions; +using JT808.Protocol.Internal; using JT808.Protocol.MessageBody; using System; using System.Collections.Generic; @@ -9,6 +10,10 @@ namespace JT808.Protocol.Test.MessageBody public class JT808_0x0704Test { JT808Serializer JT808Serializer = new JT808Serializer(); + JT808Serializer JT808Serializer1 = new JT808Serializer(new DefaultGlobalConfig() { + SkipCRCCode=true + }); + [Fact] public void Test1() { @@ -151,11 +156,28 @@ namespace JT808.Protocol.Test.MessageBody Assert.Equal(96, ((JT808_0x0200_0x01)JT808Bodies.Positions[1].JT808LocationAttachData[JT808Constants.JT808_0x0200_0x01]).Mileage); Assert.Equal(66, ((JT808_0x0200_0x02)JT808Bodies.Positions[1].JT808LocationAttachData[JT808Constants.JT808_0x0200_0x02]).Oil); } + [Fact] public void Test3() { byte[] bytes = "7E 07 04 00 53 11 22 33 44 55 66 22 B8 00 02 00 00 26 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 07 15 10 10 10 01 04 00 00 00 64 02 02 00 37 00 26 00 00 00 02 00 00 00 01 00 CB 73 55 07 E6 A3 23 00 29 00 36 00 78 18 07 15 10 10 30 01 04 00 00 00 60 02 02 00 42 D4 7E".ToHexBytes(); string json = JT808Serializer.Analyze(bytes); } + + [Fact] + public void Test4() + { + byte[] bytes = "7E070401D90111111111118D1F00020100E90000000000000003016550E2060E84A8056402B20064200603172833010400054576030202B2EA5A00030507020F226300040503012A9198000504002469400006040035FF1E0007040008522800100E000400FA00BC00A500B000A202B2001202011B00130100001401190015020000001601F000170203D20018010F0019020047EC6560C00204F760D001456050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA6510501725106026E685107023A80510802FFFF510A0103510C0155510D0400000000511101025112010000E900000003016550BA060E8620056302BC005E200603172835010400054577030202BCEA5A00030507020F22AE00040503012A9198000504002469420006040035FF1E0007040008522800100E000400FA00890083008A009602BC001202011B00130100001401190015020000001601F000170203D20018010E0019020048EC6560C002050260D001466050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA65105017251060273185107023A60510802FFFF510A0103510C0155510D04000000005111010251120100807E".ToHexBytes(); + var package = JT808Serializer1.Deserialize(bytes); + var bodies = package.Bodies as JT808_0x0704; + Assert.Single(bodies.ErrorRemainPositions); + } + + [Fact] + public void Test4_1() + { + byte[] bytes = "7E070401D90111111111118D1F00020100E90000000000000003016550E2060E84A8056402B20064200603172833010400054576030202B2EA5A00030507020F226300040503012A9198000504002469400006040035FF1E0007040008522800100E000400FA00BC00A500B000A202B2001202011B00130100001401190015020000001601F000170203D20018010F0019020047EC6560C00204F760D001456050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA6510501725106026E685107023A80510802FFFF510A0103510C0155510D0400000000511101025112010000E900000003016550BA060E8620056302BC005E200603172835010400054577030202BCEA5A00030507020F22AE00040503012A9198000504002469420006040035FF1E0007040008522800100E000400FA00890083008A009602BC001202011B00130100001401190015020000001601F000170203D20018010E0019020048EC6560C002050260D001466050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA65105017251060273185107023A60510802FFFF510A0103510C0155510D04000000005111010251120100807E".ToHexBytes(); + var json = JT808Serializer1.Analyze(bytes); + } } } diff --git a/src/JT808.Protocol.Test/Simples/Demo11.cs b/src/JT808.Protocol.Test/Simples/Demo11.cs new file mode 100644 index 0000000..0318640 --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo11.cs @@ -0,0 +1,35 @@ +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; +using JT808.Protocol.Formatters; +using JT808.Protocol.MessagePack; +using System.Text.Json; +using JT808.Protocol.MessageBody.CarDVR; +using System.Linq; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo11 + { + JT808Serializer JT808Serializer = new JT808Serializer(new DefaultGlobalConfig() { SkipCRCCode = true }); + + [Fact] + public void Test1() + { + byte[] bytes = "7E070401D90111111111118D1F00020100E90000000000000003016550E2060E84A8056402B20064200603172833010400054576030202B2EA5A00030507020F226300040503012A9198000504002469400006040035FF1E0007040008522800100E000400FA00BC00A500B000A202B2001202011B00130100001401190015020000001601F000170203D20018010F0019020047EC6560C00204F760D001456050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA6510501725106026E685107023A80510802FFFF510A0103510C0155510D0400000000511101025112010000E900000003016550BA060E8620056302BC005E200603172835010400054577030202BCEA5A00030507020F22AE00040503012A9198000504002469420006040035FF1E0007040008522800100E000400FA00890083008A009602BC001202011B00130100001401190015020000001601F000170203D20018010E0019020048EC6560C002050260D001466050017860F0015150B002005C6330015564600151649001005001010050020100500301005101017D01510201835104020FA65105017251060273185107023A60510802FFFF510A0103510C0155510D04000000005111010251120100807E".ToHexBytes(); + var package = JT808Serializer.Deserialize(bytes); + var bodies = package.Bodies as JT808_0x0704; + //从第几个补传数据开始后续的包就有问题 + Assert.Equal(1,bodies.ErrorRemainPositions.FirstOrDefault(i=>i.Key==1).Key); + Assert.Equal(2, bodies.Count); + Assert.Single(bodies.Positions); + } + } +} diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 581be6c..f014a1a 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -10208,6 +10208,13 @@ 位置汇报数据集合 + + + 异常错误剩余数据存储 + key:count index + value:0200 data + + 位置数据类型 diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0704.cs b/src/JT808.Protocol/MessageBody/JT808_0x0704.cs index 115cebb..ba67380 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x0704.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x0704.cs @@ -34,7 +34,13 @@ namespace JT808.Protocol.MessageBody /// /// 位置汇报数据集合 /// - public IList Positions { get; set; } + public List Positions { get; set; } + /// + /// 异常错误剩余数据存储 + /// key:count index + /// value:0200 data + /// + public Dictionary ErrorRemainPositions { get; set; } /// /// 位置数据类型 @@ -61,22 +67,34 @@ namespace JT808.Protocol.MessageBody JT808_0x0704 jT808_0X0704 = new JT808_0x0704(); jT808_0X0704.Count = reader.ReadUInt16(); jT808_0X0704.LocationType = (JT808_0x0704.BatchLocationType)reader.ReadByte(); - List jT808_0X0200s = new List(); + jT808_0X0704.ErrorRemainPositions = new Dictionary(); + jT808_0X0704.Positions = new List(); for (int i = 0; i < jT808_0X0704.Count; i++) { + int remainContent = reader.ReadCurrentRemainContentLength(); + if (remainContent <= 0) continue; int buflen = reader.ReadUInt16(); - try + if ((remainContent-buflen) >= 0) { - JT808MessagePackReader tmpReader = new JT808MessagePackReader(reader.ReadArray(buflen)); - JT808_0x0200 jT808_0X0200 = config.GetMessagePackFormatter().Deserialize(ref tmpReader, config); - jT808_0X0200s.Add(jT808_0X0200); + var buffer = reader.ReadArray(buflen); + try + { + JT808MessagePackReader tmpReader = new JT808MessagePackReader(buffer, reader.Version); + JT808_0x0200 jT808_0X0200 = config.GetMessagePackFormatter().Deserialize(ref tmpReader, config); + jT808_0X0704.Positions.Add(jT808_0X0200); + } + catch + { + jT808_0X0704.ErrorRemainPositions.Add(i, buffer.ToArray()); + } } - catch (Exception) + else { - + int remainContent1 = reader.ReadCurrentRemainContentLength(); + var buffer = reader.ReadArray(remainContent1); + jT808_0X0704.ErrorRemainPositions.Add(i, buffer.ToArray()); } } - jT808_0X0704.Positions = jT808_0X0200s; return jT808_0X0704; } /// @@ -87,22 +105,30 @@ namespace JT808.Protocol.MessageBody /// public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0704 value, IJT808Config config) { - writer.WriteUInt16(value.Count); - writer.WriteByte((byte)value.LocationType); - foreach (var item in value?.Positions) + if(value.Positions!=null && value.Positions.Count > 0) { - try - { - writer.Skip(2, out int position); - config.GetMessagePackFormatter().Serialize(ref writer, item, config); - ushort length = (ushort)(writer.GetCurrentPosition() - position - 2); - writer.WriteUInt16Return(length, position); - } - catch (Exception) + writer.WriteUInt16((ushort)value.Positions.Count); + writer.WriteByte((byte)value.LocationType); + foreach (var item in value.Positions) { + try + { + writer.Skip(2, out int position); + config.GetMessagePackFormatter().Serialize(ref writer, item, config); + ushort length = (ushort)(writer.GetCurrentPosition() - position - 2); + writer.WriteUInt16Return(length, position); + } + catch (Exception) + { + } } } + else + { + writer.WriteUInt16(0); + writer.WriteByte((byte)value.LocationType); + } } /// /// @@ -120,20 +146,31 @@ namespace JT808.Protocol.MessageBody writer.WriteStartArray("位置汇报数据集合"); for (int i = 0; i < jT808_0X0704.Count; i++) { + int remainContent = reader.ReadCurrentRemainContentLength(); + if (remainContent <= 0) continue; writer.WriteStartObject(); int buflen = reader.ReadUInt16(); writer.WriteNumber($"[{buflen.ReadNumber()}]位置汇报数据长度", buflen); - try + if ((remainContent - buflen) >= 0) { - writer.WriteString($"位置汇报数据", reader.ReadVirtualArray(buflen).ToArray().ToHexString()); - JT808MessagePackReader tmpReader = new JT808MessagePackReader(reader.ReadArray(buflen)); + writer.WriteString($"位置汇报数据{{{i}}}", reader.ReadVirtualArray(buflen).ToArray().ToHexString()); + JT808MessagePackReader tmpReader = new JT808MessagePackReader(reader.ReadArray(buflen), reader.Version); writer.WriteStartObject("位置信息汇报"); - config.GetAnalyze().Analyze(ref tmpReader, writer, config); + try + { + config.GetAnalyze().Analyze(ref tmpReader, writer, config); + } + catch (Exception ex) + { + writer.WriteString($"分析异常", ex.StackTrace); + } writer.WriteEndObject(); } - catch (Exception) + else { - + int remainContent1 = reader.ReadCurrentRemainContentLength(); + var buffer = reader.ReadArray(remainContent1); + writer.WriteString($"位置汇报异常数据{{{i}}}", buffer.ToArray().ToHexString()); } writer.WriteEndObject(); } diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0801.cs b/src/JT808.Protocol/MessageBody/JT808_0x0801.cs index 0150483..c5efef0 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x0801.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x0801.cs @@ -73,7 +73,7 @@ namespace JT808.Protocol.MessageBody writer.WriteNumber($"[{value.EventItemCoding.ReadNumber()}]事件项编码-{((JT808EventItemCoding)value.EventItemCoding).ToString()}", value.MultimediaCodingFormat); value.ChannelId = reader.ReadByte(); writer.WriteNumber($"[{value.ChannelId.ReadNumber()}]通道ID", value.ChannelId); - JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28), reader.Version); writer.WriteStartObject("位置基本信息"); config.GetAnalyze().Analyze(ref positionReader, writer, config); writer.WriteEndObject(); @@ -94,7 +94,7 @@ namespace JT808.Protocol.MessageBody value.MultimediaCodingFormat = reader.ReadByte(); value.EventItemCoding = reader.ReadByte(); value.ChannelId = reader.ReadByte(); - JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28), reader.Version); value.Position = config.GetMessagePackFormatter().Deserialize(ref positionReader, config); value.MultimediaDataPackage = reader.ReadContent().ToArray(); return value; diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0802.cs b/src/JT808.Protocol/MessageBody/JT808_0x0802.cs index 180b93f..24e82ea 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x0802.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x0802.cs @@ -63,7 +63,7 @@ namespace JT808.Protocol.MessageBody writer.WriteNumber($"[{jT808MultimediaSearchProperty.ChannelId.ReadNumber()}]通道ID", jT808MultimediaSearchProperty.ChannelId); jT808MultimediaSearchProperty.EventItemCoding = reader.ReadByte(); writer.WriteNumber($"[{jT808MultimediaSearchProperty.EventItemCoding.ReadNumber()}]事件项编码-{((JT808EventItemCoding)jT808MultimediaSearchProperty.EventItemCoding).ToString()}", jT808MultimediaSearchProperty.EventItemCoding); - JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28), reader.Version); writer.WriteStartObject($"位置基本信息"); config.GetAnalyze().Analyze(ref positionReader, writer, config); writer.WriteEndObject(); @@ -90,7 +90,7 @@ namespace JT808.Protocol.MessageBody jT808MultimediaSearchProperty.MultimediaType = reader.ReadByte(); jT808MultimediaSearchProperty.ChannelId = reader.ReadByte(); jT808MultimediaSearchProperty.EventItemCoding = reader.ReadByte(); - JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28), reader.Version); jT808MultimediaSearchProperty.Position = config.GetMessagePackFormatter().Deserialize(ref positionReader, config); value.MultimediaSearchItems.Add(jT808MultimediaSearchProperty); }