2.增加2019版本1102、1103、9102、9103 3.修改1001、1002、9101对2019版本的兼容 4.完善文档tags/v2.2.0
@@ -23,9 +23,9 @@ | |||
### 数据头[JT809Header] | |||
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙| | |||
|:------:|:------:|:------:|:------:|:------:|:------:|:------:| | |||
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey | | |||
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙|发送消息的系统时间(2019版本)| | |||
|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:| | |||
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey |Time| | |||
### 数据体[JT809Bodies] | |||
@@ -17,8 +17,8 @@ namespace JT809.Protocol.Test.JT809MessageBody | |||
{ | |||
JT809_0x9101 jT809_0X9101 = new JT809_0x9101(); | |||
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(); | |||
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(); | |||
JT809_0x9101 jT809_0X9101 = JT809Serializer.Deserialize<JT809_0x9101>(bytes); | |||
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))] | |||
[JT809BusinessTypeDescription("DOWN_TOTAL_RECV_BACK_MSG", "接收车辆定位信息数量通知消息")] | |||
接收车辆定位信息数量通知消息 = 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 | |||
#region 车辆动态信息交换 | |||
///<summary> | |||
@@ -15,6 +15,7 @@ namespace JT809.Protocol.Enums | |||
用户没用注册=0x03, | |||
密码错误=0x04, | |||
资源紧张_稍后再连接_已经占用= 0x05, | |||
其他 =0x06 | |||
其他 =0x06, | |||
其他_2019 = 0xFF | |||
} | |||
} |
@@ -1,4 +1,5 @@ | |||
using System; | |||
using JT809.Protocol.Enums; | |||
using System; | |||
using System.Collections.Generic; | |||
namespace JT809.Protocol.Interfaces | |||
@@ -6,7 +7,8 @@ namespace JT809.Protocol.Interfaces | |||
public interface IJT809BusinessTypeFactory : IJT809ExternalRegister | |||
{ | |||
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; | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
using JT808.Protocol.Formatters; | |||
using JT809.Protocol.Configs; | |||
using JT809.Protocol.Enums; | |||
using JT809.Protocol.Interfaces; | |||
using System; | |||
using System.Collections.Generic; | |||
@@ -40,6 +41,7 @@ namespace JT809.Protocol | |||
IJT809BusinessTypeFactory BusinessTypeFactory { get; set; } | |||
IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set; } | |||
IJT809FormatterFactory FormatterFactory { get; set; } | |||
JT809Version Version { get; set; } | |||
/// <summary> | |||
/// 全局注册外部程序集 | |||
/// </summary> | |||
@@ -2,6 +2,7 @@ | |||
using JT808.Protocol.Internal; | |||
using JT809.Protocol.Configs; | |||
using JT809.Protocol.Encrypt; | |||
using JT809.Protocol.Enums; | |||
using JT809.Protocol.Internal; | |||
using System; | |||
using System.Reflection; | |||
@@ -11,13 +12,14 @@ namespace JT809.Protocol.Interfaces | |||
{ | |||
public abstract class JT809GlobalConfigBase : IJT809Config | |||
{ | |||
protected JT809GlobalConfigBase() | |||
protected JT809GlobalConfigBase(JT809Version version= JT809Version.JTT2013) | |||
{ | |||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | |||
Encoding = Encoding.GetEncoding("GBK"); | |||
BusinessTypeFactory = new JT809BusinessTypeFactory(); | |||
SubBusinessTypeFactory = new JT809SubBusinessTypeFactory(); | |||
FormatterFactory = new JT809FormatterFactory(); | |||
Version = version; | |||
} | |||
public abstract string ConfigId { get; } | |||
public virtual IJT809MsgSNDistributed MsgSNDistributed { get; set; }= new DefaultMsgSNDistributedImpl(); | |||
@@ -29,6 +31,8 @@ namespace JT809.Protocol.Interfaces | |||
public IJT809BusinessTypeFactory BusinessTypeFactory { get ; set ; } | |||
public IJT809SubBusinessTypeFactory SubBusinessTypeFactory { get; set ; } | |||
public IJT809FormatterFactory FormatterFactory { get; set; } | |||
public JT809Version Version { get; set; } | |||
public virtual IJT809Config Register(params Assembly[] externalAssemblies) | |||
{ | |||
if (externalAssemblies != null) | |||
@@ -14,15 +14,17 @@ namespace JT808.Protocol.Internal | |||
{ | |||
public IDictionary<ushort, object> Map { get; } | |||
public IDictionary<ushort, object> Map_2019 { get; } | |||
internal JT809BusinessTypeFactory() | |||
{ | |||
Map = new Dictionary<ushort, object>(); | |||
Map_2019 = new Dictionary<ushort, object>(); | |||
InitMap(Assembly.GetExecutingAssembly()); | |||
} | |||
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() | |||
.Where(w => w.BaseType == typeof(JT809Bodies) || w.BaseType == typeof(JT809ExchangeMessageBodies)).ToList(); | |||
foreach (var type in types) | |||
@@ -30,17 +32,37 @@ namespace JT808.Protocol.Internal | |||
if (type.Name == nameof(JT809ExchangeMessageBodies)) continue; | |||
var instance = Activator.CreateInstance(type); | |||
ushort msgId = 0; | |||
JT809Version version; | |||
try | |||
{ | |||
msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | |||
version = (JT809Version)type.GetProperty(nameof(JT809Bodies.Version)).GetValue(instance); | |||
} | |||
catch (Exception ex) | |||
{ | |||
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)) | |||
{ | |||
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 | |||
{ | |||
@@ -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 | |||
{ | |||
Type type = typeof(TJT809Bodies); | |||
var instance = Activator.CreateInstance(type); | |||
var msgId = (ushort)type.GetProperty(nameof(JT809Bodies.MsgId)).GetValue(instance); | |||
JT809Version version = (JT809Version)type.GetProperty(nameof(JT809Bodies.Version)).GetValue(instance); | |||
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 | |||
{ | |||
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; | |||
} | |||
@@ -74,5 +110,17 @@ namespace JT808.Protocol.Internal | |||
{ | |||
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一下来表达意思。 | |||
/// </summary> | |||
public virtual bool SkipSerialization { get; set; } = false; | |||
public virtual JT809Version Version => JT809Version.JTT2013; | |||
public abstract ushort MsgId { get; } | |||
public abstract JT809_LinkType LinkType { 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 System; | |||
namespace JT809.Protocol | |||
{ | |||
@@ -12,6 +14,12 @@ namespace JT809.Protocol | |||
/// </summary> | |||
public const int FixedByteLength = 22; | |||
/// <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>1 + 22 + n + 1</para> | |||
@@ -44,6 +52,10 @@ namespace JT809.Protocol | |||
/// 数据加密的密匙,长度为 4 个字节 | |||
/// </summary> | |||
public uint EncryptKey { get; set; } | |||
/// <summary> | |||
/// 发送消息时的系统UTC时间,长度为8个字节 | |||
/// </summary> | |||
public DateTime Time { get; set; } = DateTime.Now; | |||
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.EncryptFlag = (JT809Header_Encrypt)reader.ReadByte(); | |||
jT809Header.EncryptKey = reader.ReadUInt32(); | |||
if(config.Version== JT809Version.JTT2019) | |||
{ | |||
Time = reader.ReadUTCDateTime(); | |||
} | |||
return jT809Header; | |||
} | |||
@@ -67,6 +83,10 @@ namespace JT809.Protocol | |||
writer.WriteArray(value.Version.Buffer); | |||
writer.WriteByte((byte)value.EncryptFlag); | |||
writer.WriteUInt32(value.EncryptKey); | |||
if (config.Version == JT809Version.JTT2019) | |||
{ | |||
writer.WriteUTCDateTime(value.Time); | |||
} | |||
} | |||
} | |||
} |
@@ -2,12 +2,13 @@ | |||
using JT809.Protocol.Exceptions; | |||
using JT809.Protocol.Extensions; | |||
using JT809.Protocol.Formatters; | |||
using JT809.Protocol.Interfaces; | |||
using JT809.Protocol.MessagePack; | |||
using System; | |||
namespace JT809.Protocol | |||
{ | |||
public class JT809Package:IJT809MessagePackFormatter<JT809Package> | |||
public class JT809Package:IJT809MessagePackFormatter<JT809Package>, IJT809_2019_Version | |||
{ | |||
public const byte BEGINFLAG = 0X5B; | |||
@@ -19,6 +20,12 @@ namespace JT809.Protocol | |||
/// <para>1 + 22 + 2 + 1 = 26</para> | |||
/// </summary> | |||
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; | |||
@@ -38,7 +45,7 @@ namespace JT809.Protocol | |||
// 1.2. 验证校验码 | |||
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(); | |||
@@ -52,12 +59,13 @@ namespace JT809.Protocol | |||
catch (Exception ex) | |||
{ | |||
throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{reader.ReadCurrentRemainContentLength()}", ex); | |||
} | |||
} | |||
// 5.数据体处理 | |||
// 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 | |||
{ | |||
@@ -82,6 +90,7 @@ namespace JT809.Protocol | |||
} | |||
} | |||
} | |||
jT809Package.CRCCode = reader.CalculateCheckXorCode; | |||
jT809Package.EndFlag = reader.ReadEnd(); | |||
return jT809Package; | |||
@@ -108,6 +117,11 @@ namespace JT809.Protocol | |||
writer.WriteByte((byte)value.Header.EncryptFlag); | |||
// 2.7.数据加密密钥 | |||
writer.WriteUInt32(value.Header.EncryptKey); | |||
if(config.Version== JT809Version.JTT2019) | |||
{ | |||
// 2.8.UTC时间戳 | |||
writer.WriteUTCDateTime(value.Header.Time); | |||
} | |||
// 3.写入数据体 | |||
// 3.1.记录当前开始位置 | |||
int startIndex = writer.GetCurrentPosition(); | |||
@@ -1,6 +1,7 @@ | |||
using JT809.Protocol.Enums; | |||
using JT809.Protocol.Extensions; | |||
using JT809.Protocol.Formatters; | |||
using JT809.Protocol.Interfaces; | |||
using JT809.Protocol.MessagePack; | |||
@@ -13,7 +14,7 @@ namespace JT809.Protocol.MessageBody | |||
/// <para>业务数据类型标识: UP-CONNECT-REQ</para> | |||
/// <para>描述:下级平台向上级平台发送用户名和密码等登录信息</para> | |||
/// </summary> | |||
public class JT809_0x1001: JT809Bodies,IJT809MessagePackFormatter<JT809_0x1001> | |||
public class JT809_0x1001: JT809Bodies,IJT809MessagePackFormatter<JT809_0x1001>, IJT809_2019_Version | |||
{ | |||
/// <summary> | |||
/// 用户名 | |||
@@ -25,6 +26,10 @@ namespace JT809.Protocol.MessageBody | |||
/// </summary> | |||
public string Password { get; set; } | |||
/// <summary> | |||
/// 下级平台接入码 | |||
/// </summary> | |||
public uint MsgGNSSCENTERID { get; set; } | |||
/// <summary> | |||
/// 下级平台提供对应的从链路服务端 IP 地址 | |||
/// 32位 | |||
/// </summary> | |||
@@ -45,6 +50,10 @@ namespace JT809.Protocol.MessageBody | |||
JT809_0x1001 jT809_0X1001 = new JT809_0x1001(); | |||
jT809_0X1001.UserId = reader.ReadUInt32(); | |||
jT809_0X1001.Password = reader.ReadString(8); | |||
if(config.Version== JT809Version.JTT2019) | |||
{ | |||
jT809_0X1001.MsgGNSSCENTERID = reader.ReadUInt32(); | |||
} | |||
jT809_0X1001.DownLinkIP = reader.ReadString(32); | |||
jT809_0X1001.DownLinkPort = reader.ReadUInt16(); | |||
return jT809_0X1001; | |||
@@ -54,6 +63,10 @@ namespace JT809.Protocol.MessageBody | |||
{ | |||
writer.WriteUInt32(value.UserId); | |||
writer.WriteStringPadRight(value.Password, 8); | |||
if (config.Version == JT809Version.JTT2019) | |||
{ | |||
writer.WriteUInt32(value.MsgGNSSCENTERID); | |||
} | |||
writer.WriteStringPadRight(value.DownLinkIP, 32); | |||
writer.WriteUInt16(value.DownLinkPort); | |||
} | |||
@@ -1,6 +1,7 @@ | |||
using JT809.Protocol.Enums; | |||
using JT809.Protocol.Extensions; | |||
using JT809.Protocol.Formatters; | |||
using JT809.Protocol.Interfaces; | |||
using JT809.Protocol.MessagePack; | |||
using System; | |||
using System.Collections.Generic; | |||
@@ -15,7 +16,7 @@ namespace JT809.Protocol.MessageBody | |||
/// <para>业务数据类型标识:UP_CONNCCT_RSP</para> | |||
/// <para>描述:上级平台对下级平台登录请求信息、进行安全验证后,返回相应的验证结果。</para> | |||
/// </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(); | |||
@@ -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 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||
/// </summary> | |||
public ulong StartTime { get; set; } | |||
public DateTime StartTime { get; set; } | |||
/// <summary> | |||
/// 结束时间,用 UTC 时间表示 | |||
/// 注:采用 UTC 时间表示,如 2010-1-10 9:7:54 的 UTC 值为 1263085674,其在协议中表示为0x000000004B49286A. | |||
/// </summary> | |||
public ulong EndTime { get; set; } | |||
public DateTime EndTime { get; set; } | |||
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) | |||
{ | |||
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.MessagePack; | |||
using JT809.Protocol.Extensions; | |||
using JT809.Protocol.Interfaces; | |||
namespace JT809.Protocol.SubMessageBody | |||
{ | |||
/// <summary> | |||
/// 上传车辆注册信息消息 | |||
/// <para>子业务类型标识:UP_ EXG_ MSG_ REGISTER</para> | |||
/// <para>子业务类型标识:UP_EXG_MSG_REGISTER</para> | |||
/// <para>描述:监控平台收到车载终端鉴权信息后,启动本命令向上级监管平台上传该车辆注册信息.各级监管平台再逐级向上级平台上传该信息</para> | |||
/// <para>本条消息服务端无需应答</para> | |||
/// </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(); | |||
@@ -30,6 +31,11 @@ namespace JT809.Protocol.SubMessageBody | |||
/// </summary> | |||
public string TerminalModelType { get; set; } | |||
/// <summary> | |||
/// 车载终端通讯模块IMEI码 | |||
/// 2019版本 | |||
/// </summary> | |||
public string IMIEId { get; set; } | |||
/// <summary> | |||
/// 车载终端编号,大写字母和数字组成 | |||
/// </summary> | |||
public string TerminalId { get; set; } | |||
@@ -40,23 +46,48 @@ namespace JT809.Protocol.SubMessageBody | |||
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) | |||
{ | |||
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); | |||
} | |||
} | |||
} | |||
} |