@@ -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) | |||
@@ -63,7 +63,7 @@ namespace JT808.Protocol | |||
/// <summary> | |||
/// 记录仪工厂 | |||
/// </summary> | |||
IJT808_Recorder_Factory IJT808_Recorder_Factory { get; set; } | |||
IJT808_Recorder_Factory JT808_Recorder_Factory { get; set; } | |||
/// <summary> | |||
/// 统一编码 | |||
/// </summary> | |||
@@ -2613,6 +2613,11 @@ | |||
只用来标识2019版本增删改情况 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.Interfaces.IJT808_Recorder_Factory"> | |||
<summary> | |||
记录仪工厂 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.IJT808Config.MsgSNDistributed"> | |||
<summary> | |||
消息流水号 | |||
@@ -2674,6 +2679,11 @@ | |||
控制类型工厂 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.IJT808Config.JT808_Recorder_Factory"> | |||
<summary> | |||
记录仪工厂 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.IJT808Config.Encoding"> | |||
<summary> | |||
统一编码 | |||
@@ -2712,6 +2722,105 @@ | |||
当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.JT808CarDVRDownBodies"> | |||
<summary> | |||
记录仪上行数据体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownBodies.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownBodies.SkipSerialization"> | |||
<summary> | |||
跳过数据体序列化 | |||
默认不跳过 | |||
当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.Begin"> | |||
<summary> | |||
起始字头 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.KeepFields"> | |||
<summary> | |||
保留字段 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.DataLength"> | |||
<summary> | |||
数据块长度 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.Bodies"> | |||
<summary> | |||
记录仪体下行数据体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRDownPackage.CheckCode"> | |||
<summary> | |||
校验字 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.JT808CarDVRUpBodies"> | |||
<summary> | |||
记录仪上行数据体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpBodies.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpBodies.SkipSerialization"> | |||
<summary> | |||
跳过数据体序列化 | |||
默认不跳过 | |||
当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.JT808CarDVRUpPackage"> | |||
<summary> | |||
行车记录仪上行数据包 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.Begin"> | |||
<summary> | |||
起始字头 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.DataLength"> | |||
<summary> | |||
数据块长度 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.KeepFields"> | |||
<summary> | |||
保留字段 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.Bodies"> | |||
<summary> | |||
记录仪体上行数据体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.JT808CarDVRUpPackage.CheckCode"> | |||
<summary> | |||
校验字 | |||
</summary> | |||
</member> | |||
<member name="F:JT808.Protocol.JT808Constants.DateLimitYear"> | |||
<summary> | |||
日期限制于2000年 | |||
@@ -6722,6 +6831,113 @@ | |||
RSA 公钥{e,n}中的 n | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.MessageBody.Recorder.JT808_RecorderBody"> | |||
<summary> | |||
记录仪数据体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderBody.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderBody.SkipSerialization"> | |||
<summary> | |||
跳过数据体序列化 | |||
默认不跳过 | |||
当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderHeader.CommandId"> | |||
<summary> | |||
命令字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderHeader.DataLength"> | |||
<summary> | |||
数据块长度 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage"> | |||
<summary> | |||
记录仪 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.Begin"> | |||
<summary> | |||
起始字头 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.JT808_RecorderHeader"> | |||
<summary> | |||
记录仪头部 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.KeepFields"> | |||
<summary> | |||
保留字段 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.JT808_RecorderBody"> | |||
<summary> | |||
记录仪体 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.CheckCode"> | |||
<summary> | |||
校验字 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.CalculateCheckXorCode"> | |||
<summary> | |||
计算的异或校验码 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.SkipSerialization"> | |||
<summary> | |||
跳过数据体序列化 | |||
默认不跳过 | |||
当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
</summary> | |||
</member> | |||
<member name="M:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.CalculateXorCheckCode(JT808.Protocol.MessagePack.JT808MessagePackReader)"> | |||
<summary> | |||
计算校验码 | |||
</summary> | |||
<param name="readOnlySpan"></param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:JT808.Protocol.MessageBody.Recorder.JT808_RecorderPackage.CalculateXorCheckCode(System.ReadOnlySpan{System.Byte})"> | |||
<summary> | |||
计算校验码 | |||
</summary> | |||
<param name="xorReadOnlySpan"></param> | |||
<returns></returns> | |||
</member> | |||
<member name="T:JT808.Protocol.MessageBody.Recorder.JT808_Recorder_Down_0x00"> | |||
<summary> | |||
采集记录仪执行标准版本 | |||
返回:记录仪执行标准的年号及修改单号 | |||
</summary> | |||
</member> | |||
<member name="T:JT808.Protocol.MessageBody.Recorder.JT808_Recorder_Up_0x00"> | |||
<summary> | |||
采集记录仪执行标准版本 | |||
返回:记录仪执行标准的年号及修改单号 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_Recorder_Up_0x00.StandardYear"> | |||
<summary> | |||
记录仪执行标准年号后 2 位 BCD 码 | |||
无应答则默认为 03 | |||
</summary> | |||
</member> | |||
<member name="P:JT808.Protocol.MessageBody.Recorder.JT808_Recorder_Up_0x00.ModifyNumber"> | |||
<summary> | |||
修改单号 | |||
无修改单或无应答则默认为 00H | |||
</summary> | |||
</member> | |||
<member name="F:JT808.Protocol.MessagePack.JT808MessagePackReader._decoded"> | |||
<summary> | |||
是否进行解码操作 | |||
@@ -0,0 +1,25 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT808.Protocol | |||
{ | |||
/// <summary> | |||
/// 记录仪上行数据体 | |||
/// </summary> | |||
public abstract class JT808CarDVRDownBodies | |||
{ | |||
/// <summary> | |||
/// 命令字 | |||
/// </summary> | |||
public abstract byte CommandId { get; } | |||
/// <summary> | |||
/// 跳过数据体序列化 | |||
/// 默认不跳过 | |||
/// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
/// </summary> | |||
public virtual bool SkipSerialization { get; set; } = false; | |||
public abstract string Description { get; } | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT808.Protocol | |||
{ | |||
public class JT808CarDVRDownPackage | |||
{ | |||
public const ushort BeginFlag = 0x557A; | |||
/// <summary> | |||
/// 起始字头 | |||
/// </summary> | |||
public ushort Begin { get; set; } = BeginFlag; | |||
/// <summary> | |||
/// 命令字 | |||
/// </summary> | |||
public byte CommandId { get; set; } | |||
/// <summary> | |||
/// 保留字段 | |||
/// </summary> | |||
public byte KeepFields { get; set; } = 0x00; | |||
/// <summary> | |||
/// 数据块长度 | |||
/// </summary> | |||
public ushort DataLength { get; set; } | |||
/// <summary> | |||
/// 记录仪体下行数据体 | |||
/// </summary> | |||
public JT808CarDVRDownBodies Bodies { get; set; } | |||
/// <summary> | |||
/// 校验字 | |||
/// </summary> | |||
public byte CheckCode { get; set; } | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT808.Protocol | |||
{ | |||
/// <summary> | |||
/// 记录仪上行数据体 | |||
/// </summary> | |||
public abstract class JT808CarDVRUpBodies | |||
{ | |||
/// <summary> | |||
/// 命令字 | |||
/// </summary> | |||
public abstract byte CommandId { get; } | |||
/// <summary> | |||
/// 跳过数据体序列化 | |||
/// 默认不跳过 | |||
/// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 | |||
/// </summary> | |||
public virtual bool SkipSerialization { get; set; } = false; | |||
public abstract string Description { get; } | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 行车记录仪上行数据包 | |||
/// </summary> | |||
public class JT808CarDVRUpPackage : IJT808MessagePackFormatter<JT808CarDVRUpPackage>, IJT808Analyze | |||
{ | |||
public const ushort BeginFlag = 0x557A; | |||
/// <summary> | |||
/// 起始字头 | |||
/// </summary> | |||
public ushort Begin { get; set; } = BeginFlag; | |||
/// <summary> | |||
/// 命令字 | |||
/// </summary> | |||
public byte CommandId { get; set; } | |||
/// <summary> | |||
/// 数据块长度 | |||
/// </summary> | |||
public ushort DataLength { get; set; } | |||
/// <summary> | |||
/// 保留字段 | |||
/// </summary> | |||
public byte KeepFields { get; set; } = 0x00; | |||
/// <summary> | |||
/// 记录仪体上行数据体 | |||
/// </summary> | |||
public JT808CarDVRUpBodies Bodies { get; set; } | |||
/// <summary> | |||
/// 校验字 | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
} |
@@ -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) | |||
{ | |||
@@ -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); | |||
} | |||
/// <summary> | |||
/// yyMMddHHmmss | |||
/// </summary> | |||