diff --git a/README.md b/README.md index 753f352..036f52e 100644 --- a/README.md +++ b/README.md @@ -342,17 +342,17 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0 | 32 | 0x8401 | √ | √ | 设置电话本 | | 33 | 0x8500 | √ | √ | 车辆控制 |修改| | 34 | 0x0500 | √ | √ | 车辆控制应答 | -| 35 | 0x8600 | √ | √ | 设置圆形区域 | +| 35 | 0x8600 | √ | √ | 设置圆形区域 |修改| | 36 | 0x8601 | √ | √ | 删除圆形区域 | -| 37 | 0x8602 | √ | √ | 设置矩形区域 | +| 37 | 0x8602 | √ | √ | 设置矩形区域 |修改| | 38 | 0x8603 | √ | √ | 删除矩形区域 | -| 39 | 0x8604 | √ | √ | 设置多边形区域 | +| 39 | 0x8604 | √ | √ | 设置多边形区域 |修改| | 40 | 0x8605 | √ | √ | 删除多边形区域 | -| 41 | 0x8606 | √ | √ | 设置路线 | +| 41 | 0x8606 | √ | √ | 设置路线 |修改| | 42 | 0x8607 | √ | √ | 删除路线 | -| 43 | 0x8700 | x | 不开发 | 行驶记录仪数据采集命令 | -| 44 | 0x0700 | x | 不开发 | 行驶记录仪数据上传 | -| 45 | 0x8701 | x | 不开发 | 行驶记录仪参数下传命令 | +| 43 | 0x8700 | x | 不开发 | 行驶记录仪数据采集命令 |不开发 +| 44 | 0x0700 | x | 不开发 | 行驶记录仪数据上传 |不开发 +| 45 | 0x8701 | x | 不开发 | 行驶记录仪参数下传命令 |不开发 | 46 | 0x0701 | √ | √ | 电子运单上报 | | 47 | 0x0702 | √ | √ | 驾驶员身份信息采集上报 | | 48 | 0x8702 | √ | 消息体为空| 上报驾驶员身份信息请求 | diff --git a/doc/JTT.808-2019.PDF b/doc/JTT.808-2019.PDF index 4456068..0afe24d 100644 Binary files a/doc/JTT.808-2019.PDF and b/doc/JTT.808-2019.PDF differ diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs index 9fbcaa2..36fa2e5 100644 --- a/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs @@ -104,5 +104,54 @@ namespace JT808.Protocol.Test.MessageBody Assert.Equal((byte)200, item2.OverspeedDuration); } + + [Fact] + public void Test_2019_1() + { + JT808_0x8600 jT808_0X8600 = new JT808_0x8600 + { + SettingAreaProperty = JT808SettingProperty.追加区域.ToByteValue(), + AreaItems = new List() + }; + jT808_0X8600.AreaItems.Add(new JT808CircleAreaProperty + { + AreaId = 1522, + AreaProperty = 222, + CenterPointLat = 123456789, + CenterPointLng = 123456789, + Radius = 200, + StartTime = DateTime.Parse("2019-11-30 00:00:12"), + EndTime = DateTime.Parse("2019-11-30 00:00:12"), + HighestSpeed = 60, + OverspeedDuration = 200, + NightMaximumSpeed=666, + AreaName="SmallChi" + }); + var hex = JT808Serializer.Serialize(jT808_0X8600,JT808Version.JTT2019).ToHexString(); + + Assert.Equal("0101000005F200DE075BCD15075BCD15000000C8003CC8029A0008536D616C6C436869", hex); + } + + [Fact] + public void Test_2019_2() + { + byte[] bytes = "0101000005F200DE075BCD15075BCD15000000C8003CC8029A0008536D616C6C436869".ToHexBytes(); + JT808_0x8600 jT808_0X8600 = JT808Serializer.Deserialize(bytes, JT808Version.JTT2019); + + Assert.Equal(JT808SettingProperty.追加区域.ToByteValue(), jT808_0X8600.SettingAreaProperty); + Assert.Equal(1, jT808_0X8600.AreaCount); + var item0 = jT808_0X8600.AreaItems[0]; + Assert.Equal((uint)1522, item0.AreaId); + Assert.Equal((ushort)222, item0.AreaProperty); + Assert.Equal((uint)123456789, item0.CenterPointLat); + Assert.Equal((uint)123456789, item0.CenterPointLng); + Assert.Equal((uint)200, item0.Radius); + Assert.Null(item0.StartTime); + Assert.Null(item0.EndTime); + Assert.Equal((ushort)60, item0.HighestSpeed); + Assert.Equal((byte)200, item0.OverspeedDuration); + Assert.Equal(666, item0.NightMaximumSpeed); + Assert.Equal("SmallChi", item0.AreaName); + } } } diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 8e5606f..1c693ee 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -5290,6 +5290,24 @@ 顶点项 + + + 夜间最高速度 + 2019版本 + + + + + 名称长度 + 2019版本 + + + + + 区域名称 + 2019版本 + + 删除多边形区域 @@ -5346,6 +5364,16 @@ 拐点项 + + + 名称长度 + + + + + 路线名称 + + 删除路线 @@ -5788,6 +5816,24 @@ 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 + + + 夜间最高速度 + 2019版本 + + + + + 名称长度 + 2019版本 + + + + + 区域名称 + 2019版本 + + 电话本联系人项数据 @@ -6039,6 +6085,24 @@ 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 + + + 夜间最高速度 + 2019版本 + + + + + 名称长度 + 2019版本 + + + + + 区域名称 + 2019版本 + + 分包属性 diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8600.cs b/src/JT808.Protocol/MessageBody/JT808_0x8600.cs index fd805d2..63fc9e1 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x8600.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x8600.cs @@ -1,4 +1,6 @@ -using JT808.Protocol.Formatters; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; using JT808.Protocol.Metadata; using System; @@ -11,7 +13,7 @@ namespace JT808.Protocol.MessageBody /// 0x8600 /// 注:本条消息协议支持周期时间范围,如要限制每天的8:30-18:00,起始/结束时间设为:00-00-00-08-30-00/00-00-00-18-00-00,其他以此类推 /// - public class JT808_0x8600 : JT808Bodies, IJT808MessagePackFormatter + public class JT808_0x8600 : JT808Bodies, IJT808MessagePackFormatter, IJT808_2019_Version { public override ushort MsgId { get; } = 0x8600; /// @@ -54,6 +56,15 @@ namespace JT808.Protocol.MessageBody { jT808CircleAreaProperty.HighestSpeed = reader.ReadUInt16(); jT808CircleAreaProperty.OverspeedDuration = reader.ReadByte(); + if (reader.Version == JT808Version.JTT2019) + { + jT808CircleAreaProperty.NightMaximumSpeed = reader.ReadUInt16(); + } + } + if(reader.Version== JT808Version.JTT2019) + { + jT808CircleAreaProperty.NameLength = reader.ReadUInt16(); + jT808CircleAreaProperty.AreaName = reader.ReadString(jT808CircleAreaProperty.NameLength); } jT808_0X8600.AreaItems.Add(jT808CircleAreaProperty); } @@ -97,6 +108,16 @@ namespace JT808.Protocol.MessageBody { writer.WriteByte(item.OverspeedDuration.Value); } + if (writer.Version == JT808Version.JTT2019) + { + writer.WriteUInt16(item.NightMaximumSpeed); + } + } + if (writer.Version == JT808Version.JTT2019) + { + writer.Skip(2, out int AreaNameLengthPosition); + writer.WriteString(item.AreaName); + writer.WriteUInt16Return((ushort)(writer.GetCurrentPosition()- AreaNameLengthPosition-2), AreaNameLengthPosition); } } } diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8602.cs b/src/JT808.Protocol/MessageBody/JT808_0x8602.cs index cb27459..4ae2ddb 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x8602.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x8602.cs @@ -1,4 +1,6 @@ -using JT808.Protocol.Formatters; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; using JT808.Protocol.Metadata; using System; @@ -10,7 +12,7 @@ namespace JT808.Protocol.MessageBody /// 设置矩形区域 /// 0x8602 /// - public class JT808_0x8602 : JT808Bodies, IJT808MessagePackFormatter + public class JT808_0x8602 : JT808Bodies, IJT808MessagePackFormatter, IJT808_2019_Version { public override ushort MsgId { get; } = 0x8602; /// @@ -35,27 +37,36 @@ namespace JT808.Protocol.MessageBody jT808_0X8602.AreaItems = new List(); for (var i = 0; i < jT808_0X8602.AreaCount; i++) { - JT808RectangleAreaProperty jT808CircleAreaProperty = new JT808RectangleAreaProperty(); - jT808CircleAreaProperty.AreaId = reader.ReadUInt32(); - jT808CircleAreaProperty.AreaProperty = reader.ReadUInt16(); - jT808CircleAreaProperty.UpLeftPointLat = reader.ReadUInt32(); - jT808CircleAreaProperty.UpLeftPointLng = reader.ReadUInt32(); - jT808CircleAreaProperty.LowRightPointLat = reader.ReadUInt32(); - jT808CircleAreaProperty.LowRightPointLng = reader.ReadUInt32(); - ReadOnlySpan areaProperty16Bit = Convert.ToString(jT808CircleAreaProperty.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + JT808RectangleAreaProperty areaProperty = new JT808RectangleAreaProperty(); + areaProperty.AreaId = reader.ReadUInt32(); + areaProperty.AreaProperty = reader.ReadUInt16(); + areaProperty.UpLeftPointLat = reader.ReadUInt32(); + areaProperty.UpLeftPointLng = reader.ReadUInt32(); + areaProperty.LowRightPointLat = reader.ReadUInt32(); + areaProperty.LowRightPointLng = reader.ReadUInt32(); + ReadOnlySpan areaProperty16Bit = Convert.ToString(areaProperty.AreaProperty, 2).PadLeft(16, '0').AsSpan(); bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); if (!bit0Flag) { - jT808CircleAreaProperty.StartTime = reader.ReadDateTime6(); - jT808CircleAreaProperty.EndTime = reader.ReadDateTime6(); + areaProperty.StartTime = reader.ReadDateTime6(); + areaProperty.EndTime = reader.ReadDateTime6(); } bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); if (!bit1Flag) { - jT808CircleAreaProperty.HighestSpeed = reader.ReadUInt16(); - jT808CircleAreaProperty.OverspeedDuration = reader.ReadByte(); + areaProperty.HighestSpeed = reader.ReadUInt16(); + areaProperty.OverspeedDuration = reader.ReadByte(); + if (reader.Version == JT808Version.JTT2019) + { + areaProperty.NightMaximumSpeed = reader.ReadUInt16(); + } + } + if (reader.Version == JT808Version.JTT2019) + { + areaProperty.NameLength = reader.ReadUInt16(); + areaProperty.AreaName = reader.ReadString(areaProperty.NameLength); } - jT808_0X8602.AreaItems.Add(jT808CircleAreaProperty); + jT808_0X8602.AreaItems.Add(areaProperty); } return jT808_0X8602; } @@ -98,6 +109,16 @@ namespace JT808.Protocol.MessageBody { writer.WriteByte(item.OverspeedDuration.Value); } + if (writer.Version == JT808Version.JTT2019) + { + writer.WriteUInt16(item.NightMaximumSpeed); + } + } + if (writer.Version == JT808Version.JTT2019) + { + writer.Skip(2, out int AreaNameLengthPosition); + writer.WriteString(item.AreaName); + writer.WriteUInt16Return((ushort)(writer.GetCurrentPosition() - AreaNameLengthPosition - 2), AreaNameLengthPosition); } } } diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8604.cs b/src/JT808.Protocol/MessageBody/JT808_0x8604.cs index 509697a..46c65b0 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x8604.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x8604.cs @@ -1,4 +1,6 @@ -using JT808.Protocol.Formatters; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; using JT808.Protocol.Metadata; using System; @@ -10,7 +12,7 @@ namespace JT808.Protocol.MessageBody /// 设置多边形区域 /// 0x8604 /// - public class JT808_0x8604 : JT808Bodies, IJT808MessagePackFormatter + public class JT808_0x8604 : JT808Bodies, IJT808MessagePackFormatter, IJT808_2019_Version { public override ushort MsgId { get; } = 0x8604; /// @@ -50,6 +52,21 @@ namespace JT808.Protocol.MessageBody /// 顶点项 /// public List PeakItems { get; set; } + /// + /// 夜间最高速度 + /// 2019版本 + /// + public ushort NightMaximumSpeed { get; set; } + /// + /// 名称长度 + /// 2019版本 + /// + public ushort NameLength { get; set; } + /// + /// 区域名称 + /// 2019版本 + /// + public string AreaName { get; set; } public JT808_0x8604 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) { @@ -78,6 +95,15 @@ namespace JT808.Protocol.MessageBody item.Lng = reader.ReadUInt32(); jT808_0X8604.PeakItems.Add(item); } + if (reader.Version == JT808Version.JTT2019) + { + if (!bit1Flag) + { + jT808_0X8604.NightMaximumSpeed = reader.ReadUInt16(); + } + jT808_0X8604.NameLength = reader.ReadUInt16(); + jT808_0X8604.AreaName = reader.ReadString(jT808_0X8604.NameLength); + } return jT808_0X8604; } @@ -119,6 +145,16 @@ namespace JT808.Protocol.MessageBody writer.WriteUInt32(item.Lng); } } + if (writer.Version == JT808Version.JTT2019) + { + if (!bit1Flag) + { + writer.WriteUInt16(value.NightMaximumSpeed); + } + writer.Skip(2, out int AreaNameLengthPosition); + writer.WriteString(value.AreaName); + writer.WriteUInt16Return((ushort)(writer.GetCurrentPosition() - AreaNameLengthPosition - 2), AreaNameLengthPosition); + } } } } diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8606.cs b/src/JT808.Protocol/MessageBody/JT808_0x8606.cs index faa96e6..c4a0791 100644 --- a/src/JT808.Protocol/MessageBody/JT808_0x8606.cs +++ b/src/JT808.Protocol/MessageBody/JT808_0x8606.cs @@ -1,4 +1,6 @@ -using JT808.Protocol.Formatters; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; using JT808.Protocol.Metadata; using System; @@ -10,7 +12,7 @@ namespace JT808.Protocol.MessageBody /// 设置路线 /// 0x8606 /// - public class JT808_0x8606 : JT808Bodies, IJT808MessagePackFormatter + public class JT808_0x8606 : JT808Bodies, IJT808MessagePackFormatter, IJT808_2019_Version { public override ushort MsgId { get; } = 0x8606; /// @@ -40,6 +42,14 @@ namespace JT808.Protocol.MessageBody /// 拐点项 /// public List InflectionPointItems { get; set; } + /// + /// 名称长度 + /// + public ushort RouteNameLength { get; set; } + /// + /// 路线名称 + /// + public string RouteName { get; set; } public JT808_0x8606 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) { @@ -78,6 +88,11 @@ namespace JT808.Protocol.MessageBody jT808InflectionPointProperty.SectionOverspeedDuration = reader.ReadByte(); } jT808_0X8606.InflectionPointItems.Add(jT808InflectionPointProperty); + if (reader.Version == JT808Version.JTT2019) + { + jT808_0X8606.RouteNameLength = reader.ReadUInt16(); + jT808_0X8606.RouteName = reader.ReadString(jT808_0X8606.RouteNameLength); + } } return jT808_0X8606; } @@ -128,6 +143,12 @@ namespace JT808.Protocol.MessageBody } } } + if (writer.Version == JT808Version.JTT2019) + { + writer.Skip(2, out int RouteNameLengthPosition); + writer.WriteString(value.RouteName); + writer.WriteUInt16Return((ushort)(writer.GetCurrentPosition() - RouteNameLengthPosition - 2), RouteNameLengthPosition); + } } } } diff --git a/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs b/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs index d635883..39f1f1b 100644 --- a/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs +++ b/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs @@ -1,11 +1,12 @@ -using System; +using JT808.Protocol.Interfaces; +using System; namespace JT808.Protocol.Metadata { /// /// 圆形区域属性 /// - public struct JT808CircleAreaProperty + public struct JT808CircleAreaProperty: IJT808_2019_Version { /// /// 区域 ID @@ -50,5 +51,20 @@ namespace JT808.Protocol.Metadata /// 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 /// public byte? OverspeedDuration { get; set; } + /// + /// 夜间最高速度 + /// 2019版本 + /// + public ushort NightMaximumSpeed { get; set; } + /// + /// 名称长度 + /// 2019版本 + /// + public ushort NameLength { get; set; } + /// + /// 区域名称 + /// 2019版本 + /// + public string AreaName { get; set; } } } diff --git a/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs b/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs index 2d31c3a..51ac299 100644 --- a/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs +++ b/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs @@ -1,11 +1,12 @@ -using System; +using JT808.Protocol.Interfaces; +using System; namespace JT808.Protocol.Metadata { /// /// 矩形区域属性 /// - public struct JT808RectangleAreaProperty + public struct JT808RectangleAreaProperty : IJT808_2019_Version { /// /// 区域 ID @@ -55,5 +56,20 @@ namespace JT808.Protocol.Metadata /// 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 /// public byte? OverspeedDuration { get; set; } + /// + /// 夜间最高速度 + /// 2019版本 + /// + public ushort NightMaximumSpeed { get; set; } + /// + /// 名称长度 + /// 2019版本 + /// + public ushort NameLength { get; set; } + /// + /// 区域名称 + /// 2019版本 + /// + public string AreaName { get; set; } } }