From ef0d9b0bf99ab37ff38a71634b0c9fcbf40c1d07 Mon Sep 17 00:00:00 2001 From: SmallChi <564952747@qq.com> Date: Mon, 24 Sep 2018 14:12:38 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=A2=9E=E5=8A=A00x1205|0x1206|0x1207?= =?UTF-8?q?=E6=B6=88=E6=81=AF=202.=E5=A2=9E=E5=8A=A00x1207=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=203.=E5=A2=9E=E5=8A=A0UTC=E6=97=B6=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++- doc/808809补充协议.pdf | Bin 423849 -> 422932 bytes .../JT809_0x1200_0x1207Test.cs | 36 ++++++++++++++++++ .../JT809Enums/JT809SubBusinessType.cs | 3 ++ .../JT809Extensions/JT809BinaryExtensions.cs | 26 +++++++++++++ .../JT809_0x1200_0x1207Formatter.cs | 29 ++++++++++++++ .../JT809_0x1200_0x1205.cs | 16 ++++++++ .../JT809_0x1200_0x1206.cs | 14 +++++++ .../JT809_0x1200_0x1207.cs | 26 +++++++++++++ 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1207Test.cs create mode 100644 src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1207Formatter.cs create mode 100644 src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1205.cs create mode 100644 src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1206.cs create mode 100644 src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1207.cs diff --git a/README.md b/README.md index b8a8355..2c28799 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,7 @@ | 1 | 0x1200 | √ | 主链路动态信息交换消息 | | 2 | 0x1201 | √ | 上传车辆注册信息 | | 3 | 0x1202 | √ | 实时上传车辆定位信息 | -| 4 | 0x1203 | √ | 车辆定位信息自动补报 | \ No newline at end of file +| 4 | 0x1203 | √ | 车辆定位信息自动补报 | +| 5 | 0x1205 | √ | 启动车辆定位信息交换应答消息 | +| 6 | 0x1206 | √ | 结束车辆定位信息交换应答消息 | +| 7 | 0x1207 | √ | 申请交换指定车辆定位信息请求消息 | \ No newline at end of file diff --git a/doc/808809补充协议.pdf b/doc/808809补充协议.pdf index 70c75849e148916ff6494ffbebe2d1b6e92b9d93..0e7ccc5a52d2144640984a12907e957e7a2bda3e 100644 GIT binary patch delta 7119 zcmdU!!Ef9|6o-{IM93VGKy6WEqy{c+JTsoLJtE2>n}$TCG)f{s3PE*tC+SAnb>#Ji zY%eR+N=V!)q4vZT!G%jC_JRawB#Oj;zy*~P2#Et1#2c@(o}IPo#C0UrmuzO=yf^c{ zdB10Szy9OW=T9$PompL6x{haUW9G?szkdIvVPF%P!SjS5++C1nrH>>uqxzE0C06(bfZlRPC-9~3tLu_TKImYflQfrU?{J_PCRXS&j;hf zQ_(m(3>#z4k3Ze}y^{fhr(4K_ft8XdKto14J&mq-CJmW+od(v6@Of}-ow7L2j>C1i z{pfIV`uM?bThnijo_VaOLoO1fmI@$=L!FvQcm3H+;{1<5anb`8udq0jJEvBxvqP~l zaUGy?x%c;eZPd0uvX>H4oVlmtYX$p)uw;@*N|@A6{W%m^x&h3-0yF za7(9+IgTeaZp0smJzS|j$Ke!|Cb8@G(*?I92&y(2?2mDex&6sQDJ1>LsYAHEbo6Y& zD{5O?AjY0M>JRo$`so@t1Vc}E2yb=Kh(kt41H%pyyVM_}uAVK-D3`A|;{2Z+5X>1o z>uXt%4*O%NL(UvqJ2NoX ze-ao5ZLS5eDZ`$Y1-U?`Aptw$Y8!zunxs070S7ag+aHVbFC8jOWB^zR*L4AYdcjCr z428-@X*mtV2eu{M43J1Wu2h&2g?@csgmdyYxApox0cvKgGN9ls5#> Zjtrv}`C$~R9{7PDw~U#Y8@HE?{{Z{QARhn# delta 7940 zcmdU!&1)n@7{LgGUihtIWl}Kn3;aLGd7>2i>a(yYa1>sZ4csXB2t|CL!eG?W(S~ z>Q~RxZ`XYI`^8TmTCYkuCcmy>w2U5yg-%0gUiH=<^WD)1wT zP=zw*Rm-jYkLjrhGBCXE)FpGWphbQMFZc&FWHw&XYn61Crqnl&-5M}2PH|7NOF zdrf5Dg6W10H4moEW6;5a(28~V^!HP=o9`g5$^{_m7QS|i{!%Q*4iy58Xk| zoa6L=1eDBC2Qkj(C`IdH^34In6o5V zU5!$>w+)~NOMPA3aKJ&fT532*kXo@|LHgeVenBqjEWbX!=O=)li!ld&e{cWMna$(i z+B^pQFf8>5fbw#dAl5Zf0-;DIi?9p-mPaUHkTjUOw#&d2*^C8d|4Ct5D-r&q zw(?}d#N4M`!hE^+)B96T-YS4ebaNcQB*J=5en!g6S&JpQzDvNA*^C3Gq?T7EQ6_T= zl*uSmSUqsr{d+|mb#GK0N7p(;+0syyM3;6Mj=6H@F*&RRR=`pDOKFbXaX&1nLkSht z+MrTJb5|}MJ=%V7baeDEK050CxqjxykBb27emMZ_j;@8|<*ZO$UG8N7=Zc}n1-Q5x za{sd$nxIFhL;9{e+xrY&fjR{+UEMDg%+d9btE_6MR#(@2379gQak#FemRGB*jHk3( z$NzfC1J99<&-pH~ z{ruP2gAWQgQr#N|9O>v%NM6o5EY+o5f}_l49HNxK3OFi%IR&C5#0{hf;qY#qRN(rqNKXC%fK90Jp`vrMTZAe`ODH01Mb6mBLq?T7EJ3X}za|!mPGGFLjS$yK_?+Rct-5?dr(X|g#-ZWGu z)Ad~frp#s>HY=$Wz*HtP`N|~3;l9=TeER&IB8O$VH!6;!%O0j|N#m$Xy9~#1l|8Kg z(8wJF<*J@an1(xXO`P%9;27WSy9D$boXP9kemK#Vc;9TpM*^5y_Racc3(ouxzPvGI z9sF~t3kUwg{(DKZWjP4SQRnyzd5pnZz}8d47z``EP_rMS@T~M;*^L;*uwHsh{LMjA zdaUaZ&*$K?dJtkkU^IjncVK?mcD@ssF&0p6Bm?%(IOsdmmjxai(ss?DpKIuOL2h6V zk};Ep7&cbMfnv}BYt0PIA(`XJbqC7|?*KgC&=;R87@Y$%L5u@$ z2qV@z6XLs$u`(iNa)(%M6GF_>&~@dmCd~JIW4R#a`^KgbF>b5^#B$3@I1W6sFYFG_ zOq#>`2L?OB3HFRZTueP|>}rVl=2DB8c#GFp3u4@qqDz@C4pim(tL2AaAPzAzogpS{ zCL8k{aX_1iaZXLfF6Uq!xppw}Fedp!L*HZ!rs8pM{*KLuK? t??=MS;A59KMKG#3#9wM|#YmKC^1(UXO2Z_Tz6W<=9=B#@Zron9{skDpeN+Gd diff --git a/src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1207Test.cs b/src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1207Test.cs new file mode 100644 index 0000000..7d13e3d --- /dev/null +++ b/src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1207Test.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using JT809.Protocol; +using JT809.Protocol.JT809Extensions; +using JT809.Protocol.JT809MessageBody; +using JT809.Protocol.JT809Exceptions; +using JT809.Protocol.JT809SubMessageBody; + +namespace JT809.Protocol.Test.JT809SubMessageBody +{ + public class JT809_0x1200_0x1207Test + { + [Fact] + public void Test1() + { + JT809_0x1200_0x1207 jT809_0X1200_0X1201 = new JT809_0x1200_0x1207 + { + StartTime = DateTime.Parse("2018-09-24 14:14:14"), + EndTime = DateTime.Parse("2018-09-24 23:23:23") + }; + var hex = JT809Serializer.Serialize(jT809_0X1200_0X1201).ToHexString(); + //"00 00 00 00 5B A8 80 B6 00 00 00 00 5B A9 01 6B" + } + + [Fact] + public void Test2() + { + var bytes = "00 00 00 00 5B A8 80 B6 00 00 00 00 5B A9 01 6B".ToHexBytes(); + JT809_0x1200_0x1207 jT809_0X1200_0X1201 = JT809Serializer.Deserialize(bytes); + Assert.Equal(DateTime.Parse("2018-09-24 14:14:14"), jT809_0X1200_0X1201.StartTime); + Assert.Equal(DateTime.Parse("2018-09-24 23:23:23"), jT809_0X1200_0X1201.EndTime); + } + } +} diff --git a/src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs b/src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs index 5fa67da..2d67fc8 100644 --- a/src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs +++ b/src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs @@ -32,16 +32,19 @@ namespace JT809.Protocol.JT809Enums ///启动车辆定位信息交换应答 /// [Description("启动车辆定位信息交换应答")] + [JT809BodiesType(typeof(JT809_0x1200_0x1205))] UP_EXG_MSG_RETURN_STARTUP_ACK = 0x1205, /// ///结束车辆定位信息交换应答 /// [Description("结束车辆定位信息交换应答")] + [JT809BodiesType(typeof(JT809_0x1200_0x1206))] UP_EXG_MSG_RETURN_END_ACK = 0x1206, /// ///申请交换指定车辆定位信息请求 /// [Description("申请交换指定车辆定位信息请求")] + [JT809BodiesType(typeof(JT809_0x1200_0x1207))] UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP = 0x1207, /// ///取消交换指定车辆定位信息请求 diff --git a/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs b/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs index d6a4cc6..a5177d3 100644 --- a/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs +++ b/src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs @@ -18,6 +18,8 @@ namespace JT809.Protocol.JT809Extensions private static ulong[] CRC = new ulong[256]; //建立CRC16表 + private static readonly DateTime UTCBaseTime = new DateTime(1970, 1, 1); + static JT809BinaryExtensions() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); @@ -117,6 +119,18 @@ namespace JT809.Protocol.JT809Extensions return dateTime; } + public static DateTime ReadUTCDateTimeLittle(ReadOnlySpan buf, ref int offset) + { + ulong result = 0; + for (int i = 0; i < 8; i++) + { + ulong currentData = (ulong)buf[offset+i] << (8 * (8 - i - 1)); + result += currentData; + } + offset += 8; + return UTCBaseTime.AddSeconds(result).AddHours(8); + } + 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]; @@ -367,6 +381,18 @@ namespace JT809.Protocol.JT809Extensions return len; } + public static int WriteUTCDateTimeLittle(IMemoryOwner memoryOwner, int offset, DateTime date) + { + ulong totalSecends = (ulong)(date.AddHours(-8) - UTCBaseTime).TotalSeconds; + //高位在前 + for (int i = 7; i >= 0; i--) + { + memoryOwner.Memory.Span[offset+i] = (byte)(totalSecends & 0xFF); //取低8位 + totalSecends = totalSecends >> 8; + } + return 8; + } + public static IEnumerable ToBytes(this string data, Encoding coding) { return coding.GetBytes(data); diff --git a/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1207Formatter.cs b/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1207Formatter.cs new file mode 100644 index 0000000..2c489c0 --- /dev/null +++ b/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1207Formatter.cs @@ -0,0 +1,29 @@ +using JT809.Protocol.JT809Extensions; +using JT809.Protocol.JT809SubMessageBody; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809Formatters.JT809SubMessageBodyFormatters +{ + public class JT809_0x1200_0x1207Formatter : IJT809Formatter + { + public JT809_0x1200_0x1207 Deserialize(ReadOnlySpan bytes, out int readSize) + { + int offset = 0; + JT809_0x1200_0x1207 jT809_0X1200_0X1207 = new JT809_0x1200_0x1207(); + jT809_0X1200_0X1207.StartTime = JT809BinaryExtensions.ReadUTCDateTimeLittle(bytes, ref offset); + jT809_0X1200_0X1207.EndTime = JT809BinaryExtensions.ReadUTCDateTimeLittle(bytes, ref offset); + readSize = offset; + return jT809_0X1200_0X1207; + } + + public int Serialize(IMemoryOwner memoryOwner, int offset, JT809_0x1200_0x1207 value) + { + offset += JT809BinaryExtensions.WriteUTCDateTimeLittle(memoryOwner, offset, value.StartTime); + offset += JT809BinaryExtensions.WriteUTCDateTimeLittle(memoryOwner, offset, value.EndTime); + return offset; + } + } +} diff --git a/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1205.cs b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1205.cs new file mode 100644 index 0000000..a846a94 --- /dev/null +++ b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1205.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809SubMessageBody +{ + /// + /// 启动车辆定位信息交换应答消息 + /// 子业务类型标识:UP_EXG_ MSG_ RETURN_ STARTUP ACK + /// 描述:本条消息是下级平台对上级平台下发的 DOWN_EXG_ MSG_ RETURN_STARTUP 消息的应答消息 + /// + public class JT809_0x1200_0x1205:JT809SubBodies + { + + } +} diff --git a/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1206.cs b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1206.cs new file mode 100644 index 0000000..86fa0a0 --- /dev/null +++ b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1206.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809SubMessageBody +{ + /// + /// 结束车辆定位信息交换应答消息 + /// 子业务类型标识:UP_EXG_MSG_RETURN_END_ACK + /// + public class JT809_0x1200_0x1206:JT809SubBodies + { + } +} diff --git a/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1207.cs b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1207.cs new file mode 100644 index 0000000..f484eb0 --- /dev/null +++ b/src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1207.cs @@ -0,0 +1,26 @@ +using JT809.Protocol.JT809Attributes; +using JT809.Protocol.JT809Formatters.JT809SubMessageBodyFormatters; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT809.Protocol.JT809SubMessageBody +{ + /// + /// 申请交换指定车辆定位信息请求消息 + /// 子业务类型标识:UP_EXG_MSG_APPLY-FOR_MONITOR_STARTUP + /// 描述:当下级平台需要在特定时问段内监控特殊车辆时,可上传此命令到上级平台申请对该车辆定位数据交换到下级平台,申请成功后,此车辆定位数据将在指定时间内交换到该平台(即使该车没有进入该平台所属区域也会交换) + /// + [JT809Formatter(typeof(JT809_0x1200_0x1207Formatter))] + public class JT809_0x1200_0x1207:JT809SubBodies + { + /// + /// 开始时间,用 UTC 时间表示 + /// + public DateTime StartTime { get; set; } + /// + /// 结束时间,用 UTC 时间表示 + /// + public DateTime EndTime { get; set; } + } +}