@@ -46,4 +46,7 @@ | |||||
| 1 | 0x1200 | √ | 主链路动态信息交换消息 | | | 1 | 0x1200 | √ | 主链路动态信息交换消息 | | ||||
| 2 | 0x1201 | √ | 上传车辆注册信息 | | | 2 | 0x1201 | √ | 上传车辆注册信息 | | ||||
| 3 | 0x1202 | √ | 实时上传车辆定位信息 | | | 3 | 0x1202 | √ | 实时上传车辆定位信息 | | ||||
| 4 | 0x1203 | √ | 车辆定位信息自动补报 | | |||||
| 4 | 0x1203 | √ | 车辆定位信息自动补报 | | |||||
| 5 | 0x1205 | √ | 启动车辆定位信息交换应答消息 | | |||||
| 6 | 0x1206 | √ | 结束车辆定位信息交换应答消息 | | |||||
| 7 | 0x1207 | √ | 申请交换指定车辆定位信息请求消息 | |
@@ -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<JT809_0x1200_0x1207>(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); | |||||
} | |||||
} | |||||
} |
@@ -32,16 +32,19 @@ namespace JT809.Protocol.JT809Enums | |||||
///启动车辆定位信息交换应答 | ///启动车辆定位信息交换应答 | ||||
///</summary> | ///</summary> | ||||
[Description("启动车辆定位信息交换应答")] | [Description("启动车辆定位信息交换应答")] | ||||
[JT809BodiesType(typeof(JT809_0x1200_0x1205))] | |||||
UP_EXG_MSG_RETURN_STARTUP_ACK = 0x1205, | UP_EXG_MSG_RETURN_STARTUP_ACK = 0x1205, | ||||
///<summary> | ///<summary> | ||||
///结束车辆定位信息交换应答 | ///结束车辆定位信息交换应答 | ||||
///</summary> | ///</summary> | ||||
[Description("结束车辆定位信息交换应答")] | [Description("结束车辆定位信息交换应答")] | ||||
[JT809BodiesType(typeof(JT809_0x1200_0x1206))] | |||||
UP_EXG_MSG_RETURN_END_ACK = 0x1206, | UP_EXG_MSG_RETURN_END_ACK = 0x1206, | ||||
///<summary> | ///<summary> | ||||
///申请交换指定车辆定位信息请求 | ///申请交换指定车辆定位信息请求 | ||||
///</summary> | ///</summary> | ||||
[Description("申请交换指定车辆定位信息请求")] | [Description("申请交换指定车辆定位信息请求")] | ||||
[JT809BodiesType(typeof(JT809_0x1200_0x1207))] | |||||
UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP = 0x1207, | UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP = 0x1207, | ||||
///<summary> | ///<summary> | ||||
///取消交换指定车辆定位信息请求 | ///取消交换指定车辆定位信息请求 | ||||
@@ -18,6 +18,8 @@ namespace JT809.Protocol.JT809Extensions | |||||
private static ulong[] CRC = new ulong[256]; //建立CRC16表 | private static ulong[] CRC = new ulong[256]; //建立CRC16表 | ||||
private static readonly DateTime UTCBaseTime = new DateTime(1970, 1, 1); | |||||
static JT809BinaryExtensions() | static JT809BinaryExtensions() | ||||
{ | { | ||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | ||||
@@ -117,6 +119,18 @@ namespace JT809.Protocol.JT809Extensions | |||||
return dateTime; | return dateTime; | ||||
} | } | ||||
public static DateTime ReadUTCDateTimeLittle(ReadOnlySpan<byte> 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<byte> read, ref int offset) | public static int ReadInt32Little(ReadOnlySpan<byte> 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]; | ||||
@@ -367,6 +381,18 @@ namespace JT809.Protocol.JT809Extensions | |||||
return len; | return len; | ||||
} | } | ||||
public static int WriteUTCDateTimeLittle(IMemoryOwner<byte> 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<byte> ToBytes(this string data, Encoding coding) | public static IEnumerable<byte> ToBytes(this string data, Encoding coding) | ||||
{ | { | ||||
return coding.GetBytes(data); | return coding.GetBytes(data); | ||||
@@ -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<JT809_0x1200_0x1207> | |||||
{ | |||||
public JT809_0x1200_0x1207 Deserialize(ReadOnlySpan<byte> 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<byte> memoryOwner, int offset, JT809_0x1200_0x1207 value) | |||||
{ | |||||
offset += JT809BinaryExtensions.WriteUTCDateTimeLittle(memoryOwner, offset, value.StartTime); | |||||
offset += JT809BinaryExtensions.WriteUTCDateTimeLittle(memoryOwner, offset, value.EndTime); | |||||
return offset; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.JT809SubMessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 启动车辆定位信息交换应答消息 | |||||
/// <para>子业务类型标识:UP_EXG_ MSG_ RETURN_ STARTUP ACK</para> | |||||
/// <para>描述:本条消息是下级平台对上级平台下发的 DOWN_EXG_ MSG_ RETURN_STARTUP 消息的应答消息</para> | |||||
/// </summary> | |||||
public class JT809_0x1200_0x1205:JT809SubBodies | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.JT809SubMessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 结束车辆定位信息交换应答消息 | |||||
/// <para>子业务类型标识:UP_EXG_MSG_RETURN_END_ACK</para> | |||||
/// </summary> | |||||
public class JT809_0x1200_0x1206:JT809SubBodies | |||||
{ | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 申请交换指定车辆定位信息请求消息 | |||||
/// <para>子业务类型标识:UP_EXG_MSG_APPLY-FOR_MONITOR_STARTUP</para> | |||||
/// <para>描述:当下级平台需要在特定时问段内监控特殊车辆时,可上传此命令到上级平台申请对该车辆定位数据交换到下级平台,申请成功后,此车辆定位数据将在指定时间内交换到该平台(即使该车没有进入该平台所属区域也会交换)</para> | |||||
/// </summary> | |||||
[JT809Formatter(typeof(JT809_0x1200_0x1207Formatter))] | |||||
public class JT809_0x1200_0x1207:JT809SubBodies | |||||
{ | |||||
/// <summary> | |||||
/// 开始时间,用 UTC 时间表示 | |||||
/// </summary> | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | |||||
/// 结束时间,用 UTC 时间表示 | |||||
/// </summary> | |||||
public DateTime EndTime { get; set; } | |||||
} | |||||
} |