diff --git a/README.md b/README.md index 61c78a4..0678c76 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ | 14 | 0x9006 | √ | 从链路连接保持应答消息 | | 15 | 0x9007 | √ | 从链路断开通知消息 | | 16 | 0x9008 | √ | 上级平台主动关闭链路通知消息 | +| 17 | 0x9101 | √ | 接收定位信息数量通知消息 | diff --git a/src/JT809.Protocol.Test/JT809MessageBody/JT809_0x9101Test.cs b/src/JT809.Protocol.Test/JT809MessageBody/JT809_0x9101Test.cs new file mode 100644 index 0000000..b6fe963 --- /dev/null +++ b/src/JT809.Protocol.Test/JT809MessageBody/JT809_0x9101Test.cs @@ -0,0 +1,34 @@ +using JT809.Protocol; +using JT809.Protocol.JT809Extensions; +using JT809.Protocol.JT809MessageBody; +using JT809.Protocol.JT809Exceptions; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JT809.Protocol.Test.JT809MessageBody +{ + public class JT809_0x9101Test + { + [Fact] + public void Test1() + { + JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); + jT809_0X9101.DynamicInfoTotal = 10000; + jT809_0X9101.StartTime = 1537513862; + jT809_0X9101.EndTime = 1537531862; + var hex = JT809Serializer.Serialize(jT809_0X9101).ToHexString(); + } + + [Fact] + public void Test2() + { + var bytes = "00 00 27 10 00 00 00 00 5B A4 99 86 00 00 00 00 5B A4 DF D6".ToHexBytes(); + JT809_0x9101 jT809_0X9101 = JT809Serializer.Deserialize(bytes); + Assert.Equal((uint)10000, jT809_0X9101.DynamicInfoTotal); + Assert.Equal((ulong)1537513862, jT809_0X9101.StartTime); + Assert.Equal((ulong)1537531862, jT809_0X9101.EndTime); + } + } +} diff --git a/src/JT809.Protocol/JT809Enums/JT809BusinessType.cs b/src/JT809.Protocol/JT809Enums/JT809BusinessType.cs index 39697b0..20cab5f 100644 --- a/src/JT809.Protocol/JT809Enums/JT809BusinessType.cs +++ b/src/JT809.Protocol/JT809Enums/JT809BusinessType.cs @@ -115,6 +115,7 @@ namespace JT809.Protocol.JT809Enums ///接收定位信息数量通知消息 /// [Description("接收定位信息数量通知消息")] + [JT809BodiesType(typeof(JT809_0x9101))] DOWN_TOTAL_RECV_BACK_MSG = 0x9101, #endregion #region 车辆动态信息交换 diff --git a/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs b/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs index 093c6df..278f448 100644 --- a/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs +++ b/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs @@ -7,7 +7,7 @@ using System.Buffers; namespace JT809.Protocol.JT809Extensions { - public static class JT809BinaryExtensions + public static class JT809BinaryExtensions { /// /// 日期限制于2000年 @@ -74,7 +74,7 @@ namespace JT809.Protocol.JT809Extensions // WriteLittle(write, (int)(Math.Pow(10, 6) * latlng), offset, 4); //} - public static long ReadBCD(ReadOnlySpan buf,ref int offset, int len) + public static long ReadBCD(ReadOnlySpan buf, ref int offset, int len) { long result = 0; try @@ -91,9 +91,9 @@ namespace JT809.Protocol.JT809Extensions return result; } - public static DateTime ReadDateTimeLittle(ReadOnlySpan buf,ref int offset) + public static DateTime ReadDateTimeLittle(ReadOnlySpan buf, ref int offset) { - DateTime dateTime= new DateTime( + DateTime dateTime = new DateTime( (buf[offset]).ReadBCD32(1) + DateLimitYear, (buf[offset + 1]).ReadBCD32(1), (buf[offset + 2]).ReadBCD32(1), @@ -116,18 +116,33 @@ namespace JT809.Protocol.JT809Extensions public static int ReadInt32Little(ReadOnlySpan read, ref int offset) { - int value= (read[offset] << 24) | (read[offset + 1] << 16) | (read[offset + 2] << 8) | read[offset + 3]; + int value = (read[offset] << 24) | (read[offset + 1] << 16) | (read[offset + 2] << 8) | read[offset + 3]; offset = offset + 4; return value; } public static uint ReadUInt32Little(ReadOnlySpan read, ref int offset) { - uint value =(uint) ((read[offset] << 24) | (read[offset + 1] << 16) | (read[offset + 2] << 8) | read[offset + 3]); + uint value = (uint)((read[offset] << 24) | (read[offset + 1] << 16) | (read[offset + 2] << 8) | read[offset + 3]); offset = offset + 4; return value; } + public static ulong ReadUInt64Little(ReadOnlySpan read, ref int offset) + { + ulong value = (ulong)( + (read[offset] << 56) | + (read[offset + 1] << 48) | + (read[offset + 2] << 40) | + (read[offset + 3] << 32) | + (read[offset + 4] << 24) | + (read[offset + 5] << 16) | + (read[offset + 6] << 8) | + read[offset + 7]); + offset = offset + 8; + return value; + } + public static ushort ReadUInt16Little(ReadOnlySpan read, ref int offset) { ushort value = (ushort)((read[offset] << 8) | (read[offset + 1])); @@ -142,7 +157,7 @@ namespace JT809.Protocol.JT809Extensions return value; } - public static byte[] ReadBytesLittle(ReadOnlySpan read, ref int offset,int len) + public static byte[] ReadBytesLittle(ReadOnlySpan read, ref int offset, int len) { ReadOnlySpan temp = read.Slice(offset, len); offset = offset + len; @@ -216,6 +231,19 @@ namespace JT809.Protocol.JT809Extensions return 4; } + public static int WriteUInt64Little(IMemoryOwner memoryOwner, int offset, ulong data) + { + memoryOwner.Memory.Span[offset] = (byte)(data >> 56); + memoryOwner.Memory.Span[offset + 1] = (byte)(data >> 48); + memoryOwner.Memory.Span[offset + 2] = (byte)(data >> 40); + memoryOwner.Memory.Span[offset + 3] = (byte)(data >> 32); + memoryOwner.Memory.Span[offset + 4] = (byte)(data >> 24); + memoryOwner.Memory.Span[offset + 5] = (byte)(data >> 16); + memoryOwner.Memory.Span[offset + 6] = (byte)(data >> 8); + memoryOwner.Memory.Span[offset + 7] = (byte)data; + return 8; + } + public static int WriteUInt16Little(ref byte[] write, int offset, ushort data) { write[offset] = (byte)(data >> 8); @@ -268,7 +296,7 @@ namespace JT809.Protocol.JT809Extensions return codeBytes.Length; } - public static int WriteStringPadLeftLittle(IMemoryOwner memoryOwner, int offset, string data,int len) + public static int WriteStringPadLeftLittle(IMemoryOwner memoryOwner, int offset, string data, int len) { data = data.PadLeft(len, '\0'); byte[] codeBytes = encoding.GetBytes(data); diff --git a/src/JT809.Protocol/JT809Formatters/JT809MessageBodyFormatters/JT809_0x9101Formatter.cs b/src/JT809.Protocol/JT809Formatters/JT809MessageBodyFormatters/JT809_0x9101Formatter.cs new file mode 100644 index 0000000..aa7a42d --- /dev/null +++ b/src/JT809.Protocol/JT809Formatters/JT809MessageBodyFormatters/JT809_0x9101Formatter.cs @@ -0,0 +1,31 @@ +using JT809.Protocol.JT809Extensions; +using JT809.Protocol.JT809MessageBody; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809Formatters.JT809MessageBodyFormatters +{ + public class JT809_0x9101Formatter : IJT809Formatter + { + public JT809_0x9101 Deserialize(ReadOnlySpan bytes, out int readSize) + { + int offset = 0; + JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); + jT809_0X9101.DynamicInfoTotal = JT809BinaryExtensions.ReadUInt32Little(bytes, ref offset); + jT809_0X9101.StartTime = JT809BinaryExtensions.ReadUInt64Little(bytes, ref offset); + jT809_0X9101.EndTime = JT809BinaryExtensions.ReadUInt64Little(bytes, ref offset); + readSize = offset; + return jT809_0X9101; + } + + public int Serialize(IMemoryOwner memoryOwner, int offset, JT809_0x9101 value) + { + offset += JT809BinaryExtensions.WriteUInt32Little(memoryOwner, offset, value.DynamicInfoTotal); + offset += JT809BinaryExtensions.WriteUInt64Little(memoryOwner, offset, value.StartTime); + offset += JT809BinaryExtensions.WriteUInt64Little(memoryOwner, offset, value.EndTime); + return offset; + } + } +} diff --git a/src/JT809.Protocol/JT809MessageBody/JT809_0x9101.cs b/src/JT809.Protocol/JT809MessageBody/JT809_0x9101.cs new file mode 100644 index 0000000..3962b9e --- /dev/null +++ b/src/JT809.Protocol/JT809MessageBody/JT809_0x9101.cs @@ -0,0 +1,35 @@ +using JT809.Protocol.JT809Attributes; +using JT809.Protocol.JT809Formatters.JT809MessageBodyFormatters; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809MessageBody +{ + /// + /// 接收车辆定位信息数量通知消息 + /// 链路类型:从链路 + /// 消息方向:上级平台往下级平台 + /// 业务类型标识: DOWN_TOTAL_RECV_BACK_MSG + /// 描述:上级平台向下级平台定星通知已经收到下级平台上传的车辆定位信息数量(如:每收到10,000 条车辆定位信息通知一次) + /// 本条消息不需下级平台应答。 + /// + [JT809Formatter(typeof(JT809_0x9101Formatter))] + public class JT809_0x9101:JT809Bodies + { + /// + /// START_TIME_END_TIME共收到的车辆定位信息数量 + /// + public uint DynamicInfoTotal { get; set; } + /// + /// 开始时间,用 UTC 时间表示 + /// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. + /// + public ulong StartTime { get; set; } + /// + /// 结束时间,用 UTC 时间表示 + /// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. + /// + public ulong EndTime { get; set; } + } +}