diff --git a/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs index 76d9e48..4922229 100644 --- a/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs +++ b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs @@ -46,6 +46,8 @@ namespace JT808.Protocol.Interfaces public virtual IJT808_0x0900_Custom_Factory JT808_0x0900_Custom_Factory { get; set; } public virtual IJT808_0x8900_Custom_Factory JT808_0x8900_Custom_Factory { get; set; } public virtual IJT808_0x8500_2019_Factory JT808_0x8500_2019_Factory { get; set; } + public IJT808_Recorder_Factory JT808_Recorder_Factory { get; set; } + public virtual IJT808Config Register(params Assembly[] externalAssemblies) { if (externalAssemblies != null) diff --git a/src/JT808.Protocol/Interfaces/IJT808Config.cs b/src/JT808.Protocol/Interfaces/IJT808Config.cs index 7b6f963..1488e8f 100644 --- a/src/JT808.Protocol/Interfaces/IJT808Config.cs +++ b/src/JT808.Protocol/Interfaces/IJT808Config.cs @@ -63,7 +63,7 @@ namespace JT808.Protocol /// /// 记录仪工厂 /// - IJT808_Recorder_Factory IJT808_Recorder_Factory { get; set; } + IJT808_Recorder_Factory JT808_Recorder_Factory { get; set; } /// /// 统一编码 /// diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 7a4ea3c..7f40e9b 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -2613,6 +2613,11 @@ 只用来标识2019版本增删改情况 + + + 记录仪工厂 + + 消息流水号 @@ -2674,6 +2679,11 @@ 控制类型工厂 + + + 记录仪工厂 + + 统一编码 @@ -2712,6 +2722,105 @@ 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + + + 记录仪上行数据体 + + + + + 命令字 + + + + + 跳过数据体序列化 + 默认不跳过 + 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + + + + + 起始字头 + + + + + 命令字 + + + + + 保留字段 + + + + + 数据块长度 + + + + + 记录仪体下行数据体 + + + + + 校验字 + + + + + 记录仪上行数据体 + + + + + 命令字 + + + + + 跳过数据体序列化 + 默认不跳过 + 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + + + + + 行车记录仪上行数据包 + + + + + 起始字头 + + + + + 命令字 + + + + + 数据块长度 + + + + + 保留字段 + + + + + 记录仪体上行数据体 + + + + + 校验字 + + 日期限制于2000年 @@ -6722,6 +6831,113 @@ RSA 公钥{e,n}中的 n + + + 记录仪数据体 + + + + + 命令字 + + + + + 跳过数据体序列化 + 默认不跳过 + 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + + + + + 命令字 + + + + + 数据块长度 + + + + + 记录仪 + + + + + 起始字头 + + + + + 记录仪头部 + + + + + 保留字段 + + + + + 记录仪体 + + + + + 校验字 + + + + + 计算的异或校验码 + + + + + 跳过数据体序列化 + 默认不跳过 + 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + + + + + 计算校验码 + + + + + + + 计算校验码 + + + + + + + 采集记录仪执行标准版本 + 返回:记录仪执行标准的年号及修改单号 + + + + + 采集记录仪执行标准版本 + 返回:记录仪执行标准的年号及修改单号 + + + + + 记录仪执行标准年号后 2 位 BCD 码 + 无应答则默认为 03 + + + + + 修改单号 + 无修改单或无应答则默认为 00H + + 是否进行解码操作 diff --git a/src/JT808.Protocol/JT808CarDVRDownBodies.cs b/src/JT808.Protocol/JT808CarDVRDownBodies.cs new file mode 100644 index 0000000..5efdb5f --- /dev/null +++ b/src/JT808.Protocol/JT808CarDVRDownBodies.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol +{ + /// + /// 记录仪上行数据体 + /// + public abstract class JT808CarDVRDownBodies + { + /// + /// 命令字 + /// + public abstract byte CommandId { get; } + /// + /// 跳过数据体序列化 + /// 默认不跳过 + /// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + /// + public virtual bool SkipSerialization { get; set; } = false; + + public abstract string Description { get; } + } +} diff --git a/src/JT808.Protocol/JT808CarDVRDownPackage.cs b/src/JT808.Protocol/JT808CarDVRDownPackage.cs new file mode 100644 index 0000000..89dde68 --- /dev/null +++ b/src/JT808.Protocol/JT808CarDVRDownPackage.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol +{ + public class JT808CarDVRDownPackage + { + public const ushort BeginFlag = 0x557A; + /// + /// 起始字头 + /// + public ushort Begin { get; set; } = BeginFlag; + /// + /// 命令字 + /// + public byte CommandId { get; set; } + /// + /// 保留字段 + /// + public byte KeepFields { get; set; } = 0x00; + /// + /// 数据块长度 + /// + public ushort DataLength { get; set; } + /// + /// 记录仪体下行数据体 + /// + public JT808CarDVRDownBodies Bodies { get; set; } + /// + /// 校验字 + /// + public byte CheckCode { get; set; } + } +} diff --git a/src/JT808.Protocol/JT808CarDVRUpBodies.cs b/src/JT808.Protocol/JT808CarDVRUpBodies.cs new file mode 100644 index 0000000..9291325 --- /dev/null +++ b/src/JT808.Protocol/JT808CarDVRUpBodies.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol +{ + /// + /// 记录仪上行数据体 + /// + public abstract class JT808CarDVRUpBodies + { + /// + /// 命令字 + /// + public abstract byte CommandId { get; } + /// + /// 跳过数据体序列化 + /// 默认不跳过 + /// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + /// + public virtual bool SkipSerialization { get; set; } = false; + + public abstract string Description { get; } + } +} diff --git a/src/JT808.Protocol/JT808CarDVRUpPackage.cs b/src/JT808.Protocol/JT808CarDVRUpPackage.cs new file mode 100644 index 0000000..f03bf46 --- /dev/null +++ b/src/JT808.Protocol/JT808CarDVRUpPackage.cs @@ -0,0 +1,69 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; + +namespace JT808.Protocol +{ + /// + /// 行车记录仪上行数据包 + /// + public class JT808CarDVRUpPackage : IJT808MessagePackFormatter, IJT808Analyze + { + public const ushort BeginFlag = 0x557A; + /// + /// 起始字头 + /// + public ushort Begin { get; set; } = BeginFlag; + /// + /// 命令字 + /// + public byte CommandId { get; set; } + /// + /// 数据块长度 + /// + public ushort DataLength { get; set; } + /// + /// 保留字段 + /// + public byte KeepFields { get; set; } = 0x00; + /// + /// 记录仪体上行数据体 + /// + public JT808CarDVRUpBodies Bodies { get; set; } + /// + /// 校验字 + /// + public byte CheckCode { get; set; } + + public void Analyze(ref JT808MessagePackReader reader, Utf8JsonWriter writer, IJT808Config config) + { + throw new NotImplementedException(); + } + + public JT808CarDVRUpPackage Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808CarDVRUpPackage value = new JT808CarDVRUpPackage(); + int currentPosition = reader.ReaderCount; + value.Begin = reader.ReadUInt16(); + value.CommandId = reader.ReadByte(); + value.DataLength = reader.ReadUInt16(); + var carDVRCheckCode = reader.ReadCarDVRCheckCode(currentPosition, value.DataLength); + //todo:定义一个行车记录仪的异常和跳过校验的配置属性 + //比如:config.SkipCRCCode + //if (carDVRCheckCode.RealXorCheckCode != carDVRCheckCode.CalculateXorCheckCode) + value.KeepFields = reader.ReadByte(); + //todo:数据体 + value.CheckCode = reader.ReadByte(); + return value; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808CarDVRUpPackage value, IJT808Config config) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/JT808.Protocol/MessageBody/Recorder/JT808_Recorderpackage.cs b/src/JT808.Protocol/MessageBody/Recorder/JT808_Recorderpackage.cs index cf3a8eb..f9e6b93 100644 --- a/src/JT808.Protocol/MessageBody/Recorder/JT808_Recorderpackage.cs +++ b/src/JT808.Protocol/MessageBody/Recorder/JT808_Recorderpackage.cs @@ -61,7 +61,7 @@ namespace JT808.Protocol.MessageBody.Recorder value.KeepFields = reader.ReadByte(); if (value.JT808_RecorderHeader.DataLength > 0) { - if (config.IJT808_Recorder_Factory.Map.TryGetValue(value.JT808_RecorderHeader.CommandId, out var instance)) + if (config.JT808_Recorder_Factory.Map.TryGetValue(value.JT808_RecorderHeader.CommandId, out var instance)) { //4.2.处理消息体 value.JT808_RecorderBody = instance.Deserialize(ref reader, config); @@ -78,7 +78,7 @@ namespace JT808.Protocol.MessageBody.Recorder value.JT808_RecorderHeader.Serialize(ref writer, value.JT808_RecorderHeader, config); writer.WriteByte(value.KeepFields); if (value.JT808_RecorderHeader.DataLength > 0) { - if (config.IJT808_Recorder_Factory.Map.TryGetValue(value.JT808_RecorderHeader.CommandId, out var instance)) + if (config.JT808_Recorder_Factory.Map.TryGetValue(value.JT808_RecorderHeader.CommandId, out var instance)) { if (!instance.SkipSerialization) { diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs index 80d2b84..c09f0a3 100644 --- a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs @@ -235,6 +235,20 @@ namespace JT808.Protocol.MessagePack return hex; } + public (byte CalculateXorCheckCode, byte RealXorCheckCode) ReadCarDVRCheckCode(int currentPosition, int bodyLength) + { + //头+ 命令字 + 数据块长度+保留字 + //2 + 1 + 2 + 1 + var reader =Reader.Slice(currentPosition, currentPosition+ (2 + 1 + 2 + 1) +bodyLength); + byte calculateXorCheckCode = 0; + foreach (var item in reader) + { + calculateXorCheckCode = (byte)(calculateXorCheckCode ^ item); + } + var realXorCheckCode = Reader.Slice(currentPosition, currentPosition + (2 + 1 + 2 + 1) + bodyLength + 1)[0]; + return (calculateXorCheckCode, realXorCheckCode); + } + /// /// yyMMddHHmmss ///