diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..026380e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+language: csharp
+solution: JTActiveSafety.sln
+dotnet: 2.2.101
+os: linux
+mono: none
+dist: trusty2
+script:
+ - dotnet restore src/JTActiveSafety.sln
+ - dotnet build src/JTActiveSafety.Protocol.Test/JTActiveSafety.Protocol.Test.csproj
+ - dotnet test src/JTActiveSafety.Protocol.Test/JTActiveSafety.Protocol.Test.csproj
+ - dotnet build src/JT808.Protocol.Extensions.JTActiveSafety.Test/JT808.Protocol.Extensions.JTActiveSafety.Test.csproj
+ - dotnet test src/JT808.Protocol.Extensions.JTActiveSafety.Test/JT808.Protocol.Extensions.JTActiveSafety.Test.csproj
+after_success:
+ - echo successful build!
+branches:
+ only:
+ - master
diff --git a/README.md b/README.md
index ff4858a..d13a50a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,23 @@
# JTActiveSafety
-JTActiveSafety协议、道路运输车辆主动安全智能防控系统-主动安全通讯协议
+
+JTActiveSafety协议、道路运输车辆主动安全智能防控系统-主动安全通讯协议主要分为两大部分。
+
+1. 设备终端到平台的通信也就是JT808
+2. 设备终端上传的附件数据也就是附件服务器
+
+[](https://github.com/SmallChi/JTActiveSafety/blob/master/LICENSE)[](https://travis-ci.org/SmallChi/JTActiveSafety)
+
+## 基于JT808扩展的JTActiveSafety消息协议
+
+### JT808扩展协议消息对照表
+
+| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 |
+| :---: | :---: | :---: | :---: | :---:|
+
+### 使用方法
+
+```dotnet
+IServiceCollection serviceDescriptors1 = new ServiceCollection();
+serviceDescriptors1.AddJT808Configure()
+ .AddJTActiveSafetyConfigure();
+```
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety.Test/JT808.Protocol.Extensions.JTActiveSafety.Test.csproj b/src/JT808.Protocol.Extensions.JTActiveSafety.Test/JT808.Protocol.Extensions.JTActiveSafety.Test.csproj
new file mode 100644
index 0000000..501a5ce
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety.Test/JT808.Protocol.Extensions.JTActiveSafety.Test.csproj
@@ -0,0 +1,15 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Enums/JT808_JTActiveSafety_MsgId.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Enums/JT808_JTActiveSafety_MsgId.cs
new file mode 100644
index 0000000..f9d4963
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Enums/JT808_JTActiveSafety_MsgId.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Enums
+{
+ public enum JT808_JTActiveSafety_MsgId : ushort
+ {
+ 报警附件信息消息= 0x1210,
+ 文件信息上传= 0x1211,
+ 文件上传完成消息 = 0x1212,
+ 报警附件上传指令 = 0x9208,
+ 文件上传完成消息应答 = 0x9212,
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x64_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x64_Formatter.cs
new file mode 100644
index 0000000..4502579
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x64_Formatter.cs
@@ -0,0 +1,59 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x0200_0x64_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x0200_0x64 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x0200_0x64 jT808_0X0200_0X64 = new JT808_0x0200_0x64();
+ jT808_0X0200_0X64.AttachInfoId = reader.ReadByte();
+ jT808_0X0200_0X64.AttachInfoLength = reader.ReadByte();
+ jT808_0X0200_0X64.AlarmId = reader.ReadUInt32();
+ jT808_0X0200_0X64.FlagState = reader.ReadByte();
+ jT808_0X0200_0X64.AlarmOrEventType = reader.ReadByte();
+ jT808_0X0200_0X64.AlarmLevel = reader.ReadByte();
+ jT808_0X0200_0X64.VehicleSpeed = reader.ReadByte();
+ jT808_0X0200_0X64.CarOrPedestrianDistanceAhead = reader.ReadByte();
+ jT808_0X0200_0X64.DeviateType = reader.ReadByte();
+ jT808_0X0200_0X64.RoadSignIdentificationType = reader.ReadByte();
+ jT808_0X0200_0X64.RoadSignIdentificationData = reader.ReadByte();
+ jT808_0X0200_0X64.Speed = reader.ReadByte();
+ jT808_0X0200_0X64.Altitude = reader.ReadUInt16();
+ jT808_0X0200_0X64.Latitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X64.Longitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X64.AlarmTime = reader.ReadDateTime6();
+ jT808_0X0200_0X64.VehicleState = reader.ReadUInt16();
+ jT808_0X0200_0X64.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ return jT808_0X0200_0X64;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x64 value, IJT808Config config)
+ {
+ writer.WriteByte(value.AttachInfoId);
+ writer.WriteByte(value.AttachInfoLength);
+ writer.WriteUInt32(value.AlarmId);
+ writer.WriteByte(value.FlagState);
+ writer.WriteByte(value.AlarmOrEventType);
+ writer.WriteByte(value.AlarmLevel);
+ writer.WriteByte(value.VehicleSpeed);
+ writer.WriteByte(value.CarOrPedestrianDistanceAhead);
+ writer.WriteByte(value.DeviateType);
+ writer.WriteByte(value.RoadSignIdentificationType);
+ writer.WriteByte(value.RoadSignIdentificationData);
+ writer.WriteByte(value.Speed);
+ writer.WriteUInt16(value.Altitude);
+ writer.WriteUInt32((uint)value.Latitude);
+ writer.WriteUInt32((uint)value.Longitude);
+ writer.WriteDateTime6(value.AlarmTime);
+ writer.WriteUInt16(value.VehicleState);
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x65_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x65_Formatter.cs
new file mode 100644
index 0000000..a2e85f8
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x65_Formatter.cs
@@ -0,0 +1,57 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x0200_0x65_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x0200_0x65 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x0200_0x65 jT808_0X0200_0X65 = new JT808_0x0200_0x65();
+ jT808_0X0200_0X65.AttachInfoId = reader.ReadByte();
+ jT808_0X0200_0X65.AttachInfoLength = reader.ReadByte();
+ jT808_0X0200_0X65.AlarmId = reader.ReadUInt32();
+ jT808_0X0200_0X65.FlagState = reader.ReadByte();
+ jT808_0X0200_0X65.AlarmOrEventType = reader.ReadByte();
+ jT808_0X0200_0X65.AlarmLevel = reader.ReadByte();
+ jT808_0X0200_0X65.Fatigue = reader.ReadByte();
+ jT808_0X0200_0X65.Retain = reader.ReadArray(4).ToArray();
+ jT808_0X0200_0X65.Speed = reader.ReadByte();
+ jT808_0X0200_0X65.Altitude = reader.ReadUInt16();
+ jT808_0X0200_0X65.Latitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X65.Longitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X65.AlarmTime = reader.ReadDateTime6();
+ jT808_0X0200_0X65.VehicleState = reader.ReadUInt16();
+ jT808_0X0200_0X65.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ return jT808_0X0200_0X65;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x65 value, IJT808Config config)
+ {
+ writer.WriteByte(value.AttachInfoId);
+ writer.WriteByte(value.AttachInfoLength);
+ writer.WriteUInt32(value.AlarmId);
+ writer.WriteByte(value.FlagState);
+ writer.WriteByte(value.AlarmOrEventType);
+ writer.WriteByte(value.AlarmLevel);
+ writer.WriteByte(value.Fatigue);
+ if (value.Retain.Length != 4)
+ {
+ throw new ArgumentOutOfRangeException($"{nameof(JT808_0x0200_0x65.Retain)} length==4");
+ }
+ writer.WriteArray(value.Retain);
+ writer.WriteByte(value.Speed);
+ writer.WriteUInt16(value.Altitude);
+ writer.WriteUInt32((uint)value.Latitude);
+ writer.WriteUInt32((uint)value.Longitude);
+ writer.WriteDateTime6(value.AlarmTime);
+ writer.WriteUInt16(value.VehicleState);
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x66_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x66_Formatter.cs
new file mode 100644
index 0000000..2842afa
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x66_Formatter.cs
@@ -0,0 +1,73 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x0200_0x66_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x0200_0x66 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x0200_0x66 jT808_0X0200_0X66 = new JT808_0x0200_0x66();
+ jT808_0X0200_0X66.AttachInfoId = reader.ReadByte();
+ jT808_0X0200_0X66.AttachInfoLength = reader.ReadByte();
+ jT808_0X0200_0X66.AlarmId = reader.ReadUInt32();
+ jT808_0X0200_0X66.FlagState = reader.ReadByte();
+ jT808_0X0200_0X66.Speed = reader.ReadByte();
+ jT808_0X0200_0X66.Altitude = reader.ReadUInt16();
+ jT808_0X0200_0X66.Latitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X66.Longitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X66.AlarmTime = reader.ReadDateTime6();
+ jT808_0X0200_0X66.VehicleState = reader.ReadUInt16();
+ jT808_0X0200_0X66.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ jT808_0X0200_0X66.AlarmOrEventCount = reader.ReadByte();
+ if (jT808_0X0200_0X66.AlarmOrEventCount > 0)
+ {
+ jT808_0X0200_0X66.AlarmOrEvents = new List();
+ for(int i=0;i< jT808_0X0200_0X66.AlarmOrEventCount; i++)
+ {
+ AlarmOrEventProperty alarmOrEventProperty = new AlarmOrEventProperty();
+ alarmOrEventProperty.TirePressureAlarmPosition = reader.ReadByte();
+ alarmOrEventProperty.AlarmOrEventType = reader.ReadUInt16();
+ alarmOrEventProperty.TirePressure = reader.ReadUInt16();
+ alarmOrEventProperty.TireTemperature = reader.ReadUInt16();
+ alarmOrEventProperty.BatteryLevel = reader.ReadUInt16();
+ jT808_0X0200_0X66.AlarmOrEvents.Add(alarmOrEventProperty);
+ }
+ }
+ return jT808_0X0200_0X66;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x66 value, IJT808Config config)
+ {
+ writer.WriteByte(value.AttachInfoId);
+ writer.Skip(1, out int AttachInfoLengthPosition);
+ writer.WriteUInt32(value.AlarmId);
+ writer.WriteByte(value.FlagState);
+ writer.WriteByte(value.Speed);
+ writer.WriteUInt16(value.Altitude);
+ writer.WriteUInt32((uint)value.Latitude);
+ writer.WriteUInt32((uint)value.Longitude);
+ writer.WriteDateTime6(value.AlarmTime);
+ writer.WriteUInt16(value.VehicleState);
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ if (value.AlarmOrEvents.Count > 0)
+ {
+ writer.WriteByte((byte)value.AlarmOrEvents.Count);
+ foreach(var item in value.AlarmOrEvents)
+ {
+ writer.WriteByte(item.TirePressureAlarmPosition);
+ writer.WriteUInt16(item.AlarmOrEventType);
+ writer.WriteUInt16(item.TirePressure);
+ writer.WriteUInt16(item.TireTemperature);
+ writer.WriteUInt16(item.BatteryLevel);
+ }
+ }
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - AttachInfoLengthPosition - 1), AttachInfoLengthPosition);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x67_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x67_Formatter.cs
new file mode 100644
index 0000000..94c0d67
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x0200_0x67_Formatter.cs
@@ -0,0 +1,49 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x0200_0x67_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x0200_0x67 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x0200_0x67 jT808_0X0200_0X67 = new JT808_0x0200_0x67();
+ jT808_0X0200_0X67.AttachInfoId = reader.ReadByte();
+ jT808_0X0200_0X67.AttachInfoLength = reader.ReadByte();
+ jT808_0X0200_0X67.AlarmId = reader.ReadUInt32();
+ jT808_0X0200_0X67.FlagState = reader.ReadByte();
+ jT808_0X0200_0X67.AlarmOrEventType = reader.ReadByte();
+ jT808_0X0200_0X67.AlarmLevel = reader.ReadByte();
+ jT808_0X0200_0X67.Speed = reader.ReadByte();
+ jT808_0X0200_0X67.Altitude = reader.ReadUInt16();
+ jT808_0X0200_0X67.Latitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X67.Longitude = (int)reader.ReadUInt32();
+ jT808_0X0200_0X67.AlarmTime = reader.ReadDateTime6();
+ jT808_0X0200_0X67.VehicleState = reader.ReadUInt16();
+ jT808_0X0200_0X67.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ return jT808_0X0200_0X67;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x67 value, IJT808Config config)
+ {
+ writer.WriteByte(value.AttachInfoId);
+ writer.WriteByte(value.AttachInfoLength);
+ writer.WriteUInt32(value.AlarmId);
+ writer.WriteByte(value.FlagState);
+ writer.WriteByte(value.AlarmOrEventType);
+ writer.WriteByte(value.AlarmLevel);
+ writer.WriteByte(value.Speed);
+ writer.WriteUInt16(value.Altitude);
+ writer.WriteUInt32((uint)value.Latitude);
+ writer.WriteUInt32((uint)value.Longitude);
+ writer.WriteDateTime6(value.AlarmTime);
+ writer.WriteUInt16(value.VehicleState);
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1210_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1210_Formatter.cs
new file mode 100644
index 0000000..dd00932
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1210_Formatter.cs
@@ -0,0 +1,58 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x1210_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x1210 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x1210 jT808_0X1210 = new JT808_0x1210();
+ jT808_0X1210.TerminalID = reader.ReadString(7);
+ jT808_0X1210.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ jT808_0X1210.AlarmId = reader.ReadString(32);
+ jT808_0X1210.InfoType = reader.ReadByte();
+ jT808_0X1210.AttachCount = reader.ReadByte();
+ if (jT808_0X1210.AttachCount > 0)
+ {
+ jT808_0X1210.AttachInfos = new List();
+ for(int i=0;i< jT808_0X1210.AttachCount; i++)
+ {
+ AttachProperty attachProperty = new AttachProperty();
+ attachProperty.FileNameLength= reader.ReadByte();
+ attachProperty.FileName= reader.ReadString(attachProperty.FileNameLength);
+ attachProperty.FileSize= reader.ReadUInt32();
+ jT808_0X1210.AttachInfos.Add(attachProperty);
+ }
+ }
+ return jT808_0X1210;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x1210 value, IJT808Config config)
+ {
+ writer.WriteString(value.TerminalID.PadRight(7,'0'));
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ writer.WriteString(value.AlarmId);
+ writer.WriteByte(value.InfoType);
+ if(value.AttachInfos!=null && value.AttachInfos.Count > 0)
+ {
+ foreach(var item in value.AttachInfos)
+ {
+ writer.Skip(1, out int FileNameLengthPosition);
+ writer.WriteString(item.FileName);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - FileNameLengthPosition - 1), FileNameLengthPosition);
+ writer.WriteUInt32(item.FileSize);
+ }
+ }
+ else
+ {
+ writer.WriteByte(0);
+ }
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1211_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1211_Formatter.cs
new file mode 100644
index 0000000..55c2bf1
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1211_Formatter.cs
@@ -0,0 +1,32 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x1211_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x1211 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x1211 jT808_0X1211 = new JT808_0x1211();
+ jT808_0X1211.FileNameLength= reader.ReadByte();
+ jT808_0X1211.FileName= reader.ReadString(jT808_0X1211.FileNameLength);
+ jT808_0X1211.FileType = reader.ReadByte();
+ jT808_0X1211.FileSize= reader.ReadUInt32();
+ return jT808_0X1211;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x1211 value, IJT808Config config)
+ {
+ writer.Skip(1, out int FileNameLengthPosition);
+ writer.WriteString(value.FileName);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - FileNameLengthPosition - 1), FileNameLengthPosition);
+ writer.WriteByte(value.FileType);
+ writer.WriteUInt32(value.FileSize);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1212_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1212_Formatter.cs
new file mode 100644
index 0000000..b7f13d8
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x1212_Formatter.cs
@@ -0,0 +1,32 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x1212_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x1212 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x1212 jT808_0X1212 = new JT808_0x1212();
+ jT808_0X1212.FileNameLength= reader.ReadByte();
+ jT808_0X1212.FileName= reader.ReadString(jT808_0X1212.FileNameLength);
+ jT808_0X1212.FileType = reader.ReadByte();
+ jT808_0X1212.FileSize= reader.ReadUInt32();
+ return jT808_0X1212;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x1212 value, IJT808Config config)
+ {
+ writer.Skip(1, out int FileNameLengthPosition);
+ writer.WriteString(value.FileName);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - FileNameLengthPosition - 1), FileNameLengthPosition);
+ writer.WriteByte(value.FileType);
+ writer.WriteUInt32(value.FileSize);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9208_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9208_Formatter.cs
new file mode 100644
index 0000000..c4a6b13
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9208_Formatter.cs
@@ -0,0 +1,38 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x9208_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x9208 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x9208 jT808_0X9208 = new JT808_0x9208();
+ jT808_0X9208.AttachmentServerIPLength = reader.ReadByte();
+ jT808_0X9208.AttachmentServerIP = reader.ReadString(jT808_0X9208.AttachmentServerIPLength);
+ jT808_0X9208.AttachmentServerIPTcpPort = reader.ReadUInt16();
+ jT808_0X9208.AttachmentServerIPUdpPort = reader.ReadUInt16();
+ jT808_0X9208.AlarmIdentification = JT808_AlarmIdentificationProperty_Formatter.Instance.Deserialize(ref reader, config);
+ jT808_0X9208.AlarmId = reader.ReadString(32);
+ jT808_0X9208.Retain = reader.ReadArray(16).ToArray();
+ return jT808_0X9208;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x9208 value, IJT808Config config)
+ {
+ writer.Skip(1, out int AttachmentServerIPLengthPosition);
+ writer.WriteString(value.AttachmentServerIP);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition()- AttachmentServerIPLengthPosition-1), AttachmentServerIPLengthPosition);
+ writer.WriteUInt16(value.AttachmentServerIPTcpPort);
+ writer.WriteUInt16(value.AttachmentServerIPUdpPort);
+ JT808_AlarmIdentificationProperty_Formatter.Instance.Serialize(ref writer, value.AlarmIdentification, config);
+ writer.WriteString(value.AlarmId);
+ writer.WriteArray(value.Retain);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9212_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9212_Formatter.cs
new file mode 100644
index 0000000..c39231e
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_0x9212_Formatter.cs
@@ -0,0 +1,57 @@
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_0x9212_Formatter : IJT808MessagePackFormatter
+ {
+ public JT808_0x9212 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x9212 jT808_0X9212 = new JT808_0x9212();
+ jT808_0X9212.FileNameLength = reader.ReadByte();
+ jT808_0X9212.FileName = reader.ReadString(jT808_0X9212.FileNameLength);
+ jT808_0X9212.FileType = reader.ReadByte();
+ jT808_0X9212.UploadResult = reader.ReadByte();
+ jT808_0X9212.DataPackageCount= reader.ReadByte();
+ if (jT808_0X9212.DataPackageCount > 0)
+ {
+ jT808_0X9212.DataPackages = new List();
+ for(int i=0;i< jT808_0X9212.DataPackageCount; i++)
+ {
+ DataPackageProperty dataPackageProperty = new DataPackageProperty();
+ dataPackageProperty.Offset = reader.ReadUInt32();
+ dataPackageProperty.Length = reader.ReadUInt32();
+ jT808_0X9212.DataPackages.Add(dataPackageProperty);
+ }
+ }
+ return jT808_0X9212;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x9212 value, IJT808Config config)
+ {
+ writer.Skip(1, out int FileNameLengthPosition);
+ writer.WriteString(value.FileName);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - FileNameLengthPosition - 1), FileNameLengthPosition);
+ writer.WriteByte(value.FileType);
+ writer.WriteByte(value.UploadResult);
+ if(value.DataPackages!=null && value.DataPackages.Count > 0)
+ {
+ writer.WriteByte((byte)value.DataPackages.Count);
+ foreach (var item in value.DataPackages)
+ {
+ writer.WriteUInt32(item.Offset);
+ writer.WriteUInt32(item.Length);
+ }
+ }
+ else
+ {
+ writer.WriteByte(0);
+ }
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_AlarmIdentificationProperty_Formatter.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_AlarmIdentificationProperty_Formatter.cs
new file mode 100644
index 0000000..d7ed177
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Formatters/JT808_AlarmIdentificationProperty_Formatter.cs
@@ -0,0 +1,37 @@
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Formatters
+{
+ public class JT808_AlarmIdentificationProperty_Formatter : IJT808MessagePackFormatter
+ {
+ public readonly static JT808_AlarmIdentificationProperty_Formatter Instance = new JT808_AlarmIdentificationProperty_Formatter();
+ public AlarmIdentificationProperty Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ AlarmIdentificationProperty alarmIdentification = new AlarmIdentificationProperty();
+ alarmIdentification.TerminalID = reader.ReadString(7);
+ alarmIdentification.Time = reader.ReadDateTime6();
+ alarmIdentification.SN = reader.ReadByte();
+ alarmIdentification.AttachCount = reader.ReadByte();
+ alarmIdentification.Retain = reader.ReadByte();
+ return alarmIdentification;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, AlarmIdentificationProperty value, IJT808Config config)
+ {
+ if (value == null)
+ {
+ throw new NullReferenceException($"{nameof(AlarmIdentificationProperty)}不为空");
+ }
+ writer.WriteString(value.TerminalID);
+ writer.WriteDateTime6(value.Time);
+ writer.WriteByte(value.SN);
+ writer.WriteByte(value.AttachCount);
+ writer.WriteByte(value.Retain);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/JT808.Protocol.Extensions.JTActiveSafety.csproj b/src/JT808.Protocol.Extensions.JTActiveSafety/JT808.Protocol.Extensions.JTActiveSafety.csproj
index 1df4b06..cc270aa 100644
--- a/src/JT808.Protocol.Extensions.JTActiveSafety/JT808.Protocol.Extensions.JTActiveSafety.csproj
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/JT808.Protocol.Extensions.JTActiveSafety.csproj
@@ -2,6 +2,21 @@
netstandard2.0
+ 7.3
+ Copyright 2019.
+ SmallChi(Koike)
+ JT808.Protocol.Extensions.JTActiveSafety
+ JT808.Protocol.Extensions.JTActiveSafety
+ 基于JT808协议、GB808协议扩展的主动安全消息协议
+ 基于JT808协议、GB808协议扩展的主动安全消息协议
+ true
+ https://github.com/SmallChi/JTActiveSafety
+ https://github.com/SmallChi/JTActiveSafety
+ https://github.com/SmallChi/JTActiveSafety/blob/master/LICENSE
+ https://github.com/SmallChi/JTActiveSafety/blob/master/LICENSE
+ false
+ 2.1.6
+ LICENSE
@@ -9,7 +24,12 @@
-
+
+ True
+
+
+
+
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/JTActiveSafetyDependencyInjectionExtensions.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/JTActiveSafetyDependencyInjectionExtensions.cs
new file mode 100644
index 0000000..facbb1e
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/JTActiveSafetyDependencyInjectionExtensions.cs
@@ -0,0 +1,33 @@
+using JT808.Protocol.Extensions.JTActiveSafety.Enums;
+using JT808.Protocol.Extensions.JTActiveSafety.MessageBody;
+using JT808.Protocol.Interfaces;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety
+{
+ public static class JTActiveSafetyDependencyInjectionExtensions
+ {
+ public static IJT808Builder AddJTActiveSafetyConfigure(this IJT808Builder jT808Builder)
+ {
+ jT808Builder.Config.Register(Assembly.GetExecutingAssembly());
+ jT808Builder.Config.MsgIdFactory.SetMap((ushort)JT808_JTActiveSafety_MsgId.报警附件信息消息, "");
+ jT808Builder.Config.MsgIdFactory.SetMap((ushort)JT808_JTActiveSafety_MsgId.文件信息上传, "");
+ jT808Builder.Config.MsgIdFactory.SetMap((ushort)JT808_JTActiveSafety_MsgId.文件上传完成消息, "");
+ jT808Builder.Config.MsgIdFactory.SetMap((ushort)JT808_JTActiveSafety_MsgId.报警附件上传指令, "");
+ jT808Builder.Config.MsgIdFactory.SetMap((ushort)JT808_JTActiveSafety_MsgId.文件上传完成消息应答, "");
+ jT808Builder.Config.JT808_0X0200_Factory.JT808LocationAttachMethod.Add(JT808_JTActiveSafety_Constants.JT808_0X0200_0x64, typeof(JT808_0x0200_0x64));
+ jT808Builder.Config.JT808_0X0200_Factory.JT808LocationAttachMethod.Add(JT808_JTActiveSafety_Constants.JT808_0X0200_0x65, typeof(JT808_0x0200_0x65));
+ jT808Builder.Config.JT808_0X0200_Factory.JT808LocationAttachMethod.Add(JT808_JTActiveSafety_Constants.JT808_0X0200_0x66, typeof(JT808_0x0200_0x66));
+ jT808Builder.Config.JT808_0X0200_Factory.JT808LocationAttachMethod.Add(JT808_JTActiveSafety_Constants.JT808_0X0200_0x67, typeof(JT808_0x0200_0x67));
+ jT808Builder.Config.JT808_0X8103_Factory.ParamMethods.Add(JT808_JTActiveSafety_Constants.JT808_0X8103_0xF364, typeof(JT808_0x8103_0xF364));
+ jT808Builder.Config.JT808_0X8103_Factory.ParamMethods.Add(JT808_JTActiveSafety_Constants.JT808_0X8103_0xF365, typeof(JT808_0x8103_0xF365));
+ jT808Builder.Config.JT808_0X8103_Factory.ParamMethods.Add(JT808_JTActiveSafety_Constants.JT808_0X8103_0xF366, typeof(JT808_0x8103_0xF366));
+ jT808Builder.Config.JT808_0X8103_Factory.ParamMethods.Add(JT808_JTActiveSafety_Constants.JT808_0X8103_0xF367, typeof(JT808_0x8103_0xF367));
+ return jT808Builder;
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x64.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x64.cs
new file mode 100644
index 0000000..015410a
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x64.cs
@@ -0,0 +1,86 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.MessageBody;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 高级驾驶辅助系统报警信息
+ ///
+ [JT808Formatter(typeof(JT808_0x0200_0x64_Formatter))]
+ public class JT808_0x0200_0x64 : JT808_0x0200_BodyBase
+ {
+ public override byte AttachInfoId { get; set; } = 0x64;
+ public override byte AttachInfoLength { get; set; } = 32;
+ ///
+ /// 报警ID
+ ///
+ public uint AlarmId { get; set; }
+ ///
+ /// 标志状态
+ ///
+ public byte FlagState { get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmOrEventType{ get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmLevel { get; set; }
+ ///
+ /// 前车车速
+ ///
+ public byte VehicleSpeed { get; set; }
+ ///
+ /// 前车/行人距离
+ ///
+ public byte CarOrPedestrianDistanceAhead { get; set; }
+ ///
+ /// 偏离类型
+ ///
+ public byte DeviateType { get; set; }
+ ///
+ /// 道路标志识别类型
+ ///
+ public byte RoadSignIdentificationType { get; set; }
+ ///
+ /// 道路标志识别类型
+ ///
+ public byte RoadSignIdentificationData { get; set; }
+ ///
+ /// 车速
+ ///
+ public byte Speed { get; set; }
+ ///
+ /// 高程
+ ///
+ public ushort Altitude { get; set; }
+ ///
+ /// 纬度
+ ///
+ public int Latitude { get; set; }
+ ///
+ /// 经度
+ ///
+ public int Longitude { get; set; }
+ ///
+ /// 日期时间
+ /// YYMMDDhhmmss
+ /// BCD[6]
+ ///
+ public DateTime AlarmTime { get; set; }
+ ///
+ /// 车辆状态
+ ///
+ public ushort VehicleState { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x65.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x65.cs
new file mode 100644
index 0000000..1321da3
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x65.cs
@@ -0,0 +1,74 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.MessageBody;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 驾驶员状态监测系统报警信息
+ ///
+ [JT808Formatter(typeof(JT808_0x0200_0x65_Formatter))]
+ public class JT808_0x0200_0x65 : JT808_0x0200_BodyBase
+ {
+ public override byte AttachInfoId { get; set; } = 0x65;
+ public override byte AttachInfoLength { get; set; } = 32;
+ ///
+ /// 报警ID
+ ///
+ public uint AlarmId { get; set; }
+ ///
+ /// 标志状态
+ ///
+ public byte FlagState { get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmOrEventType{ get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmLevel { get; set; }
+ ///
+ /// 疲劳程度
+ ///
+ public byte Fatigue { get; set; }
+ ///
+ /// 预留
+ ///
+ public byte[] Retain { get; set; } = new byte[4];
+ ///
+ /// 车速
+ ///
+ public byte Speed { get; set; }
+ ///
+ /// 高程
+ ///
+ public ushort Altitude { get; set; }
+ ///
+ /// 纬度
+ ///
+ public int Latitude { get; set; }
+ ///
+ /// 经度
+ ///
+ public int Longitude { get; set; }
+ ///
+ /// 日期时间
+ /// YYMMDDhhmmss
+ /// BCD[6]
+ ///
+ public DateTime AlarmTime { get; set; }
+ ///
+ /// 车辆状态
+ ///
+ public ushort VehicleState { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x66.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x66.cs
new file mode 100644
index 0000000..e72a4f9
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x66.cs
@@ -0,0 +1,66 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.MessageBody;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 胎压监测系统报警信息
+ ///
+ [JT808Formatter(typeof(JT808_0x0200_0x66_Formatter))]
+ public class JT808_0x0200_0x66 : JT808_0x0200_BodyBase
+ {
+ public override byte AttachInfoId { get; set; } = 0x66;
+ public override byte AttachInfoLength { get; set; }
+ ///
+ /// 报警ID
+ ///
+ public uint AlarmId { get; set; }
+ ///
+ /// 标志状态
+ ///
+ public byte FlagState { get; set; }
+ ///
+ /// 车速
+ ///
+ public byte Speed { get; set; }
+ ///
+ /// 高程
+ ///
+ public ushort Altitude { get; set; }
+ ///
+ /// 纬度
+ ///
+ public int Latitude { get; set; }
+ ///
+ /// 经度
+ ///
+ public int Longitude { get; set; }
+ ///
+ /// 日期时间
+ /// YYMMDDhhmmss
+ /// BCD[6]
+ ///
+ public DateTime AlarmTime { get; set; }
+ ///
+ /// 车辆状态
+ ///
+ public ushort VehicleState { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ ///
+ /// 报警/事件列表总数
+ ///
+ public byte AlarmOrEventCount { get; set; }
+ ///
+ /// 报警/事件信息列表
+ ///
+ public List AlarmOrEvents { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x67.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x67.cs
new file mode 100644
index 0000000..995f462
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x0200_0x67.cs
@@ -0,0 +1,66 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using JT808.Protocol.MessageBody;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 盲区监测系统报警信息
+ ///
+ [JT808Formatter(typeof(JT808_0x0200_0x67_Formatter))]
+ public class JT808_0x0200_0x67 : JT808_0x0200_BodyBase
+ {
+ public override byte AttachInfoId { get; set; } = 0x67;
+ public override byte AttachInfoLength { get; set; } = 26;
+ ///
+ /// 报警ID
+ ///
+ public uint AlarmId { get; set; }
+ ///
+ /// 标志状态
+ ///
+ public byte FlagState { get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmOrEventType{ get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public byte AlarmLevel { get; set; }
+ ///
+ /// 车速
+ ///
+ public byte Speed { get; set; }
+ ///
+ /// 高程
+ ///
+ public ushort Altitude { get; set; }
+ ///
+ /// 纬度
+ ///
+ public int Latitude { get; set; }
+ ///
+ /// 经度
+ ///
+ public int Longitude { get; set; }
+ ///
+ /// 日期时间
+ /// YYMMDDhhmmss
+ /// BCD[6]
+ ///
+ public DateTime AlarmTime { get; set; }
+ ///
+ /// 车辆状态
+ ///
+ public ushort VehicleState { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1210.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1210.cs
new file mode 100644
index 0000000..4c86c06
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1210.cs
@@ -0,0 +1,45 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 报警附件信息消息
+ ///
+ [JT808Formatter(typeof(JT808_0x1210_Formatter))]
+ public class JT808_0x1210:JT808Bodies
+ {
+ ///
+ /// 终端ID
+ /// 7 个字节,由大写字母和数字组成,此终端ID 由制造商自行定义,位数不足时,后补“0x00”
+ ///
+ public string TerminalID { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ ///
+ /// 平台给报警分配的唯一编号
+ /// 32
+ ///
+ public string AlarmId { get; set; }
+ ///
+ /// 信息类型
+ /// 0x00:正常报警文件信息
+ /// 0x01:补传报警文件信息
+ ///
+ public byte InfoType { get; set; }
+ ///
+ /// 附件数量
+ ///
+ public byte AttachCount { get; set; }
+ ///
+ /// 附件信息列表
+ ///
+ public List AttachInfos { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1211.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1211.cs
new file mode 100644
index 0000000..d2c0184
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1211.cs
@@ -0,0 +1,33 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 文件信息上传
+ ///
+ [JT808Formatter(typeof(JT808_0x1211_Formatter))]
+ public class JT808_0x1211 : JT808Bodies
+ {
+ ///
+ /// 文件名称长度
+ ///
+ public byte FileNameLength { get; set; }
+ ///
+ /// 文件名称
+ /// <文件类型>_<通道号>_<报警类型>_<序号>_<报警编号>.<后缀名>
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 文件类型
+ ///
+ public byte FileType { get; set; }
+ ///
+ /// 文件大小
+ ///
+ public uint FileSize { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1212.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1212.cs
new file mode 100644
index 0000000..d5a1626
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x1212.cs
@@ -0,0 +1,33 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 文件上传完成消息
+ ///
+ [JT808Formatter(typeof(JT808_0x1212_Formatter))]
+ public class JT808_0x1212 : JT808Bodies
+ {
+ ///
+ /// 文件名称长度
+ ///
+ public byte FileNameLength { get; set; }
+ ///
+ /// 文件名称
+ /// <文件类型>_<通道号>_<报警类型>_<序号>_<报警编号>.<后缀名>
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 文件类型
+ ///
+ public byte FileType { get; set; }
+ ///
+ /// 文件大小
+ ///
+ public uint FileSize { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9208.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9208.cs
new file mode 100644
index 0000000..d5d6f6f
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9208.cs
@@ -0,0 +1,34 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 报警附件上传指令
+ ///
+ [JT808Formatter(typeof(JT808_0x9208_Formatter))]
+ public class JT808_0x9208:JT808Bodies
+ {
+ public byte AttachmentServerIPLength { get; set; }
+ public string AttachmentServerIP { get; set; }
+ public ushort AttachmentServerIPTcpPort { get; set; }
+ public ushort AttachmentServerIPUdpPort { get; set; }
+ ///
+ /// 报警标识号
+ ///
+ public AlarmIdentificationProperty AlarmIdentification { get; set; }
+ ///
+ /// 平台给报警分配的唯一编号
+ /// 32
+ ///
+ public string AlarmId { get; set; }
+ ///
+ /// 预留
+ ///
+ public byte[] Retain { get; set; } = new byte[16];
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9212.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9212.cs
new file mode 100644
index 0000000..a6d9c69
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/MessageBody/JT808_0x9212.cs
@@ -0,0 +1,42 @@
+using JT808.Protocol.Attributes;
+using JT808.Protocol.Extensions.JTActiveSafety.Formatters;
+using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.MessageBody
+{
+ ///
+ /// 文件上传完成消息应答
+ ///
+ [JT808Formatter(typeof(JT808_0x9212_Formatter))]
+ public class JT808_0x9212:JT808Bodies
+ {
+ ///
+ /// 文件名称长度
+ ///
+ public byte FileNameLength { get; set; }
+ ///
+ /// 文件名称
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 文件类型
+ ///
+ public byte FileType { get; set; }
+ ///
+ /// 上传结果
+ ///
+ public byte UploadResult { get; set; }
+ ///
+ /// 补传数据包数量
+ /// 需要补传的数据包数量,无补传时该值为0
+ ///
+ public byte DataPackageCount { get; set; }
+ ///
+ /// 补传数据包列表
+ ///
+ public List DataPackages { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmIdentificationProperty.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmIdentificationProperty.cs
new file mode 100644
index 0000000..085ccb0
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmIdentificationProperty.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Metadata
+{
+ ///
+ /// 报警标识号
+ ///
+ public class AlarmIdentificationProperty
+ {
+ ///
+ /// 终端ID
+ ///
+ public string TerminalID { get; set; }
+ ///
+ /// YY-MM-DD-hh-mm-ss
+ /// BCD[6]
+ ///
+ public DateTime Time { get; set; }
+ ///
+ /// 序号
+ ///
+ public byte SN { get; set; }
+ ///
+ /// 附件数量
+ ///
+ public byte AttachCount { get; set; }
+ ///
+ /// 预留
+ ///
+ public byte Retain { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmOrEventProperty.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmOrEventProperty.cs
new file mode 100644
index 0000000..91977cb
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AlarmOrEventProperty.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Metadata
+{
+ ///
+ /// 胎压监测系统报警/事件信息
+ ///
+ public class AlarmOrEventProperty
+ {
+ ///
+ /// 胎压报警位置
+ ///
+ public byte TirePressureAlarmPosition { get; set; }
+ ///
+ /// 报警/事件类型
+ ///
+ public ushort AlarmOrEventType { get; set; }
+ ///
+ /// 胎压
+ ///
+ public ushort TirePressure { get; set; }
+ ///
+ /// 胎温
+ ///
+ public ushort TireTemperature { get; set; }
+ ///
+ /// 电池电量
+ ///
+ public ushort BatteryLevel { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AttachProperty.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AttachProperty.cs
new file mode 100644
index 0000000..0b57375
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/AttachProperty.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Metadata
+{
+ ///
+ /// 附件信息
+ ///
+ public class AttachProperty
+ {
+ ///
+ /// 文件名称长度
+ ///
+ public byte FileNameLength { get; set; }
+ ///
+ /// 文件名称
+ /// <文件类型>_<通道号>_<报警类型>_<序号>_<报警编号>.<后缀名>
+ ///
+ public string FileName{ get; set; }
+ ///
+ /// 文件大小
+ ///
+ public uint FileSize { get; set; }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/DataPackageProperty.cs b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/DataPackageProperty.cs
new file mode 100644
index 0000000..f336dc2
--- /dev/null
+++ b/src/JT808.Protocol.Extensions.JTActiveSafety/Metadata/DataPackageProperty.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Protocol.Extensions.JTActiveSafety.Metadata
+{
+ ///
+ /// 补传数据包信息
+ ///
+ public class DataPackageProperty
+ {
+ ///
+ /// 数据偏移量
+ ///
+ public uint Offset { get; set; }
+ ///
+ /// 数据长度
+ ///
+ public uint Length { get; set; }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol.Test/JTActiveSafety.Protocol.Test.csproj b/src/JTActiveSafety.Protocol.Test/JTActiveSafety.Protocol.Test.csproj
new file mode 100644
index 0000000..501a5ce
--- /dev/null
+++ b/src/JTActiveSafety.Protocol.Test/JTActiveSafety.Protocol.Test.csproj
@@ -0,0 +1,15 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
diff --git a/src/JTActiveSafety.Protocol.Test/UnitTest1.cs b/src/JTActiveSafety.Protocol.Test/UnitTest1.cs
new file mode 100644
index 0000000..d2308e8
--- /dev/null
+++ b/src/JTActiveSafety.Protocol.Test/UnitTest1.cs
@@ -0,0 +1,14 @@
+using System;
+using Xunit;
+
+namespace JTActiveSafety.Protocol.Test
+{
+ public class UnitTest1
+ {
+ [Fact]
+ public void Test1()
+ {
+
+ }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/Buffers/JTActiveSafetyBufferWriter.cs b/src/JTActiveSafety.Protocol/Buffers/JTActiveSafetyBufferWriter.cs
new file mode 100644
index 0000000..5910600
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/Buffers/JTActiveSafetyBufferWriter.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace JTActiveSafety.Protocol.Buffers
+{
+ ///
+ ///
+ ///
+ ref partial struct JTActiveSafetyBufferWriter
+ {
+ private Span _buffer;
+ public JTActiveSafetyBufferWriter(Span buffer)
+ {
+ _buffer = buffer;
+ WrittenCount = 0;
+ }
+ public Span Free => _buffer.Slice(WrittenCount);
+ public Span Written => _buffer.Slice(0, WrittenCount);
+ public int WrittenCount { get; private set; }
+ public void Advance(int count)
+ {
+ WrittenCount += count;
+ }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/JTActiveSafety.Protocol.csproj b/src/JTActiveSafety.Protocol/JTActiveSafety.Protocol.csproj
index 9f5c4f4..f1ab155 100644
--- a/src/JTActiveSafety.Protocol/JTActiveSafety.Protocol.csproj
+++ b/src/JTActiveSafety.Protocol/JTActiveSafety.Protocol.csproj
@@ -1,7 +1,30 @@
-
+
netstandard2.0
+ 7.3
+ Copyright 2019.
+ SmallChi(Koike)
+ JTActiveSafety
+ JTActiveSafety
+ 基于JTActiveSafety的附件协议
+ 基于JTActiveSafety的附件协议
+ true
+ https://github.com/SmallChi/JTActiveSafety
+ https://github.com/SmallChi/JTActiveSafety
+ https://github.com/SmallChi/JTActiveSafety/blob/master/LICENSE
+ https://github.com/SmallChi/JTActiveSafety/blob/master/LICENSE
+ false
+ 1.0.0
+ LICENSE
-
+
+
+
+
+
+ True
+
+
+
diff --git a/src/JTActiveSafety.Protocol/JTActiveSafetyArrayPool.cs b/src/JTActiveSafety.Protocol/JTActiveSafetyArrayPool.cs
new file mode 100644
index 0000000..11b540c
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/JTActiveSafetyArrayPool.cs
@@ -0,0 +1,24 @@
+using System.Buffers;
+
+namespace JTActiveSafety.Protocol
+{
+ internal static class JTActiveSafetyArrayPool
+ {
+ private readonly static ArrayPool ArrayPool;
+
+ static JTActiveSafetyArrayPool()
+ {
+ ArrayPool = ArrayPool.Create();
+ }
+
+ public static byte[] Rent(int minimumLength)
+ {
+ return ArrayPool.Rent(minimumLength);
+ }
+
+ public static void Return(byte[] array, bool clearArray = false)
+ {
+ ArrayPool.Return(array, clearArray);
+ }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/JTActiveSafetyPackage.cs b/src/JTActiveSafety.Protocol/JTActiveSafetyPackage.cs
new file mode 100644
index 0000000..4e68432
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/JTActiveSafetyPackage.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JTActiveSafety.Protocol
+{
+ public class JTActiveSafetyPackage
+ {
+ ///
+ /// 帧头标识
+ ///
+ public static byte[] FH_Bytes = new byte[] { 0x30, 0x31, 0x63, 0x64 };
+ ///
+ /// 帧头标识
+ ///
+ public const uint FH = 0x30316364;
+ ///
+ /// 帧头标识
+ /// 固定为0x30 0x31 0x63 0x64
+ ///
+ public uint FH_Flag { get; set; } = FH;
+ ///
+ /// 文件名称
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 数据偏移量
+ ///
+ public uint Offset { get; set; }
+ ///
+ /// 数据长度
+ ///
+ public uint Length { get; set; }
+ ///
+ /// 数据体
+ /// 默认长度64K,文件小于64K 则为实际长度
+ ///
+ public byte[] Bodies{ get; set; }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/JTActiveSafetySerializer.cs b/src/JTActiveSafety.Protocol/JTActiveSafetySerializer.cs
new file mode 100644
index 0000000..023c64c
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/JTActiveSafetySerializer.cs
@@ -0,0 +1,42 @@
+using JTActiveSafety.Protocol.Buffers;
+using JTActiveSafety.Protocol.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JTActiveSafety.Protocol
+{
+ public static class JTActiveSafetySerializer
+ {
+ public static byte[] Serialize(JTActiveSafetyPackage package, int minBufferSize = 4096)
+ {
+ byte[] buffer = JTActiveSafetyArrayPool.Rent(minBufferSize);
+ try
+ {
+ JTActiveSafetyMessagePackWriter writer = new JTActiveSafetyMessagePackWriter(buffer);
+ writer.WriteUInt32(package.FH_Flag);
+ writer.WriteString(package.FileName);
+ writer.WriteUInt32(package.Offset);
+ writer.WriteUInt32(package.Length);
+ writer.WriteArray(package.Bodies);
+ return writer.FlushAndGetArray();
+ }
+ finally
+ {
+ JTActiveSafetyArrayPool.Return(buffer);
+ }
+ }
+
+ public static JTActiveSafetyPackage Deserialize(ReadOnlySpan bytes)
+ {
+ JTActiveSafetyPackage jTActiveSafetyPackage= new JTActiveSafetyPackage();
+ JTActiveSafetyMessagePackReader reader = new JTActiveSafetyMessagePackReader(bytes);
+ jTActiveSafetyPackage.FH_Flag = reader.ReadUInt32();
+ jTActiveSafetyPackage.FileName = reader.ReadString(50);
+ jTActiveSafetyPackage.Offset= reader.ReadUInt32();
+ jTActiveSafetyPackage.Length = reader.ReadUInt32();
+ jTActiveSafetyPackage.Bodies = reader.ReadRemainArray().ToArray();
+ return jTActiveSafetyPackage;
+ }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackReader.cs b/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackReader.cs
new file mode 100644
index 0000000..c13c2bc
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackReader.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Buffers;
+using System.Buffers.Binary;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace JTActiveSafety.Protocol.MessagePack
+{
+ ref struct JTActiveSafetyMessagePackReader
+ {
+ public ReadOnlySpan Reader { get; private set; }
+ public ReadOnlySpan SrcBuffer { get; }
+ public int ReaderCount { get; private set; }
+ public JTActiveSafetyMessagePackReader(ReadOnlySpan srcBuffer)
+ {
+ SrcBuffer = srcBuffer;
+ ReaderCount = 0;
+ Reader = srcBuffer;
+ }
+ public ushort ReadUInt16()
+ {
+ var readOnlySpan = GetReadOnlySpan(2);
+ return BinaryPrimitives.ReadUInt16BigEndian(readOnlySpan.Slice(0, 2));
+ }
+ public uint ReadUInt32()
+ {
+ var readOnlySpan = GetReadOnlySpan(4);
+ return BinaryPrimitives.ReadUInt32BigEndian(readOnlySpan.Slice(0, 4));
+ }
+ public int ReadInt32()
+ {
+ var readOnlySpan = GetReadOnlySpan(4);
+ return BinaryPrimitives.ReadInt32BigEndian(readOnlySpan.Slice(0, 4));
+ }
+ public ulong ReadUInt64()
+ {
+ var readOnlySpan = GetReadOnlySpan(8);
+ return BinaryPrimitives.ReadUInt64BigEndian(readOnlySpan.Slice(0, 8));
+ }
+ public byte ReadByte()
+ {
+ var readOnlySpan = GetReadOnlySpan(1);
+ return readOnlySpan[0];
+ }
+ ///
+ /// 数字编码 大端模式、高位在前
+ ///
+ ///
+ public string ReadBigNumber(int len)
+ {
+ ulong result = 0;
+ var readOnlySpan = GetReadOnlySpan(len);
+ for (int i = 0; i < len; i++)
+ {
+ ulong currentData = (ulong)readOnlySpan[i] << (8 * (len - i - 1));
+ result += currentData;
+ }
+ return result.ToString();
+ }
+ public ReadOnlySpan ReadArray(int start,int end)
+ {
+ return Reader.Slice(start,end);
+ }
+ public string ReadString(int len)
+ {
+ var readOnlySpan = GetReadOnlySpan(len);
+ string value = Encoding.UTF8.GetString(readOnlySpan.Slice(0, len).ToArray());
+ return value;
+ }
+ public string ReadBCD(int len)
+ {
+ int count = len / 2;
+ var readOnlySpan = GetReadOnlySpan(count);
+ StringBuilder bcdSb = new StringBuilder(count);
+ for (int i = 0; i < count; i++)
+ {
+ bcdSb.Append(readOnlySpan[i].ToString("X2"));
+ }
+ return bcdSb.ToString();
+ }
+ public ReadOnlySpan ReadRemainArray()
+ {
+ return Reader.Slice(ReaderCount);
+ }
+ private ReadOnlySpan GetReadOnlySpan(int count)
+ {
+ ReaderCount += count;
+ return Reader.Slice(ReaderCount - count);
+ }
+ }
+}
diff --git a/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackWriter.cs b/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackWriter.cs
new file mode 100644
index 0000000..5c4bfda
--- /dev/null
+++ b/src/JTActiveSafety.Protocol/MessagePack/JTActiveSafetyMessagePackWriter.cs
@@ -0,0 +1,98 @@
+using JTActiveSafety.Protocol.Buffers;
+using System;
+using System.Buffers;
+using System.Buffers.Binary;
+using System.Text;
+
+namespace JTActiveSafety.Protocol.MessagePack
+{
+ ref struct JTActiveSafetyMessagePackWriter
+ {
+ private JTActiveSafetyBufferWriter writer;
+ public JTActiveSafetyMessagePackWriter(Span buffer)
+ {
+ this.writer = new JTActiveSafetyBufferWriter(buffer);
+ }
+ public byte[] FlushAndGetArray()
+ {
+ return writer.Written.ToArray();
+ }
+ public void WriteByte(byte value)
+ {
+ var span = writer.Free;
+ span[0] = value;
+ writer.Advance(1);
+ }
+ public void WriteUInt16(ushort value)
+ {
+ BinaryPrimitives.WriteUInt16BigEndian(writer.Free, value);
+ writer.Advance(2);
+ }
+ public void WriteInt32(int value)
+ {
+ BinaryPrimitives.WriteInt32BigEndian(writer.Free, value);
+ writer.Advance(4);
+ }
+ public void WriteUInt64(ulong value)
+ {
+ BinaryPrimitives.WriteUInt64BigEndian(writer.Free, value);
+ writer.Advance(8);
+ }
+ public void WriteUInt32(uint value)
+ {
+ BinaryPrimitives.WriteUInt32BigEndian(writer.Free, value);
+ writer.Advance(4);
+ }
+ public void WriteString(string value)
+ {
+ byte[] codeBytes = Encoding.UTF8.GetBytes(value);
+ codeBytes.CopyTo(writer.Free);
+ writer.Advance(codeBytes.Length);
+ }
+ public void WriteArray(ReadOnlySpan src)
+ {
+ src.CopyTo(writer.Free);
+ writer.Advance(src.Length);
+ }
+ public void WriteBCD(string value, int len)
+ {
+ string bcdText = value ?? "";
+ int startIndex = 0;
+ int noOfZero = len - bcdText.Length;
+ if (noOfZero > 0)
+ {
+ bcdText = bcdText.Insert(startIndex, new string('0', noOfZero));
+ }
+ int byteIndex = 0;
+ int count = len / 2;
+ var bcdSpan = bcdText.AsSpan();
+ var spanFree = writer.Free;
+ while (startIndex < bcdText.Length && byteIndex < count)
+ {
+ spanFree[byteIndex++] = Convert.ToByte(bcdSpan.Slice(startIndex, 2).ToString(), 16);
+ startIndex += 2;
+ }
+ writer.Advance(byteIndex);
+ }
+ ///
+ /// 数字编码 大端模式、高位在前
+ ///
+ ///
+ ///
+ public void WriteBigNumber(string value, int len)
+ {
+ var spanFree = writer.Free;
+ ulong number = string.IsNullOrEmpty(value) ? 0 : (ulong)double.Parse(value);
+ for (int i = len - 1; i >= 0; i--)
+ {
+ spanFree[i] = (byte)(number & 0xFF); //取低8位
+ number = number >> 8;
+ }
+ writer.Advance(len);
+ }
+ public int GetCurrentPosition()
+ {
+ return writer.WrittenCount;
+ }
+ }
+}
diff --git a/src/JTActiveSafety.sln b/src/JTActiveSafety.sln
index 8a20adc..f62cc95 100644
--- a/src/JTActiveSafety.sln
+++ b/src/JTActiveSafety.sln
@@ -3,9 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Protocol.Extensions.JTActiveSafety", "JT808.Protocol.Extensions.JTActiveSafety\JT808.Protocol.Extensions.JTActiveSafety.csproj", "{EDB6CAC8-B2A6-4C59-BFC3-8FF13A7CF799}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Extensions.JTActiveSafety", "JT808.Protocol.Extensions.JTActiveSafety\JT808.Protocol.Extensions.JTActiveSafety.csproj", "{EDB6CAC8-B2A6-4C59-BFC3-8FF13A7CF799}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JTActiveSafety.Protocol", "JTActiveSafety.Protocol\JTActiveSafety.Protocol.csproj", "{FF716FAA-0C89-4DB9-A559-C50E502B996D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JTActiveSafety.Protocol", "JTActiveSafety.Protocol\JTActiveSafety.Protocol.csproj", "{FF716FAA-0C89-4DB9-A559-C50E502B996D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Protocol.Extensions.JTActiveSafety.Test", "JT808.Protocol.Extensions.JTActiveSafety.Test\JT808.Protocol.Extensions.JTActiveSafety.Test.csproj", "{5A5B068D-4276-4E9D-84A4-C659A86A4A6B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JTActiveSafety.Protocol.Test", "JTActiveSafety.Protocol.Test\JTActiveSafety.Protocol.Test.csproj", "{148DB5C2-A8ED-4430-8AB8-44839FC45C7F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +25,14 @@ Global
{FF716FAA-0C89-4DB9-A559-C50E502B996D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF716FAA-0C89-4DB9-A559-C50E502B996D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF716FAA-0C89-4DB9-A559-C50E502B996D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A5B068D-4276-4E9D-84A4-C659A86A4A6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A5B068D-4276-4E9D-84A4-C659A86A4A6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A5B068D-4276-4E9D-84A4-C659A86A4A6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A5B068D-4276-4E9D-84A4-C659A86A4A6B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {148DB5C2-A8ED-4430-8AB8-44839FC45C7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {148DB5C2-A8ED-4430-8AB8-44839FC45C7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {148DB5C2-A8ED-4430-8AB8-44839FC45C7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {148DB5C2-A8ED-4430-8AB8-44839FC45C7F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE