@@ -23,9 +23,9 @@ | |||||
### 数据头[JT809Header] | ### 数据头[JT809Header] | ||||
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙| | |||||
|:------:|:------:|:------:|:------:|:------:|:------:|:------:| | |||||
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey | | |||||
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙|发送消息的系统时间(2019版本)| | |||||
|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:| | |||||
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey |Time| | |||||
### 数据体[JT809Bodies] | ### 数据体[JT809Bodies] | ||||
@@ -17,8 +17,8 @@ namespace JT809.Protocol.Test.JT809MessageBody | |||||
{ | { | ||||
JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); | JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); | ||||
jT809_0X9101.DynamicInfoTotal = 10000; | jT809_0X9101.DynamicInfoTotal = 10000; | ||||
jT809_0X9101.StartTime = 1537513862; | |||||
jT809_0X9101.EndTime = 1537531862; | |||||
jT809_0X9101.StartTime = DateTime.Parse("2018-09-21 15:11:02"); | |||||
jT809_0X9101.EndTime = DateTime.Parse("2018-09-21 20:11:02"); | |||||
var hex = JT809Serializer.Serialize(jT809_0X9101).ToHexString(); | var hex = JT809Serializer.Serialize(jT809_0X9101).ToHexString(); | ||||
Assert.Equal("00002710000000005BA49986000000005BA4DFD6",hex); | Assert.Equal("00002710000000005BA49986000000005BA4DFD6",hex); | ||||
} | } | ||||
@@ -29,8 +29,8 @@ namespace JT809.Protocol.Test.JT809MessageBody | |||||
var bytes = "00 00 27 10 00 00 00 00 5B A4 99 86 00 00 00 00 5B A4 DF D6".ToHexBytes(); | 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<JT809_0x9101>(bytes); | JT809_0x9101 jT809_0X9101 = JT809Serializer.Deserialize<JT809_0x9101>(bytes); | ||||
Assert.Equal((uint)10000, jT809_0X9101.DynamicInfoTotal); | Assert.Equal((uint)10000, jT809_0X9101.DynamicInfoTotal); | ||||
Assert.Equal((ulong)1537513862, jT809_0X9101.StartTime); | |||||
Assert.Equal((ulong)1537531862, jT809_0X9101.EndTime); | |||||
Assert.Equal(DateTime.Parse("2018-09-21 15:11:02"), jT809_0X9101.StartTime); | |||||
Assert.Equal(DateTime.Parse("2018-09-21 20:11:02"), jT809_0X9101.EndTime); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -151,6 +151,46 @@ namespace JT809.Protocol.Enums | |||||
[JT809BodiesType(typeof(JT809_0x9101))] | [JT809BodiesType(typeof(JT809_0x9101))] | ||||
[JT809BusinessTypeDescription("DOWN_TOTAL_RECV_BACK_MSG", "接收车辆定位信息数量通知消息")] | [JT809BusinessTypeDescription("DOWN_TOTAL_RECV_BACK_MSG", "接收车辆定位信息数量通知消息")] | ||||
接收车辆定位信息数量通知消息 = 0x9101, | 接收车辆定位信息数量通知消息 = 0x9101, | ||||
///<summary> | |||||
///发送车辆定位信息数据量通知消息_2019 | |||||
///DOWN_TOTAL_RECV_BACK_MSG | |||||
///</summary> | |||||
[Description("接收车辆定位信息数量通知消息")] | |||||
[JT809BodiesType(typeof(JT809_2019_0x9101))] | |||||
[JT809BusinessTypeDescription("DOWN_TOTAL_RECV_BACK_MSG", "发送车辆定位信息数据量通知消息")] | |||||
发送车辆定位信息数据量通知消息_2019 = 0x9101, | |||||
///<summary> | |||||
///发送车辆定位信息数据量通知消息_2019 | |||||
///DOWN_TOTAL_RECV_BACK_MSG | |||||
///</summary> | |||||
[Description("平台链路连接情况与车辆定位消息传输情况上报请求消息")] | |||||
[JT809BodiesType(typeof(JT809_0x9102))] | |||||
[JT809BusinessTypeDescription("DOWN_MANAGE_MSG_REQ", "平台链路连接情况与车辆定位消息传输情况上报请求消息")] | |||||
平台链路连接情况与车辆定位消息传输情况上报请求消息_2019 = 0x9102, | |||||
///<summary> | |||||
///发送车辆定位信息数据量通知消息_2019 | |||||
///UP_MANAGE_MSG_RSP | |||||
///</summary> | |||||
[Description("平台链路连接情况与车辆定位消息传输情况上报应答消息")] | |||||
[JT809BodiesType(typeof(JT809_0x1102))] | |||||
[JT809BusinessTypeDescription("UP_MANAGE_MSG_RSP", "平台链路连接情况与车辆定位消息传输情况上报应答消息")] | |||||
平台链路连接情况与车辆定位消息传输情况上报应答消息_2019 = 0x1102, | |||||
///<summary> | |||||
///上传平台间消息序列号通知消息 | |||||
///UP_MANAGE_MSG_SN_INFORM | |||||
///</summary> | |||||
[Description("上传平台间消息序列号通知消息")] | |||||
[JT809BodiesType(typeof(JT809_0x1102))] | |||||
[JT809BusinessTypeDescription("UP_MANAGE_MSG_SN_INFORM", "上传平台间消息序列号通知消息")] | |||||
上传平台间消息序列号通知消息_2019 = 0x1103, | |||||
///<summary> | |||||
///下发平台间消息序列号通知消息 | |||||
///UP_MANAGE_MSG_SN_INFORM | |||||
///</summary> | |||||
[Description("下发平台间消息序列号通知消息")] | |||||
[JT809BodiesType(typeof(JT809_0x1102))] | |||||
[JT809BusinessTypeDescription("DOWN_MANAGE_MSG_SN_INFORM", "下发平台间消息序列号通知消息")] | |||||
下发平台间消息序列号通知消息_2019 = 0x9103, | |||||
#endregion | #endregion | ||||
#region 车辆动态信息交换 | #region 车辆动态信息交换 | ||||
///<summary> | ///<summary> | ||||
@@ -15,6 +15,7 @@ namespace JT809.Protocol.Enums | |||||
用户没用注册=0x03, | 用户没用注册=0x03, | ||||
密码错误=0x04, | 密码错误=0x04, | ||||
资源紧张_稍后再连接_已经占用= 0x05, | 资源紧张_稍后再连接_已经占用= 0x05, | ||||
其他 =0x06 | |||||
其他 =0x06, | |||||
其他_2019 = 0xFF | |||||
} | } | ||||
} | } |
@@ -1,4 +1,5 @@ | |||||
using System; | |||||
using JT809.Protocol.Enums; | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
namespace JT809.Protocol.Interfaces | namespace JT809.Protocol.Interfaces | ||||
@@ -6,7 +7,8 @@ namespace JT809.Protocol.Interfaces | |||||
public interface IJT809BusinessTypeFactory : IJT809ExternalRegister | public interface IJT809BusinessTypeFactory : IJT809ExternalRegister | ||||
{ | { | ||||
IDictionary<ushort, object> Map { get; } | IDictionary<ushort, object> Map { get; } | ||||
bool TryGetValue(ushort msgId, out object instance); | |||||
IDictionary<ushort, object> Map_2019 { get; } | |||||
bool TryGetValue(ushort msgId, JT809Version version , out object instance); | |||||
IJT809BusinessTypeFactory SetMap<TJT809Bodies>() where TJT809Bodies : JT809Bodies; | IJT809BusinessTypeFactory SetMap<TJT809Bodies>() where TJT809Bodies : JT809Bodies; | ||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
using JT808.Protocol.Formatters; | using JT808.Protocol.Formatters; | ||||
using JT809.Protocol.Configs; | using JT809.Protocol.Configs; | ||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Interfaces; | using JT809.Protocol.Interfaces; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
@@ -40,6 +41,7 @@ namespace JT809.Protocol | |||||
IJT809BusinessTypeFactory BusinessTypeFactory { get; set; } | IJT809BusinessTypeFactory BusinessTypeFactory { get; set; } | ||||
IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set; } | IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set; } | ||||
IJT809FormatterFactory FormatterFactory { get; set; } | IJT809FormatterFactory FormatterFactory { get; set; } | ||||
JT809Version Version { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// 全局注册外部程序集 | /// 全局注册外部程序集 | ||||
/// </summary> | /// </summary> | ||||
@@ -2,6 +2,7 @@ | |||||
using JT808.Protocol.Internal; | using JT808.Protocol.Internal; | ||||
using JT809.Protocol.Configs; | using JT809.Protocol.Configs; | ||||
using JT809.Protocol.Encrypt; | using JT809.Protocol.Encrypt; | ||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Internal; | using JT809.Protocol.Internal; | ||||
using System; | using System; | ||||
using System.Reflection; | using System.Reflection; | ||||
@@ -11,13 +12,14 @@ namespace JT809.Protocol.Interfaces | |||||
{ | { | ||||
public abstract class JT809GlobalConfigBase : IJT809Config | public abstract class JT809GlobalConfigBase : IJT809Config | ||||
{ | { | ||||
protected JT809GlobalConfigBase() | |||||
protected JT809GlobalConfigBase(JT809Version version= JT809Version.JTT2013) | |||||
{ | { | ||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | ||||
Encoding = Encoding.GetEncoding("GBK"); | Encoding = Encoding.GetEncoding("GBK"); | ||||
BusinessTypeFactory = new JT809BusinessTypeFactory(); | BusinessTypeFactory = new JT809BusinessTypeFactory(); | ||||
SubBusinessTypeFactory = new JT809SubBusinessTypeFactory(); | SubBusinessTypeFactory = new JT809SubBusinessTypeFactory(); | ||||
FormatterFactory = new JT809FormatterFactory(); | FormatterFactory = new JT809FormatterFactory(); | ||||
Version = version; | |||||
} | } | ||||
public abstract string ConfigId { get; } | public abstract string ConfigId { get; } | ||||
public virtual IJT809MsgSNDistributed MsgSNDistributed { get; set; }= new DefaultMsgSNDistributedImpl(); | public virtual IJT809MsgSNDistributed MsgSNDistributed { get; set; }= new DefaultMsgSNDistributedImpl(); | ||||
@@ -29,6 +31,8 @@ namespace JT809.Protocol.Interfaces | |||||
public IJT809BusinessTypeFactory BusinessTypeFactory { get ; set ; } | public IJT809BusinessTypeFactory BusinessTypeFactory { get ; set ; } | ||||
public IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set ; } | public IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set ; } | ||||
public IJT809FormatterFactory FormatterFactory { get; set; } | public IJT809FormatterFactory FormatterFactory { get; set; } | ||||
public JT809Version Version { get; set; } | |||||
public virtual IJT809Config Register(params Assembly[] externalAssemblies) | public virtual IJT809Config Register(params Assembly[] externalAssemblies) | ||||
{ | { | ||||
if (externalAssemblies != null) | if (externalAssemblies != null) | ||||
@@ -14,15 +14,17 @@ namespace JT808.Protocol.Internal | |||||
{ | { | ||||
public IDictionary<ushort, object> Map { get; } | public IDictionary<ushort, object> Map { get; } | ||||
public IDictionary<ushort, object> Map_2019 { get; } | |||||
internal JT809BusinessTypeFactory() | internal JT809BusinessTypeFactory() | ||||
{ | { | ||||
Map = new Dictionary<ushort, object>(); | Map = new Dictionary<ushort, object>(); | ||||
Map_2019 = new Dictionary<ushort, object>(); | |||||
InitMap(Assembly.GetExecutingAssembly()); | InitMap(Assembly.GetExecutingAssembly()); | ||||
} | } | ||||
private void InitMap(Assembly assembly) | private void InitMap(Assembly assembly) | ||||
{ | { | ||||
// var types = assembly.GetTypes().Where(w => w.BaseType == typeof(JT809Bodies)).Where(w=>w != typeof(JT809ExchangeMessageBodies)).ToList(); | |||||
var types = assembly.GetTypes() | var types = assembly.GetTypes() | ||||
.Where(w => w.BaseType == typeof(JT809Bodies) || w.BaseType == typeof(JT809ExchangeMessageBodies)).ToList(); | .Where(w => w.BaseType == typeof(JT809Bodies) || w.BaseType == typeof(JT809ExchangeMessageBodies)).ToList(); | ||||
foreach (var type in types) | foreach (var type in types) | ||||
@@ -30,17 +32,37 @@ namespace JT808.Protocol.Internal | |||||
if (type.Name == nameof(JT809ExchangeMessageBodies)) continue; | if (type.Name == nameof(JT809ExchangeMessageBodies)) continue; | ||||
var instance = Activator.CreateInstance(type); | var instance = Activator.CreateInstance(type); | ||||
ushort msgId = 0; | ushort msgId = 0; | ||||
JT809Version version; | |||||
try | try | ||||
{ | { | ||||
msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | ||||
version = (JT809Version)type.GetProperty(nameof(JT809Bodies.Version)).GetValue(instance); | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
continue; | continue; | ||||
} | } | ||||
if (Map_2019.ContainsKey(msgId)) | |||||
{ | |||||
if (version == JT809Version.JTT2019) | |||||
{ | |||||
Map_2019[msgId] = instance; | |||||
} | |||||
else | |||||
{ | |||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Map_2019.Add(msgId, instance); | |||||
} | |||||
if (Map.ContainsKey(msgId)) | if (Map.ContainsKey(msgId)) | ||||
{ | { | ||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
if (version != JT809Version.JTT2019) | |||||
{ | |||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -49,24 +71,38 @@ namespace JT808.Protocol.Internal | |||||
} | } | ||||
} | } | ||||
public bool TryGetValue(ushort msgId, out object instance) | |||||
{ | |||||
return Map.TryGetValue(msgId, out instance); | |||||
} | |||||
public IJT809BusinessTypeFactory SetMap<TJT809Bodies>() where TJT809Bodies : JT809Bodies | public IJT809BusinessTypeFactory SetMap<TJT809Bodies>() where TJT809Bodies : JT809Bodies | ||||
{ | { | ||||
Type type = typeof(TJT809Bodies); | Type type = typeof(TJT809Bodies); | ||||
var instance = Activator.CreateInstance(type); | var instance = Activator.CreateInstance(type); | ||||
var msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | var msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | ||||
JT809Version version = (JT809Version)type.GetProperty(nameof(JT809Bodies.Version)).GetValue(instance); | |||||
if (Map.ContainsKey(msgId)) | if (Map.ContainsKey(msgId)) | ||||
{ | { | ||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
if (version != JT809Version.JTT2019) | |||||
{ | |||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
Map.Add(msgId, instance); | Map.Add(msgId, instance); | ||||
} | } | ||||
if (Map_2019.ContainsKey(msgId)) | |||||
{ | |||||
if (version == JT809Version.JTT2019) | |||||
{ | |||||
Map_2019[msgId] = instance; | |||||
} | |||||
else | |||||
{ | |||||
throw new ArgumentException($"{type.FullName} {msgId} An element with the same key already exists."); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Map_2019.Add(msgId, instance); | |||||
} | |||||
return this; | return this; | ||||
} | } | ||||
@@ -74,5 +110,17 @@ namespace JT808.Protocol.Internal | |||||
{ | { | ||||
InitMap(externalAssembly); | InitMap(externalAssembly); | ||||
} | } | ||||
public bool TryGetValue(ushort msgId, JT809Version version, out object instance) | |||||
{ | |||||
if(version== JT809Version.JTT2019) | |||||
{ | |||||
return Map_2019.TryGetValue(msgId, out instance); | |||||
} | |||||
else | |||||
{ | |||||
return Map.TryGetValue(msgId, out instance); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -11,11 +11,9 @@ namespace JT809.Protocol | |||||
/// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | /// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | ||||
/// </summary> | /// </summary> | ||||
public virtual bool SkipSerialization { get; set; } = false; | public virtual bool SkipSerialization { get; set; } = false; | ||||
public virtual JT809Version Version => JT809Version.JTT2013; | |||||
public abstract ushort MsgId { get; } | public abstract ushort MsgId { get; } | ||||
public abstract JT809_LinkType LinkType { get; } | public abstract JT809_LinkType LinkType { get; } | ||||
public abstract string Description { get; } | public abstract string Description { get; } | ||||
} | } | ||||
} | } |
@@ -1,5 +1,7 @@ | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | using JT809.Protocol.MessagePack; | ||||
using System; | |||||
namespace JT809.Protocol | namespace JT809.Protocol | ||||
{ | { | ||||
@@ -12,6 +14,12 @@ namespace JT809.Protocol | |||||
/// </summary> | /// </summary> | ||||
public const int FixedByteLength = 22; | public const int FixedByteLength = 22; | ||||
/// <summary> | /// <summary> | ||||
/// 2019版本固定为30个字节长度 | |||||
/// <para>MSG LENGTH + MSG_SN + MSG_ID + MSG_GNSSCENTERID + VERSION_FLAG + ENCRYPT_FLAG + ENCRYPT_KEY+TIME</para> | |||||
/// <para>4 + 4 + 2 + 4 + 3 + 1 + 4 +8 = 30</para> | |||||
/// </summary> | |||||
public const int FixedByteLength_2019 = 30; | |||||
/// <summary> | |||||
/// 数据长度(包括头标识、数据头、数据体和尾标识) | /// 数据长度(包括头标识、数据头、数据体和尾标识) | ||||
/// <para>头标识 + 数据头 + 数据体 + 尾标识</para> | /// <para>头标识 + 数据头 + 数据体 + 尾标识</para> | ||||
/// <para>1 + 22 + n + 1</para> | /// <para>1 + 22 + n + 1</para> | ||||
@@ -44,6 +52,10 @@ namespace JT809.Protocol | |||||
/// 数据加密的密匙,长度为 4 个字节 | /// 数据加密的密匙,长度为 4 个字节 | ||||
/// </summary> | /// </summary> | ||||
public uint EncryptKey { get; set; } | public uint EncryptKey { get; set; } | ||||
/// <summary> | |||||
/// 发送消息时的系统UTC时间,长度为8个字节 | |||||
/// </summary> | |||||
public DateTime Time { get; set; } = DateTime.Now; | |||||
public JT809Header Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | public JT809Header Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | ||||
{ | { | ||||
@@ -55,6 +67,10 @@ namespace JT809.Protocol | |||||
jT809Header.Version = new JT809Header_Version(reader.ReadArray(JT809Header_Version.FixedByteLength)); | jT809Header.Version = new JT809Header_Version(reader.ReadArray(JT809Header_Version.FixedByteLength)); | ||||
jT809Header.EncryptFlag = (JT809Header_Encrypt)reader.ReadByte(); | jT809Header.EncryptFlag = (JT809Header_Encrypt)reader.ReadByte(); | ||||
jT809Header.EncryptKey = reader.ReadUInt32(); | jT809Header.EncryptKey = reader.ReadUInt32(); | ||||
if(config.Version== JT809Version.JTT2019) | |||||
{ | |||||
Time = reader.ReadUTCDateTime(); | |||||
} | |||||
return jT809Header; | return jT809Header; | ||||
} | } | ||||
@@ -67,6 +83,10 @@ namespace JT809.Protocol | |||||
writer.WriteArray(value.Version.Buffer); | writer.WriteArray(value.Version.Buffer); | ||||
writer.WriteByte((byte)value.EncryptFlag); | writer.WriteByte((byte)value.EncryptFlag); | ||||
writer.WriteUInt32(value.EncryptKey); | writer.WriteUInt32(value.EncryptKey); | ||||
if (config.Version == JT809Version.JTT2019) | |||||
{ | |||||
writer.WriteUTCDateTime(value.Time); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -2,12 +2,13 @@ | |||||
using JT809.Protocol.Exceptions; | using JT809.Protocol.Exceptions; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using JT809.Protocol.Formatters; | using JT809.Protocol.Formatters; | ||||
using JT809.Protocol.Interfaces; | |||||
using JT809.Protocol.MessagePack; | using JT809.Protocol.MessagePack; | ||||
using System; | using System; | ||||
namespace JT809.Protocol | namespace JT809.Protocol | ||||
{ | { | ||||
public class JT809Package:IJT809MessagePackFormatter<JT809Package> | |||||
public class JT809Package:IJT809MessagePackFormatter<JT809Package>, IJT809_2019_Version | |||||
{ | { | ||||
public const byte BEGINFLAG = 0X5B; | public const byte BEGINFLAG = 0X5B; | ||||
@@ -19,6 +20,12 @@ namespace JT809.Protocol | |||||
/// <para>1 + 22 + 2 + 1 = 26</para> | /// <para>1 + 22 + 2 + 1 = 26</para> | ||||
/// </summary> | /// </summary> | ||||
public const int FixedByteLength = 26; | public const int FixedByteLength = 26; | ||||
/// <summary> | |||||
/// 固定为26个字节长度 | |||||
/// <para>Head flag + Message Header + CRC Code + End Flag</para> | |||||
/// <para>1 + 30 + 2 + 1 = 26</para> | |||||
/// </summary> | |||||
public const int FixedByteLength_2019 = 34; | |||||
public byte BeginFlag { get; set; } = BEGINFLAG; | public byte BeginFlag { get; set; } = BEGINFLAG; | ||||
@@ -38,7 +45,7 @@ namespace JT809.Protocol | |||||
// 1.2. 验证校验码 | // 1.2. 验证校验码 | ||||
if (!reader.CheckXorCodeVali) | if (!reader.CheckXorCodeVali) | ||||
{ | { | ||||
throw new JT809Exception(JT809ErrorCode.CRC16CheckInvalid, $"{reader.CalculateCheckXorCode.ToString()}!={reader.RealCheckXorCode.ToString()}"); | |||||
throw new JT809Exception(JT809ErrorCode.CRC16CheckInvalid, $"{reader.CalculateCheckXorCode}!={reader.RealCheckXorCode}"); | |||||
} | } | ||||
} | } | ||||
JT809Package jT809Package = new JT809Package(); | JT809Package jT809Package = new JT809Package(); | ||||
@@ -52,12 +59,13 @@ namespace JT809.Protocol | |||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{reader.ReadCurrentRemainContentLength()}", ex); | throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{reader.ReadCurrentRemainContentLength()}", ex); | ||||
} | |||||
} | |||||
// 5.数据体处理 | // 5.数据体处理 | ||||
// 5.1 判断是否有数据体(总长度-固定长度)> 0 | // 5.1 判断是否有数据体(总长度-固定长度)> 0 | ||||
if ((jT809Package.Header.MsgLength - FixedByteLength) > 0) | |||||
int fixedByteLength = config.Version == JT809Version.JTT2019 ? FixedByteLength_2019 : FixedByteLength; | |||||
if ((jT809Package.Header.MsgLength - fixedByteLength) > 0) | |||||
{ | { | ||||
if (config.BusinessTypeFactory.TryGetValue(jT809Package.Header.BusinessType, out object instance)) | |||||
if (config.BusinessTypeFactory.TryGetValue(jT809Package.Header.BusinessType, config.Version, out object instance)) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -82,6 +90,7 @@ namespace JT809.Protocol | |||||
} | } | ||||
} | } | ||||
} | } | ||||
jT809Package.CRCCode = reader.CalculateCheckXorCode; | jT809Package.CRCCode = reader.CalculateCheckXorCode; | ||||
jT809Package.EndFlag = reader.ReadEnd(); | jT809Package.EndFlag = reader.ReadEnd(); | ||||
return jT809Package; | return jT809Package; | ||||
@@ -108,6 +117,11 @@ namespace JT809.Protocol | |||||
writer.WriteByte((byte)value.Header.EncryptFlag); | writer.WriteByte((byte)value.Header.EncryptFlag); | ||||
// 2.7.数据加密密钥 | // 2.7.数据加密密钥 | ||||
writer.WriteUInt32(value.Header.EncryptKey); | writer.WriteUInt32(value.Header.EncryptKey); | ||||
if(config.Version== JT809Version.JTT2019) | |||||
{ | |||||
// 2.8.UTC时间戳 | |||||
writer.WriteUTCDateTime(value.Header.Time); | |||||
} | |||||
// 3.写入数据体 | // 3.写入数据体 | ||||
// 3.1.记录当前开始位置 | // 3.1.记录当前开始位置 | ||||
int startIndex = writer.GetCurrentPosition(); | int startIndex = writer.GetCurrentPosition(); | ||||
@@ -1,6 +1,7 @@ | |||||
using JT809.Protocol.Enums; | using JT809.Protocol.Enums; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using JT809.Protocol.Formatters; | using JT809.Protocol.Formatters; | ||||
using JT809.Protocol.Interfaces; | |||||
using JT809.Protocol.MessagePack; | using JT809.Protocol.MessagePack; | ||||
@@ -13,7 +14,7 @@ namespace JT809.Protocol.MessageBody | |||||
/// <para>业务数据类型标识: UP-CONNECT-REQ</para> | /// <para>业务数据类型标识: UP-CONNECT-REQ</para> | ||||
/// <para>描述:下级平台向上级平台发送用户名和密码等登录信息</para> | /// <para>描述:下级平台向上级平台发送用户名和密码等登录信息</para> | ||||
/// </summary> | /// </summary> | ||||
public class JT809_0x1001: JT809Bodies,IJT809MessagePackFormatter<JT809_0x1001> | |||||
public class JT809_0x1001: JT809Bodies,IJT809MessagePackFormatter<JT809_0x1001>, IJT809_2019_Version | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// 用户名 | /// 用户名 | ||||
@@ -25,6 +26,10 @@ namespace JT809.Protocol.MessageBody | |||||
/// </summary> | /// </summary> | ||||
public string Password { get; set; } | public string Password { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// 下级平台接入码 | |||||
/// </summary> | |||||
public uint MsgGNSSCENTERID { get; set; } | |||||
/// <summary> | |||||
/// 下级平台提供对应的从链路服务端 IP 地址 | /// 下级平台提供对应的从链路服务端 IP 地址 | ||||
/// 32位 | /// 32位 | ||||
/// </summary> | /// </summary> | ||||
@@ -45,6 +50,10 @@ namespace JT809.Protocol.MessageBody | |||||
JT809_0x1001 jT809_0X1001 = new JT809_0x1001(); | JT809_0x1001 jT809_0X1001 = new JT809_0x1001(); | ||||
jT809_0X1001.UserId = reader.ReadUInt32(); | jT809_0X1001.UserId = reader.ReadUInt32(); | ||||
jT809_0X1001.Password = reader.ReadString(8); | jT809_0X1001.Password = reader.ReadString(8); | ||||
if(config.Version== JT809Version.JTT2019) | |||||
{ | |||||
jT809_0X1001.MsgGNSSCENTERID = reader.ReadUInt32(); | |||||
} | |||||
jT809_0X1001.DownLinkIP = reader.ReadString(32); | jT809_0X1001.DownLinkIP = reader.ReadString(32); | ||||
jT809_0X1001.DownLinkPort = reader.ReadUInt16(); | jT809_0X1001.DownLinkPort = reader.ReadUInt16(); | ||||
return jT809_0X1001; | return jT809_0X1001; | ||||
@@ -54,6 +63,10 @@ namespace JT809.Protocol.MessageBody | |||||
{ | { | ||||
writer.WriteUInt32(value.UserId); | writer.WriteUInt32(value.UserId); | ||||
writer.WriteStringPadRight(value.Password, 8); | writer.WriteStringPadRight(value.Password, 8); | ||||
if (config.Version == JT809Version.JTT2019) | |||||
{ | |||||
writer.WriteUInt32(value.MsgGNSSCENTERID); | |||||
} | |||||
writer.WriteStringPadRight(value.DownLinkIP, 32); | writer.WriteStringPadRight(value.DownLinkIP, 32); | ||||
writer.WriteUInt16(value.DownLinkPort); | writer.WriteUInt16(value.DownLinkPort); | ||||
} | } | ||||
@@ -1,6 +1,7 @@ | |||||
using JT809.Protocol.Enums; | using JT809.Protocol.Enums; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using JT809.Protocol.Formatters; | using JT809.Protocol.Formatters; | ||||
using JT809.Protocol.Interfaces; | |||||
using JT809.Protocol.MessagePack; | using JT809.Protocol.MessagePack; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
@@ -15,7 +16,7 @@ namespace JT809.Protocol.MessageBody | |||||
/// <para>业务数据类型标识:UP_CONNCCT_RSP</para> | /// <para>业务数据类型标识:UP_CONNCCT_RSP</para> | ||||
/// <para>描述:上级平台对下级平台登录请求信息、进行安全验证后,返回相应的验证结果。</para> | /// <para>描述:上级平台对下级平台登录请求信息、进行安全验证后,返回相应的验证结果。</para> | ||||
/// </summary> | /// </summary> | ||||
public class JT809_0x1002 : JT809Bodies, IJT809MessagePackFormatter<JT809_0x1002> | |||||
public class JT809_0x1002 : JT809Bodies, IJT809MessagePackFormatter<JT809_0x1002>, IJT809_2019_Version | |||||
{ | { | ||||
public override ushort MsgId => JT809BusinessType.主链路登录应答消息.ToUInt16Value(); | public override ushort MsgId => JT809BusinessType.主链路登录应答消息.ToUInt16Value(); | ||||
@@ -0,0 +1,78 @@ | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Extensions; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | |||||
using JT809.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.MessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 平台链路连接情况与车辆定位消息传输情况上报应答消息 | |||||
/// <para>链路类型:主链路</para> | |||||
/// <para>消息方向:上级平台往下级平台</para> | |||||
/// <para>业务类型标识:UP_MANAGE_MSG_RSP</para> | |||||
/// </summary> | |||||
public class JT809_0x1102 : JT809ExchangeMessageBodies, IJT809MessagePackFormatter<JT809_0x1102>,IJT809_2019_Version | |||||
{ | |||||
public override ushort MsgId => JT809BusinessType.平台链路连接情况与车辆定位消息传输情况上报应答消息_2019.ToUInt16Value(); | |||||
public override string Description => "平台链路连接情况与车辆定位消息传输情况上报应答消息"; | |||||
public override JT809_LinkType LinkType => JT809_LinkType.main; | |||||
public override JT809Version Version => JT809Version.JTT2019; | |||||
/// <summary> | |||||
/// 平台唯一编码 | |||||
/// </summary> | |||||
public string PlateformId { get; set; } | |||||
/// <summary> | |||||
/// 开始时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | |||||
/// 结束时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public DateTime EndTime { get; set; } | |||||
/// <summary> | |||||
/// START_TIME~END_TIME期间下级平台丢失得车辆定位消息总数 | |||||
/// </summary> | |||||
public uint LoseDymamicSum { get; set; } | |||||
/// <summary> | |||||
/// START_TIME~END_TIME期间下级监控平台链路断开次数 | |||||
/// </summary> | |||||
public byte DisconnectNum { get; set; } | |||||
/// <summary> | |||||
/// START_TIME~END_TIME期间下级监控平台链路断开总时长,用秒表示 | |||||
/// </summary> | |||||
public uint DisconnectTime { get; set; } | |||||
public JT809_0x1102 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | |||||
{ | |||||
JT809_0x1102 value = new JT809_0x1102(); | |||||
value.SubBusinessType = reader.ReadUInt16(); | |||||
value.DataLength = reader.ReadUInt32(); | |||||
value.PlateformId = reader.ReadBigNumber(11); | |||||
value.StartTime = reader.ReadUTCDateTime(); | |||||
value.EndTime = reader.ReadUTCDateTime(); | |||||
value.LoseDymamicSum = reader.ReadUInt32(); | |||||
value.DisconnectNum = reader.ReadByte(); | |||||
value.DisconnectTime = reader.ReadUInt32(); | |||||
return value; | |||||
} | |||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x1102 value, IJT809Config config) | |||||
{ | |||||
writer.WriteUInt16(value.SubBusinessType); | |||||
writer.WriteUInt32(36); | |||||
writer.WriteBigNumber(value.PlateformId, 11); | |||||
writer.WriteUTCDateTime(value.StartTime); | |||||
writer.WriteUTCDateTime(value.EndTime); | |||||
writer.WriteUInt32(value.LoseDymamicSum); | |||||
writer.WriteByte(value.DisconnectNum); | |||||
writer.WriteUInt32(value.DisconnectTime); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Extensions; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | |||||
using JT809.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using JT809.Protocol.Metadata; | |||||
namespace JT809.Protocol.MessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 上传平台间消息序列号通知消息 | |||||
/// <para>链路类型:主链路</para> | |||||
/// <para>消息方向:上级平台往下级平台</para> | |||||
/// <para>业务类型标识:UP_MANAGE_MSG_SN_INFORM</para> | |||||
/// </summary> | |||||
public class JT809_0x1103 : JT809ExchangeMessageBodies, IJT809MessagePackFormatter<JT809_0x1103>,IJT809_2019_Version | |||||
{ | |||||
public override ushort MsgId => JT809BusinessType.上传平台间消息序列号通知消息_2019.ToUInt16Value(); | |||||
public override string Description => "上传平台间消息序列号通知消息"; | |||||
public override JT809_LinkType LinkType => JT809_LinkType.main; | |||||
public override JT809Version Version => JT809Version.JTT2019; | |||||
public List<JT809ManageMsgSNInform> ManageMsgSNInform { get; set; } = new List<JT809ManageMsgSNInform>(); | |||||
public byte Count { get; set; } | |||||
public JT809_0x1103 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | |||||
{ | |||||
JT809_0x1103 value = new JT809_0x1103(); | |||||
value.SubBusinessType = reader.ReadUInt16(); | |||||
value.DataLength = reader.ReadUInt32(); | |||||
value.Count = reader.ReadByte(); | |||||
for(int i=0;i < value.Count; i++) | |||||
{ | |||||
JT809ManageMsgSNInform item = new JT809ManageMsgSNInform(); | |||||
item.SubBusinessType = reader.ReadUInt16(); | |||||
item.MsgSN = reader.ReadUInt32(); | |||||
item.Time = reader.ReadUTCDateTime(); | |||||
value.ManageMsgSNInform.Add(item); | |||||
} | |||||
return value; | |||||
} | |||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x1103 value, IJT809Config config) | |||||
{ | |||||
writer.WriteUInt16(value.SubBusinessType); | |||||
// 先写入内容,然后在根据内容反写内容长度 | |||||
writer.Skip(4, out int subContentLengthPosition); | |||||
writer.WriteByte((byte)value.ManageMsgSNInform.Count); | |||||
foreach(var item in value.ManageMsgSNInform) | |||||
{ | |||||
writer.WriteUInt16(item.SubBusinessType); | |||||
writer.WriteUInt32(item.MsgSN); | |||||
writer.WriteUTCDateTime(item.Time); | |||||
} | |||||
writer.WriteInt32Return(writer.GetCurrentPosition() - subContentLengthPosition - 4, subContentLengthPosition); | |||||
} | |||||
} | |||||
} |
@@ -29,26 +29,26 @@ namespace JT809.Protocol.MessageBody | |||||
/// 开始时间,用 UTC 时间表示 | /// 开始时间,用 UTC 时间表示 | ||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | /// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | ||||
/// </summary> | /// </summary> | ||||
public ulong StartTime { get; set; } | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// 结束时间,用 UTC 时间表示 | /// 结束时间,用 UTC 时间表示 | ||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | /// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | ||||
/// </summary> | /// </summary> | ||||
public ulong EndTime { get; set; } | |||||
public DateTime EndTime { get; set; } | |||||
public JT809_0x9101 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | public JT809_0x9101 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | ||||
{ | { | ||||
JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); | |||||
jT809_0X9101.DynamicInfoTotal = reader.ReadUInt32(); | |||||
jT809_0X9101.StartTime = reader.ReadUInt64(); | |||||
jT809_0X9101.EndTime = reader.ReadUInt64(); | |||||
return jT809_0X9101; | |||||
JT809_0x9101 value = new JT809_0x9101(); | |||||
value.DynamicInfoTotal = reader.ReadUInt32(); | |||||
value.StartTime = reader.ReadUTCDateTime(); | |||||
value.EndTime = reader.ReadUTCDateTime(); | |||||
return value; | |||||
} | } | ||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x9101 value, IJT809Config config) | public void Serialize(ref JT809MessagePackWriter writer, JT809_0x9101 value, IJT809Config config) | ||||
{ | { | ||||
writer.WriteUInt32(value.DynamicInfoTotal); | writer.WriteUInt32(value.DynamicInfoTotal); | ||||
writer.WriteUInt64(value.StartTime); | |||||
writer.WriteUInt64(value.EndTime); | |||||
writer.WriteUTCDateTime(value.StartTime); | |||||
writer.WriteUTCDateTime(value.EndTime); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -0,0 +1,60 @@ | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Extensions; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | |||||
using JT809.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.MessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 平台链路连接情况与车辆定位消息传输情况上报请求消息 | |||||
/// <para>链路类型:从链路</para> | |||||
/// <para>消息方向:上级平台往下级平台</para> | |||||
/// <para>业务类型标识:DOWN_MANAGE_MSG_REQ</para> | |||||
/// </summary> | |||||
public class JT809_0x9102 : JT809ExchangeMessageBodies, IJT809MessagePackFormatter<JT809_0x9102>,IJT809_2019_Version | |||||
{ | |||||
public override ushort MsgId => JT809BusinessType.平台链路连接情况与车辆定位消息传输情况上报请求消息_2019.ToUInt16Value(); | |||||
public override string Description => "平台链路连接情况与车辆定位消息传输情况上报请求消息"; | |||||
public override JT809_LinkType LinkType => JT809_LinkType.subordinate; | |||||
public override JT809Version Version => JT809Version.JTT2019; | |||||
/// <summary> | |||||
/// 平台唯一编码 | |||||
/// </summary> | |||||
public string PlateformId { get; set; } | |||||
/// <summary> | |||||
/// 开始时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | |||||
/// 结束时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public DateTime EndTime { get; set; } | |||||
public JT809_0x9102 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | |||||
{ | |||||
JT809_0x9102 value = new JT809_0x9102(); | |||||
value.SubBusinessType = reader.ReadUInt16(); | |||||
value.DataLength = reader.ReadUInt32(); | |||||
value.PlateformId = reader.ReadBigNumber(11); | |||||
value.StartTime = reader.ReadUTCDateTime(); | |||||
value.EndTime = reader.ReadUTCDateTime(); | |||||
return value; | |||||
} | |||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x9102 value, IJT809Config config) | |||||
{ | |||||
writer.WriteUInt16(value.SubBusinessType); | |||||
writer.WriteUInt32(27); | |||||
writer.WriteBigNumber(value.PlateformId, 11); | |||||
writer.WriteUTCDateTime(value.StartTime); | |||||
writer.WriteUTCDateTime(value.EndTime); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Extensions; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | |||||
using JT809.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using JT809.Protocol.Metadata; | |||||
namespace JT809.Protocol.MessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 下发平台间消息序列号通知消息 | |||||
/// <para>链路类型:从链路</para> | |||||
/// <para>消息方向:上级平台往下级平台</para> | |||||
/// <para>业务类型标识:DOWN_MANAGE_MSG_SN_INFORM</para> | |||||
/// </summary> | |||||
public class JT809_0x9103 : JT809ExchangeMessageBodies, IJT809MessagePackFormatter<JT809_0x9103>,IJT809_2019_Version | |||||
{ | |||||
public override ushort MsgId => JT809BusinessType.下发平台间消息序列号通知消息_2019.ToUInt16Value(); | |||||
public override string Description => "下发平台间消息序列号通知消息"; | |||||
public override JT809_LinkType LinkType => JT809_LinkType.subordinate; | |||||
public override JT809Version Version => JT809Version.JTT2019; | |||||
public List<JT809ManageMsgSNInform> ManageMsgSNInform { get; set; } = new List<JT809ManageMsgSNInform>(); | |||||
public byte Count { get; set; } | |||||
public JT809_0x9103 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | |||||
{ | |||||
JT809_0x9103 value = new JT809_0x9103(); | |||||
value.SubBusinessType = reader.ReadUInt16(); | |||||
value.DataLength = reader.ReadUInt32(); | |||||
value.Count = reader.ReadByte(); | |||||
for(int i=0;i < value.Count; i++) | |||||
{ | |||||
JT809ManageMsgSNInform item = new JT809ManageMsgSNInform(); | |||||
item.SubBusinessType = reader.ReadUInt16(); | |||||
item.MsgSN = reader.ReadUInt32(); | |||||
item.Time = reader.ReadUTCDateTime(); | |||||
value.ManageMsgSNInform.Add(item); | |||||
} | |||||
return value; | |||||
} | |||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x9103 value, IJT809Config config) | |||||
{ | |||||
writer.WriteUInt16(value.SubBusinessType); | |||||
// 先写入内容,然后在根据内容反写内容长度 | |||||
writer.Skip(4, out int subContentLengthPosition); | |||||
writer.WriteByte((byte)value.ManageMsgSNInform.Count); | |||||
foreach(var item in value.ManageMsgSNInform) | |||||
{ | |||||
writer.WriteUInt16(item.SubBusinessType); | |||||
writer.WriteUInt32(item.MsgSN); | |||||
writer.WriteUTCDateTime(item.Time); | |||||
} | |||||
writer.WriteInt32Return(writer.GetCurrentPosition() - subContentLengthPosition - 4, subContentLengthPosition); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,56 @@ | |||||
using JT809.Protocol.Enums; | |||||
using JT809.Protocol.Extensions; | |||||
using JT809.Protocol.Formatters; | |||||
using JT809.Protocol.MessagePack; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.MessageBody | |||||
{ | |||||
/// <summary> | |||||
/// 发送车辆定位信息数据量通知消息 | |||||
/// <para>链路类型:主链路</para> | |||||
/// <para>消息方向:下级平台往上级平台</para> | |||||
/// <para>业务类型标识: DOWN_TOTAL_RECV_BACK_MSG</para> | |||||
/// <para>描述:下级平台向上级平台定量通知已经上传的车辆定位信息数量(如:每收到10,000 条车辆定位信息通知一次)</para> | |||||
/// <para>本条消息不需下级平台应答。</para> | |||||
/// </summary> | |||||
public class JT809_2019_0x9101 : JT809Bodies, IJT809MessagePackFormatter<JT809_2019_0x9101> | |||||
{ | |||||
public override ushort MsgId => JT809BusinessType.发送车辆定位信息数据量通知消息_2019.ToUInt16Value(); | |||||
public override string Description => "发送车辆定位信息数据量通知消息"; | |||||
public override JT809_LinkType LinkType => JT809_LinkType.main; | |||||
public override JT809Version Version => JT809Version.JTT2019; | |||||
/// <summary> | |||||
/// START_TIME_END_TIME共收到的车辆定位信息数量 | |||||
/// </summary> | |||||
public uint DynamicInfoTotal { get; set; } | |||||
/// <summary> | |||||
/// 开始时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public ulong StartTime { get; set; } | |||||
/// <summary> | |||||
/// 结束时间,用 UTC 时间表示 | |||||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||||
/// </summary> | |||||
public ulong EndTime { get; set; } | |||||
public JT809_2019_0x9101 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | |||||
{ | |||||
JT809_2019_0x9101 value = new JT809_2019_0x9101(); | |||||
value.DynamicInfoTotal = reader.ReadUInt32(); | |||||
value.StartTime = reader.ReadUInt64(); | |||||
value.EndTime = reader.ReadUInt64(); | |||||
return value; | |||||
} | |||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_2019_0x9101 value, IJT809Config config) | |||||
{ | |||||
writer.WriteUInt32(value.DynamicInfoTotal); | |||||
writer.WriteUInt64(value.StartTime); | |||||
writer.WriteUInt64(value.EndTime); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,22 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.Metadata | |||||
{ | |||||
public class JT809ManageMsgSNInform | |||||
{ | |||||
/// <summary> | |||||
/// 子业务类型标识 | |||||
/// </summary> | |||||
public ushort SubBusinessType { get; set; } | |||||
/// <summary> | |||||
/// 对应得子夜吴数据类型报文序列号 | |||||
/// </summary> | |||||
public uint MsgSN { get; set; } | |||||
/// <summary> | |||||
/// 系统UTC时间 | |||||
/// </summary> | |||||
public DateTime Time { get; set; } | |||||
} | |||||
} |
@@ -2,16 +2,17 @@ | |||||
using JT809.Protocol.Formatters; | using JT809.Protocol.Formatters; | ||||
using JT809.Protocol.MessagePack; | using JT809.Protocol.MessagePack; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using JT809.Protocol.Interfaces; | |||||
namespace JT809.Protocol.SubMessageBody | namespace JT809.Protocol.SubMessageBody | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// 上传车辆注册信息消息 | /// 上传车辆注册信息消息 | ||||
/// <para>子业务类型标识:UP_ EXG_ MSG_ REGISTER</para> | |||||
/// <para>子业务类型标识:UP_EXG_MSG_REGISTER</para> | |||||
/// <para>描述:监控平台收到车载终端鉴权信息后,启动本命令向上级监管平台上传该车辆注册信息.各级监管平台再逐级向上级平台上传该信息</para> | /// <para>描述:监控平台收到车载终端鉴权信息后,启动本命令向上级监管平台上传该车辆注册信息.各级监管平台再逐级向上级平台上传该信息</para> | ||||
/// <para>本条消息服务端无需应答</para> | /// <para>本条消息服务端无需应答</para> | ||||
/// </summary> | /// </summary> | ||||
public class JT809_0x1200_0x1201:JT809SubBodies, IJT809MessagePackFormatter<JT809_0x1200_0x1201> | |||||
public class JT809_0x1200_0x1201:JT809SubBodies, IJT809MessagePackFormatter<JT809_0x1200_0x1201>, IJT809_2019_Version | |||||
{ | { | ||||
public override ushort SubMsgId => JT809SubBusinessType.上传车辆注册信息.ToUInt16Value(); | public override ushort SubMsgId => JT809SubBusinessType.上传车辆注册信息.ToUInt16Value(); | ||||
@@ -30,6 +31,11 @@ namespace JT809.Protocol.SubMessageBody | |||||
/// </summary> | /// </summary> | ||||
public string TerminalModelType { get; set; } | public string TerminalModelType { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// 车载终端通讯模块IMEI码 | |||||
/// 2019版本 | |||||
/// </summary> | |||||
public string IMIEId { get; set; } | |||||
/// <summary> | |||||
/// 车载终端编号,大写字母和数字组成 | /// 车载终端编号,大写字母和数字组成 | ||||
/// </summary> | /// </summary> | ||||
public string TerminalId { get; set; } | public string TerminalId { get; set; } | ||||
@@ -40,23 +46,48 @@ namespace JT809.Protocol.SubMessageBody | |||||
public JT809_0x1200_0x1201 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | public JT809_0x1200_0x1201 Deserialize(ref JT809MessagePackReader reader, IJT809Config config) | ||||
{ | { | ||||
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = new JT809_0x1200_0x1201(); | |||||
jT809_0X1200_0X1201.PlateformId = reader.ReadBigNumber(11); | |||||
jT809_0X1200_0X1201.ProducerId = reader.ReadBigNumber(11); | |||||
jT809_0X1200_0X1201.TerminalModelType = reader.ReadString(20); | |||||
jT809_0X1200_0X1201.TerminalId = reader.ReadString(7); | |||||
jT809_0X1200_0X1201.TerminalId = jT809_0X1200_0X1201.TerminalId.ToUpper(); | |||||
jT809_0X1200_0X1201.TerminalSimCode = reader.ReadString(12); | |||||
return jT809_0X1200_0X1201; | |||||
JT809_0x1200_0x1201 value = new JT809_0x1200_0x1201(); | |||||
if(config.Version== JT809Version.JTT2013) | |||||
{ | |||||
value.PlateformId = reader.ReadBigNumber(11); | |||||
value.ProducerId = reader.ReadBigNumber(11); | |||||
value.TerminalModelType = reader.ReadString(20); | |||||
value.TerminalId = reader.ReadString(7); | |||||
value.TerminalId = value.TerminalId.ToUpper(); | |||||
value.TerminalSimCode = reader.ReadString(12); | |||||
} | |||||
else | |||||
{ | |||||
value.PlateformId = reader.ReadBigNumber(11); | |||||
value.ProducerId = reader.ReadBigNumber(11); | |||||
value.TerminalModelType = reader.ReadString(30); | |||||
value.IMIEId = reader.ReadString(15); | |||||
value.TerminalId = reader.ReadString(30); | |||||
value.TerminalId = value.TerminalId.ToUpper(); | |||||
value.TerminalSimCode = reader.ReadString(13); | |||||
} | |||||
return value; | |||||
} | } | ||||
public void Serialize(ref JT809MessagePackWriter writer, JT809_0x1200_0x1201 value, IJT809Config config) | public void Serialize(ref JT809MessagePackWriter writer, JT809_0x1200_0x1201 value, IJT809Config config) | ||||
{ | { | ||||
writer.WriteBigNumber(value.PlateformId, 11); | |||||
writer.WriteBigNumber(value.ProducerId, 11); | |||||
writer.WriteStringPadRight(value.TerminalModelType, 20); | |||||
writer.WriteStringPadRight(value.TerminalId.ToUpper(), 7); | |||||
writer.WriteStringPadRight(value.TerminalSimCode, 12); | |||||
if(config.Version== JT809Version.JTT2013) | |||||
{ | |||||
writer.WriteBigNumber(value.PlateformId, 11); | |||||
writer.WriteBigNumber(value.ProducerId, 11); | |||||
writer.WriteStringPadRight(value.TerminalModelType, 20); | |||||
writer.WriteStringPadRight(value.TerminalId.ToUpper(), 7); | |||||
writer.WriteStringPadLeft(value.TerminalSimCode, 12); | |||||
} | |||||
else | |||||
{ | |||||
writer.WriteBigNumber(value.PlateformId, 11); | |||||
writer.WriteBigNumber(value.ProducerId, 11); | |||||
writer.WriteStringPadRight(value.TerminalModelType, 30); | |||||
writer.WriteStringPadRight(value.IMIEId, 15); | |||||
writer.WriteStringPadRight(value.TerminalId.ToUpper(), 30); | |||||
writer.WriteStringPadLeft(value.TerminalSimCode, 13); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |