Browse Source

1.增加对2019版本的兼容

2.增加2019版本1102、1103、9102、9103
3.修改1001、1002、9101对2019版本的兼容
4.完善文档
tags/v2.2.0
SmallChi(Koike) 5 years ago
parent
commit
f3fcc58dbf
21 changed files with 566 additions and 54 deletions
  1. +3
    -3
      README.md
  2. +4
    -4
      src/JT809.Protocol.Test/JT809MessageBody/JT809_0x9101Test.cs
  3. +40
    -0
      src/JT809.Protocol/Enums/JT809BusinessType.cs
  4. +2
    -1
      src/JT809.Protocol/Enums/JT809_0x1002_Result.cs
  5. +4
    -2
      src/JT809.Protocol/Interfaces/IJT809BusinessTypeFactory.cs
  6. +2
    -0
      src/JT809.Protocol/Interfaces/IJT809Config.cs
  7. +5
    -1
      src/JT809.Protocol/Interfaces/JT809GlobalConfigBase.cs
  8. +56
    -8
      src/JT809.Protocol/Internal/JT809BusinessTypeFactory.cs
  9. +1
    -3
      src/JT809.Protocol/JT809Bodies.cs
  10. +21
    -1
      src/JT809.Protocol/JT809Header.cs
  11. +19
    -5
      src/JT809.Protocol/JT809Package.cs
  12. +14
    -1
      src/JT809.Protocol/MessageBody/JT809_0x1001.cs
  13. +2
    -1
      src/JT809.Protocol/MessageBody/JT809_0x1002.cs
  14. +78
    -0
      src/JT809.Protocol/MessageBody/JT809_0x1102.cs
  15. +61
    -0
      src/JT809.Protocol/MessageBody/JT809_0x1103.cs
  16. +9
    -9
      src/JT809.Protocol/MessageBody/JT809_0x9101.cs
  17. +60
    -0
      src/JT809.Protocol/MessageBody/JT809_0x9102.cs
  18. +61
    -0
      src/JT809.Protocol/MessageBody/JT809_0x9103.cs
  19. +56
    -0
      src/JT809.Protocol/MessageBody/JT809_2019_0x9101.cs
  20. +22
    -0
      src/JT809.Protocol/Metadata/JT809ManageMsgSNInform.cs
  21. +46
    -15
      src/JT809.Protocol/SubMessageBody/JT809_0x1200_0x1201.cs

+ 3
- 3
README.md View File

@@ -23,9 +23,9 @@

### 数据头[JT809Header]

|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙|
|:------:|:------:|:------:|:------:|:------:|:------:|:------:|
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey |
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙|发送消息的系统时间(2019版本)|
|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|
| MsgLength | MsgSN | BusinessType | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey |Time|

### 数据体[JT809Bodies]



+ 4
- 4
src/JT809.Protocol.Test/JT809MessageBody/JT809_0x9101Test.cs View File

@@ -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);
}
}
}

+ 40
- 0
src/JT809.Protocol/Enums/JT809BusinessType.cs View File

@@ -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>


+ 2
- 1
src/JT809.Protocol/Enums/JT809_0x1002_Result.cs View File

@@ -15,6 +15,7 @@ namespace JT809.Protocol.Enums
用户没用注册=0x03,
密码错误=0x04,
资源紧张_稍后再连接_已经占用= 0x05,
其他 =0x06
其他 =0x06,
其他_2019 = 0xFF
}
}

+ 4
- 2
src/JT809.Protocol/Interfaces/IJT809BusinessTypeFactory.cs View File

@@ -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;
}
}

+ 2
- 0
src/JT809.Protocol/Interfaces/IJT809Config.cs View File

@@ -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>


+ 5
- 1
src/JT809.Protocol/Interfaces/JT809GlobalConfigBase.cs View File

@@ -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)


+ 56
- 8
src/JT809.Protocol/Internal/JT809BusinessTypeFactory.cs View File

@@ -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);
}
}
}
}

+ 1
- 3
src/JT809.Protocol/JT809Bodies.cs View File

@@ -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; }
}
}

+ 21
- 1
src/JT809.Protocol/JT809Header.cs View File

@@ -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);
}
}
}
}

+ 19
- 5
src/JT809.Protocol/JT809Package.cs View File

@@ -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();


+ 14
- 1
src/JT809.Protocol/MessageBody/JT809_0x1001.cs View File

@@ -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);
}


+ 2
- 1
src/JT809.Protocol/MessageBody/JT809_0x1002.cs View File

@@ -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();



+ 78
- 0
src/JT809.Protocol/MessageBody/JT809_0x1102.cs View File

@@ -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);
}
}
}

+ 61
- 0
src/JT809.Protocol/MessageBody/JT809_0x1103.cs View File

@@ -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);
}
}
}

+ 9
- 9
src/JT809.Protocol/MessageBody/JT809_0x9101.cs View File

@@ -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);
}
}
}

+ 60
- 0
src/JT809.Protocol/MessageBody/JT809_0x9102.cs View File

@@ -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);
}
}
}

+ 61
- 0
src/JT809.Protocol/MessageBody/JT809_0x9103.cs View File

@@ -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);
}
}
}

+ 56
- 0
src/JT809.Protocol/MessageBody/JT809_2019_0x9101.cs View File

@@ -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);
}
}
}

+ 22
- 0
src/JT809.Protocol/Metadata/JT809ManageMsgSNInform.cs View File

@@ -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; }
}
}

+ 46
- 15
src/JT809.Protocol/SubMessageBody/JT809_0x1200_0x1201.cs View File

@@ -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);
}
}
}
}

Loading…
Cancel
Save