2.增加内存包的读写器功能 3.将消息总包数和包序号属性移入数据头更贴切协议 4.修改数据头-消息体属性及对应测试用例 5.修改文档内容tags/v2.1.3
@@ -16,22 +16,22 @@ | |||
### 数据包[JT808Package] | |||
| 头标识 | 数据头 | 数据体 | 校验码 | 尾标识 | | |||
| :----: | :---------: | :---------: | :-------: | :----: | | |||
| Begin | JT808Header | JT808Bodies | CheckCode | End | | |||
| 头标识 | 数据头 | 数据体 | 校验码 | 尾标识 | | |||
| :----: | :---------: | :---------: | :----------: | :----: | | |||
| Begin | JT808Header | JT808Bodies |CheckCode | End | | |||
| 7E | - | - | - | 7E | | |||
### 数据头[JT808Header] | |||
| 消息ID | 消息体属性 | 终端手机号 | 消息流水号 | | |||
| :----: | :----------------------------: | :-------------: | :--------: | | |||
| MsgId | JT808HeaderMessageBodyProperty | TerminalPhoneNo | MsgNum | | |||
| 消息ID | 消息体属性 | 终端手机号 | 消息流水号 | 消息总包数(依赖是否分包) | 包序号(依赖是否分包) | | |||
| :----: | :----------------------------: | :-------------: | :--------: |:---------: | :-------:| | |||
| MsgId | JT808HeaderMessageBodyProperty | TerminalPhoneNo | MsgNum |PackgeCount | PackageIndex | | |||
#### 数据头-消息体属性[JT808HeaderMessageBodyProperty] | |||
| 是否分包 | 加密标识 | 消息体长度 | 消息总包数 | 包序号 | | |||
| :------: | :------: | :--------: | :---------: | :----------: | | |||
| IsPackge | Encrypt | DataLength | PackgeCount | PackageIndex | | |||
| 是否分包 | 加密标识 | 消息体长度 | | |||
| :------: | :------: | :--------: | | |||
| IsPackge | Encrypt | DataLength | | |||
#### 消息体属性[JT808Bodies] | |||
@@ -145,8 +145,8 @@ Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); | |||
Assert.Equal(126, jT808Package.Header.MsgNum); | |||
Assert.Equal("123456789012", jT808Package.Header.TerminalPhoneNo); | |||
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); | |||
Assert.Equal(0, jT808Package.Header.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.PackgeCount); | |||
Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); | |||
//4.数据包体 | |||
@@ -181,8 +181,8 @@ JT808Package jT808Package = Enums.JT808MsgId.位置信息汇报.Create("12345678 | |||
StatusFlag = 2, | |||
JT808LocationAttachData = new Dictionary<byte, JT808LocationAttachBase> | |||
{ | |||
{ JT808_0x0200_BodyBase.AttachId0x01,new JT808_0x0200_0x01{Mileage = 100}}, | |||
{ JT808_0x0200_BodyBase.AttachId0x02,new JT808_0x0200_0x02{Oil = 125}} | |||
{ JT808Constants.JT808_0x0200_0x01,new JT808_0x0200_0x01{Mileage = 100}}, | |||
{ JT808Constants.JT808_0x0200_0x02,new JT808_0x0200_0x02{Oil = 125}} | |||
} | |||
}); | |||
@@ -17,7 +17,7 @@ namespace JT808.Protocol.Test.Extensions | |||
{ | |||
var package= JT808MsgId.终端心跳.Create_终端心跳("123456789", new Protocol.MessageBody.JT808_0x0002 { | |||
}); | |||
}); | |||
} | |||
@@ -0,0 +1,31 @@ | |||
using JT808.Protocol.Enums; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace JT808.Protocol.Test | |||
{ | |||
public class JT808HeaderMessageBodyPropertyTest | |||
{ | |||
[Fact] | |||
public void Test1() | |||
{ | |||
JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty(); | |||
jT808HeaderMessageBodyProperty.DataLength = 255; | |||
jT808HeaderMessageBodyProperty.IsPackage = true; | |||
jT808HeaderMessageBodyProperty.Encrypt = JT808EncryptMethod.RSA; | |||
var result = jT808HeaderMessageBodyProperty.Wrap(); | |||
Assert.Equal(9471, result); | |||
} | |||
[Fact] | |||
public void Test2() | |||
{ | |||
JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty(9471); | |||
Assert.Equal(255, jT808HeaderMessageBodyProperty.DataLength); | |||
Assert.True(jT808HeaderMessageBodyProperty.IsPackage); | |||
Assert.Equal(JT808EncryptMethod.RSA, jT808HeaderMessageBodyProperty.Encrypt); | |||
} | |||
} | |||
} |
@@ -29,7 +29,7 @@ namespace JT808.Protocol.Test | |||
{ | |||
TerminalPhoneNo = "13812345678" | |||
}; | |||
jT808HeaderProperty.MessageBodyProperty.DataLength = 5; | |||
jT808HeaderProperty.MessageBodyProperty=new JT808HeaderMessageBodyProperty(5); | |||
jT808HeaderProperty.MsgNum = 135; | |||
jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value(); | |||
@@ -45,7 +45,7 @@ namespace JT808.Protocol.Test | |||
JT808Header jT808Header = JT808Serializer.Deserialize<JT808Header>(headerBytes); | |||
Assert.Equal(135, jT808Header.MsgNum); | |||
Assert.Equal("13812345678", jT808Header.TerminalPhoneNo); | |||
Assert.False(jT808Header.MessageBodyProperty.IsPackge); | |||
Assert.False(jT808Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId); | |||
Assert.Equal(5, jT808Header.MessageBodyProperty.DataLength); | |||
} | |||
@@ -55,7 +55,7 @@ namespace JT808.Protocol.Test | |||
{ | |||
JT808Header jT808HeaderProperty = new JT808Header(); | |||
jT808HeaderProperty.TerminalPhoneNo = "13812345678"; | |||
jT808HeaderProperty.MessageBodyProperty.DataLength = 5; | |||
jT808HeaderProperty.MessageBodyProperty=new JT808HeaderMessageBodyProperty(5); | |||
jT808HeaderProperty.MsgNum = 135; | |||
jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value(); | |||
//"01 02 00 05 01 38 12 34 56 78 00 87" | |||
@@ -71,7 +71,7 @@ namespace JT808.Protocol.Test | |||
JT808Header jT808Header = JT808Serializer.Deserialize<JT808Header>(headerBytes); | |||
Assert.Equal(135, jT808Header.MsgNum); | |||
Assert.Equal("13812345678", jT808Header.TerminalPhoneNo); | |||
Assert.False(jT808Header.MessageBodyProperty.IsPackge); | |||
Assert.False(jT808Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId); | |||
Assert.Equal(5, jT808Header.MessageBodyProperty.DataLength); | |||
} | |||
@@ -276,10 +276,9 @@ namespace JT808.Protocol.Test.MessageBody | |||
Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); | |||
Assert.Equal(8888, jT808Package.Header.MsgNum); | |||
Assert.Equal("112233445566", jT808Package.Header.TerminalPhoneNo); | |||
//Assert.Equal(1, jT808Package.Header.MessageBodyProperty.DataLength); | |||
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); | |||
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(0, jT808Package.Header.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.PackgeCount); | |||
Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); | |||
JT808_0x0200 jT808UploadLocationRequest = (JT808_0x0200)jT808Package.Bodies; | |||
@@ -35,9 +35,9 @@ namespace JT808.Protocol.Test.Simples | |||
Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); | |||
Assert.Equal(126, jT808Package.Header.MsgNum); | |||
Assert.Equal("123456789012", jT808Package.Header.TerminalPhoneNo); | |||
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); | |||
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(0, jT808Package.Header.PackageIndex); | |||
Assert.Equal(0, jT808Package.Header.PackgeCount); | |||
Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); | |||
//4.数据包体 | |||
@@ -56,15 +56,46 @@ namespace JT808.Protocol.Test.Simples | |||
byte[] bytes10 = "7e08012017013812345678203c000a000ad4dea2f72e50269b5a1ca251400a2ad427e5a4ca47ffd9d17e".ToHexBytes(); | |||
JT808Package jT808_0X0801_1 = JT808Serializer.Deserialize<JT808Package>(bytes1); | |||
Assert.True(jT808_0X0801_1.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(1, jT808_0X0801_1.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_1.Header.PackgeCount); | |||
JT808Package jT808_0X0801_2 = JT808Serializer.Deserialize<JT808Package>(bytes2); | |||
Assert.True(jT808_0X0801_2.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(2, jT808_0X0801_2.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_2.Header.PackgeCount); | |||
JT808Package jT808_0X0801_3 = JT808Serializer.Deserialize<JT808Package>(bytes3); | |||
Assert.True(jT808_0X0801_3.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(3, jT808_0X0801_3.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_3.Header.PackgeCount); | |||
JT808Package jT808_0X0801_4 = JT808Serializer.Deserialize<JT808Package>(bytes4); | |||
Assert.True(jT808_0X0801_4.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(4, jT808_0X0801_4.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_4.Header.PackgeCount); | |||
JT808Package jT808_0X0801_5 = JT808Serializer.Deserialize<JT808Package>(bytes5); | |||
Assert.True(jT808_0X0801_5.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(5, jT808_0X0801_5.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_5.Header.PackgeCount); | |||
JT808Package jT808_0X0801_6 = JT808Serializer.Deserialize<JT808Package>(bytes6); | |||
Assert.True(jT808_0X0801_6.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(6, jT808_0X0801_6.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_6.Header.PackgeCount); | |||
JT808Package jT808_0X0801_7 = JT808Serializer.Deserialize<JT808Package>(bytes7); | |||
Assert.True(jT808_0X0801_7.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(7, jT808_0X0801_7.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_7.Header.PackgeCount); | |||
JT808Package jT808_0X0801_8 = JT808Serializer.Deserialize<JT808Package>(bytes8); | |||
Assert.True(jT808_0X0801_8.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(8, jT808_0X0801_8.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_8.Header.PackgeCount); | |||
JT808Package jT808_0X0801_9 = JT808Serializer.Deserialize<JT808Package>(bytes9); | |||
Assert.True(jT808_0X0801_9.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(9, jT808_0X0801_9.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_9.Header.PackgeCount); | |||
JT808Package jT808_0X0801_10 = JT808Serializer.Deserialize<JT808Package>(bytes10); | |||
Assert.True(jT808_0X0801_10.Header.MessageBodyProperty.IsPackage); | |||
Assert.Equal(10, jT808_0X0801_10.Header.PackageIndex); | |||
Assert.Equal(10, jT808_0X0801_10.Header.PackgeCount); | |||
var jT808_0X0801_body_1 = jT808_0X0801_1.Bodies as JT808_0x0801; | |||
var jT808_0X0801_body_2 = jT808_0X0801_2.Bodies as JT808SplitPackageBodies; | |||
@@ -18,10 +18,18 @@ namespace JT808.Protocol.Formatters | |||
// 1.消息ID | |||
jT808Header.MsgId = reader.ReadUInt16(); | |||
// 2.消息体属性 | |||
jT808Header.MessageBodyProperty = JT808HeaderMessageBodyPropertyFormatter.Instance.Deserialize(ref reader, config); | |||
jT808Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(reader.ReadUInt16()); | |||
// 3.终端手机号 | |||
jT808Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); | |||
jT808Header.MsgNum = reader.ReadUInt16(); | |||
// 4.判断有无分包 | |||
if (jT808Header.MessageBodyProperty.IsPackage) | |||
{ | |||
//5.读取消息包总数 | |||
jT808Header.PackgeCount = reader.ReadUInt16(); | |||
//6.读取消息包序号 | |||
jT808Header.PackageIndex = reader.ReadUInt16(); | |||
} | |||
return jT808Header; | |||
} | |||
@@ -30,11 +38,19 @@ namespace JT808.Protocol.Formatters | |||
// 1.消息ID | |||
writer.WriteUInt16(value.MsgId); | |||
// 2.消息体属性 | |||
JT808HeaderMessageBodyPropertyFormatter.Instance.Serialize(ref writer,value.MessageBodyProperty, config); | |||
writer.WriteUInt16(value.MessageBodyProperty.Wrap()); | |||
// 3.终端手机号 | |||
writer.WriteBCD(value.TerminalPhoneNo, config.TerminalPhoneNoLength); | |||
// 4.消息流水号 | |||
writer.WriteUInt16(value.MsgNum); | |||
// 5.判断是否分包 | |||
if (value.MessageBodyProperty.IsPackage) | |||
{ | |||
// 6.消息包总数 | |||
writer.WriteUInt16(value.PackgeCount); | |||
// 7.消息包序号 | |||
writer.WriteUInt16(value.PackageIndex); | |||
} | |||
} | |||
} | |||
} |
@@ -1,31 +0,0 @@ | |||
using JT808.Protocol.Enums; | |||
using JT808.Protocol.Extensions; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.MessagePack; | |||
using System; | |||
namespace JT808.Protocol.Formatters | |||
{ | |||
/// <summary> | |||
/// 头部消息体属性的格式化器 | |||
/// </summary> | |||
public class JT808HeaderMessageBodyPropertyFormatter : IJT808MessagePackFormatter<JT808HeaderMessageBodyProperty> | |||
{ | |||
public static readonly JT808HeaderMessageBodyPropertyFormatter Instance = new JT808HeaderMessageBodyPropertyFormatter(); | |||
public JT808HeaderMessageBodyProperty Deserialize(ref JT808MessagePackReader writer, IJT808Config config) | |||
{ | |||
JT808HeaderMessageBodyProperty messageBodyProperty = new JT808HeaderMessageBodyProperty(); | |||
messageBodyProperty.Unwrap(writer.ReadUInt16(), config); | |||
if (messageBodyProperty.IsPackge) | |||
{ | |||
messageBodyProperty.PackgeCount = writer.ReadUInt16(); | |||
messageBodyProperty.PackageIndex = writer.ReadUInt16(); | |||
} | |||
return messageBodyProperty; | |||
} | |||
public void Serialize(ref JT808MessagePackWriter writer, JT808HeaderMessageBodyProperty value, IJT808Config config) | |||
{ | |||
writer.WriteUInt16(value.Wrap(config)); | |||
} | |||
} | |||
} |
@@ -28,21 +28,20 @@ namespace JT808.Protocol.Formatters | |||
// 3.1.读取消息Id | |||
jT808Package.Header.MsgId = reader.ReadUInt16(); | |||
// 3.2.读取消息体属性 | |||
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(); | |||
ushort messageBodyPropertyValue = reader.ReadUInt16(); | |||
// 3.2.1.解包消息体属性 | |||
jT808Package.Header.MessageBodyProperty.Unwrap(messageBodyPropertyValue, config); | |||
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(messageBodyPropertyValue); | |||
// 3.3.读取终端手机号 | |||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); | |||
// 3.4.读取消息流水号 | |||
jT808Package.Header.MsgNum = reader.ReadUInt16(); | |||
// 3.5.判断有无分包 | |||
if (jT808Package.Header.MessageBodyProperty.IsPackge) | |||
if (jT808Package.Header.MessageBodyProperty.IsPackage) | |||
{ | |||
//3.5.1.读取消息包总数 | |||
jT808Package.Header.MessageBodyProperty.PackgeCount = reader.ReadUInt16(); | |||
jT808Package.PackgeCount = reader.ReadUInt16(); | |||
//3.5.2.读取消息包序号 | |||
jT808Package.Header.MessageBodyProperty.PackageIndex = reader.ReadUInt16(); | |||
jT808Package.PackageIndex = reader.ReadUInt16(); | |||
} | |||
// 4.处理数据体 | |||
// 4.1.判断有无数据体 | |||
@@ -32,21 +32,18 @@ namespace JT808.Protocol.Formatters | |||
// 3.1.读取消息Id | |||
jT808Package.Header.MsgId = reader.ReadUInt16(); | |||
// 3.2.读取消息体属性 | |||
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(); | |||
ushort messageBodyPropertyValue= reader.ReadUInt16(); | |||
// 3.2.1.解包消息体属性 | |||
jT808Package.Header.MessageBodyProperty.Unwrap(messageBodyPropertyValue, config); | |||
jT808Package.Header.MessageBodyProperty=new JT808HeaderMessageBodyProperty(reader.ReadUInt16()); | |||
// 3.3.读取终端手机号 | |||
jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); | |||
// 3.4.读取消息流水号 | |||
jT808Package.Header.MsgNum= reader.ReadUInt16(); | |||
// 3.5.判断有无分包 | |||
if (jT808Package.Header.MessageBodyProperty.IsPackge) | |||
if (jT808Package.Header.MessageBodyProperty.IsPackage) | |||
{ | |||
//3.5.1.读取消息包总数 | |||
jT808Package.Header.MessageBodyProperty.PackgeCount = reader.ReadUInt16(); | |||
jT808Package.Header.PackgeCount = reader.ReadUInt16(); | |||
//3.5.2.读取消息包序号 | |||
jT808Package.Header.MessageBodyProperty.PackageIndex = reader.ReadUInt16(); | |||
jT808Package.Header.PackageIndex = reader.ReadUInt16(); | |||
} | |||
// 4.处理数据体 | |||
// 4.1.判断有无数据体 | |||
@@ -55,9 +52,9 @@ namespace JT808.Protocol.Formatters | |||
Type jT808BodiesImplType = config.MsgIdFactory.GetBodiesImplTypeByMsgId(jT808Package.Header.MsgId, jT808Package.Header.TerminalPhoneNo); | |||
if (jT808BodiesImplType != null) | |||
{ | |||
if (jT808Package.Header.MessageBodyProperty.IsPackge) | |||
if (jT808Package.Header.MessageBodyProperty.IsPackage) | |||
{ | |||
if (jT808Package.Header.MessageBodyProperty.PackageIndex > 1) | |||
if (jT808Package.Header.PackageIndex > 1) | |||
{ | |||
try | |||
{ | |||
@@ -124,12 +121,12 @@ namespace JT808.Protocol.Formatters | |||
// 2.4.消息流水号 | |||
writer.WriteUInt16(value.Header.MsgNum); | |||
// 2.5.判断是否分包 | |||
if (value.Header.MessageBodyProperty.IsPackge) | |||
if (value.Header.MessageBodyProperty.IsPackage) | |||
{ | |||
// 2.5.1.消息包总数 | |||
writer.WriteUInt16(value.Header.MessageBodyProperty.PackgeCount); | |||
writer.WriteUInt16(value.Header.PackgeCount); | |||
// 2.5.2.消息包序号 | |||
writer.WriteUInt16(value.Header.MessageBodyProperty.PackageIndex); | |||
writer.WriteUInt16(value.Header.PackageIndex); | |||
} | |||
int headerLength = writer.GetCurrentPosition(); | |||
// 3.处理数据体部分 | |||
@@ -144,10 +141,9 @@ namespace JT808.Protocol.Formatters | |||
} | |||
} | |||
// 3.1.处理数据体长度 | |||
value.Header.MessageBodyProperty.DataLength = writer.GetCurrentPosition() - headerLength; | |||
ushort msgBodiesPropertyValue = value.Header.MessageBodyProperty.Wrap(config); | |||
value.Header.MessageBodyProperty=new JT808HeaderMessageBodyProperty((ushort)(writer.GetCurrentPosition() - headerLength)); | |||
// 2.2.回写消息体属性 | |||
writer.WriteUInt16Return(msgBodiesPropertyValue, msgBodiesPropertyPosition); | |||
writer.WriteUInt16Return(value.Header.MessageBodyProperty.Wrap(), msgBodiesPropertyPosition); | |||
// 4.校验码 | |||
writer.WriteXor(); | |||
// 5.终止符 | |||
@@ -1,11 +1,12 @@ | |||
using JT808.Protocol.Enums; | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Reflection; | |||
using System.Text; | |||
namespace JT808.Protocol.Interfaces | |||
namespace JT808.Protocol | |||
{ | |||
public interface IJT808Config | |||
{ | |||
@@ -14,7 +14,7 @@ | |||
<licenseUrl>https://github.com/SmallChi/JT808/blob/master/LICENSE</licenseUrl> | |||
<license>https://github.com/SmallChi/JT808/blob/master/LICENSE</license> | |||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||
<Version>2.1.2</Version> | |||
<Version>2.1.3</Version> | |||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||
@@ -14,7 +14,7 @@ namespace JT808.Protocol | |||
/// <see cref="JT808.Protocol.Enums.JT808MsgId"/> | |||
/// </summary> | |||
public ushort MsgId { get; set; } | |||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } = new JT808HeaderMessageBodyProperty(); | |||
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } | |||
/// <summary> | |||
/// 终端手机号 | |||
/// 根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充 | |||
@@ -27,5 +27,13 @@ namespace JT808.Protocol | |||
/// 程序开始运行时等于零,发送第一帧数据时开始计数,到最大数后自动归零 | |||
/// </summary> | |||
public ushort MsgNum { get; set; } | |||
/// <summary> | |||
/// 消息总包数 | |||
/// </summary> | |||
public ushort PackgeCount { get; set; } | |||
/// <summary> | |||
/// 报序号 从1开始 | |||
/// </summary> | |||
public ushort PackageIndex { get; set; } | |||
} | |||
} |
@@ -1,31 +1,41 @@ | |||
using JT808.Protocol.Attributes; | |||
using JT808.Protocol.Enums; | |||
using JT808.Protocol.Formatters; | |||
using JT808.Protocol.Interfaces; | |||
using System; | |||
namespace JT808.Protocol | |||
{ | |||
[JT808Formatter(typeof(JT808HeaderMessageBodyPropertyFormatter))] | |||
public class JT808HeaderMessageBodyProperty | |||
public struct JT808HeaderMessageBodyProperty | |||
{ | |||
private const string encrypt_none = "000"; | |||
private const string encrypt_rsa = "001"; | |||
private const char char_zero = '0'; | |||
private const char char_one = '1'; | |||
public JT808HeaderMessageBodyProperty() | |||
public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None) | |||
{ | |||
IsPackge = false; | |||
Encrypt = JT808EncryptMethod.None; | |||
PackgeCount = 0; | |||
PackageIndex = 0; | |||
IsPackage = isPackage; | |||
Encrypt = jT808EncryptMethod; | |||
DataLength = dataLength; | |||
} | |||
public JT808HeaderMessageBodyProperty(ushort value) | |||
{ | |||
IsPackage = (value >> 13) == 1; | |||
switch ((value & 0x400) >> 10) | |||
{ | |||
case 0: | |||
Encrypt = JT808EncryptMethod.None; | |||
break; | |||
case 1: | |||
Encrypt = JT808EncryptMethod.RSA; | |||
break; | |||
default: | |||
Encrypt = JT808EncryptMethod.None; | |||
break; | |||
} | |||
DataLength = value & 0x3FF; | |||
} | |||
/// <summary> | |||
/// 是否分包 | |||
/// true-1 表示消息体为长消息,进行分包发送处理 | |||
/// false-0 消息头中无消息包封装项字段。 | |||
/// </summary> | |||
public bool IsPackge { get; set; } | |||
public bool IsPackage { get; set; } | |||
/// <summary> | |||
/// 加密标识,0为不加密 | |||
/// 当此三位都为 0,表示消息体不加密; | |||
@@ -37,40 +47,27 @@ namespace JT808.Protocol | |||
/// 消息体长度 | |||
/// </summary> | |||
public int DataLength { get; set; } | |||
/// <summary> | |||
/// 消息总包数 | |||
/// </summary> | |||
public ushort PackgeCount { get; set; } | |||
/// <summary> | |||
/// 报序号 从1开始 | |||
/// </summary> | |||
public ushort PackageIndex { get; set; } | |||
public ushort Wrap(IJT808Config jT808Config) | |||
public ushort Wrap() | |||
{ | |||
// 2.消息体属性 | |||
Span<char> msgMethod = new char[16]; | |||
// 2.1.保留 | |||
msgMethod[0] = char_zero; | |||
msgMethod[1] = char_zero; | |||
// 2.2.是否分包 | |||
msgMethod[2] = IsPackge ? char_one : char_zero; | |||
// 1.是否分包 | |||
int tmpIsPacke = 0; | |||
// 2.是否加密 | |||
int tmpEncrypt = 0; | |||
if (IsPackage) | |||
{ | |||
tmpIsPacke = 1 << 13; | |||
} | |||
// 2.3.数据加密方式 | |||
switch (Encrypt) | |||
{ | |||
case JT808EncryptMethod.None: | |||
msgMethod[3] = char_zero; | |||
msgMethod[4] = char_zero; | |||
msgMethod[5] = char_zero; | |||
tmpEncrypt = 0; | |||
break; | |||
case JT808EncryptMethod.RSA: | |||
msgMethod[3] = char_zero; | |||
msgMethod[4] = char_zero; | |||
msgMethod[5] = char_one; | |||
tmpEncrypt=1 << 10; | |||
break; | |||
default: | |||
msgMethod[3] = char_zero; | |||
msgMethod[4] = char_zero; | |||
msgMethod[5] = char_zero; | |||
tmpEncrypt = 0; | |||
break; | |||
} | |||
// 2.4.数据长度 | |||
@@ -78,34 +75,8 @@ namespace JT808.Protocol | |||
{ | |||
// 判断有无数据体长度 | |||
DataLength = 0; | |||
} | |||
ReadOnlySpan<char> dataLen = Convert.ToString(DataLength, 2).PadLeft(10, char_zero).AsSpan(); | |||
for (int i = 1; i <= 10; i++) | |||
{ | |||
msgMethod[5 + i] = dataLen[i - 1]; | |||
} | |||
return Convert.ToUInt16(msgMethod.ToString(), 2); | |||
} | |||
public void Unwrap(ushort value, IJT808Config jT808Config) | |||
{ | |||
ReadOnlySpan<char> msgMethod = Convert.ToString(value, 2).PadLeft(16, '0').AsSpan(); | |||
DataLength = Convert.ToInt32(msgMethod.Slice(6, 10).ToString(), 2); | |||
// 2.2. 数据加密方式 | |||
switch (msgMethod.Slice(3, 3).ToString()) | |||
{ | |||
case encrypt_none: | |||
Encrypt = JT808EncryptMethod.None; | |||
break; | |||
case encrypt_rsa: | |||
Encrypt = JT808EncryptMethod.RSA; | |||
break; | |||
default: | |||
Encrypt = JT808EncryptMethod.None; | |||
break; | |||
} | |||
IsPackge = msgMethod[2] != char_zero; | |||
PackgeCount = 0; | |||
PackageIndex = 0; | |||
} | |||
return (ushort)(tmpIsPacke | tmpEncrypt | DataLength); | |||
} | |||
} | |||
} |
@@ -30,5 +30,13 @@ namespace JT808.Protocol | |||
/// 终止符 | |||
/// </summary> | |||
public byte End { get; set; } | |||
/// <summary> | |||
/// 消息总包数 | |||
/// </summary> | |||
public ushort PackgeCount { get; set; } | |||
/// <summary> | |||
/// 报序号 从1开始 | |||
/// </summary> | |||
public ushort PackageIndex { get; set; } | |||
} | |||
} |
@@ -126,70 +126,56 @@ namespace JT808.Protocol.MessagePack | |||
public byte ReadEnd()=> ReadByte(); | |||
public ushort ReadUInt16() | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(2); | |||
ushort value = (ushort)((readOnlySpan[0] << 8) | (readOnlySpan[1])); | |||
return value; | |||
return BinaryPrimitives.ReadUInt16BigEndian(GetReadOnlySpan(2)); | |||
} | |||
public uint ReadUInt32() | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(4); | |||
uint value = (uint)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); | |||
return value; | |||
return BinaryPrimitives.ReadUInt32BigEndian(GetReadOnlySpan(4)); | |||
} | |||
public int ReadInt32() | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(4); | |||
int value = (int)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); | |||
return value; | |||
return BinaryPrimitives.ReadInt32BigEndian(GetReadOnlySpan(4)); | |||
} | |||
public ulong ReadUInt64() | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(8); | |||
ulong value = (ulong)( | |||
(readOnlySpan[0] << 56) | | |||
(readOnlySpan[1] << 48) | | |||
(readOnlySpan[2] << 40) | | |||
(readOnlySpan[3] << 32) | | |||
(readOnlySpan[4] << 24) | | |||
(readOnlySpan[5] << 16) | | |||
(readOnlySpan[6] << 8) | | |||
readOnlySpan[7]); | |||
return value; | |||
return BinaryPrimitives.ReadUInt64BigEndian(GetReadOnlySpan(8)); | |||
} | |||
public long ReadInt64() | |||
{ | |||
return BinaryPrimitives.ReadInt64BigEndian(GetReadOnlySpan(8)); | |||
} | |||
public byte ReadByte() | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(1); | |||
return readOnlySpan[0]; | |||
return GetReadOnlySpan(1)[0]; | |||
} | |||
public byte ReadVirtualByte() | |||
{ | |||
var readOnlySpan = GetVirtualReadOnlySpan(1); | |||
return readOnlySpan[0]; | |||
return GetVirtualReadOnlySpan(1)[0]; | |||
} | |||
public ushort ReadVirtualUInt16() | |||
{ | |||
var readOnlySpan = GetVirtualReadOnlySpan(2); | |||
return (ushort)((readOnlySpan[0] << 8) | (readOnlySpan[1])); | |||
return BinaryPrimitives.ReadUInt16BigEndian(GetVirtualReadOnlySpan(2)); | |||
} | |||
public short ReadVirtualInt16() | |||
{ | |||
return BinaryPrimitives.ReadInt16BigEndian(GetVirtualReadOnlySpan(2)); | |||
} | |||
public uint ReadVirtualUInt32() | |||
{ | |||
var readOnlySpan = GetVirtualReadOnlySpan(4); | |||
return (uint)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); | |||
return BinaryPrimitives.ReadUInt32BigEndian(GetVirtualReadOnlySpan(4)); | |||
} | |||
public int ReadVirtualInt32() | |||
{ | |||
return BinaryPrimitives.ReadInt32BigEndian(GetVirtualReadOnlySpan(4)); | |||
} | |||
public ulong ReadVirtualUInt64() | |||
{ | |||
var readOnlySpan = GetVirtualReadOnlySpan(8); | |||
return (ulong)( | |||
(readOnlySpan[0] << 56) | | |||
(readOnlySpan[1] << 48) | | |||
(readOnlySpan[2] << 40) | | |||
(readOnlySpan[3] << 32) | | |||
(readOnlySpan[4] << 24) | | |||
(readOnlySpan[5] << 16) | | |||
(readOnlySpan[6] << 8) | | |||
readOnlySpan[7]); | |||
return BinaryPrimitives.ReadUInt64BigEndian(GetVirtualReadOnlySpan(8)); | |||
} | |||
public long ReadVirtualInt64() | |||
{ | |||
return BinaryPrimitives.ReadInt64BigEndian(GetVirtualReadOnlySpan(8)); | |||
} | |||
/// <summary> | |||
/// 数字编码 大端模式、高位在前 | |||
/// </summary> | |||
@@ -207,8 +193,7 @@ namespace JT808.Protocol.MessagePack | |||
} | |||
public ReadOnlySpan<byte> ReadArray(int len) | |||
{ | |||
var readOnlySpan = GetReadOnlySpan(len); | |||
return readOnlySpan.Slice(0, len); | |||
return GetReadOnlySpan(len).Slice(0, len); | |||
} | |||
public ReadOnlySpan<byte> ReadArray(int start,int end) | |||
{ | |||
@@ -57,40 +57,22 @@ namespace JT808.Protocol.MessagePack | |||
} | |||
public void WriteUInt16(ushort value) | |||
{ | |||
var span = writer.Free; | |||
span[0] = (byte)(value >> 8); | |||
span[1] = (byte)value; | |||
BinaryPrimitives.WriteUInt16BigEndian(writer.Free, value); | |||
writer.Advance(2); | |||
} | |||
public void WriteInt32(int value) | |||
{ | |||
var span = writer.Free; | |||
span[0] = (byte)(value >> 24); | |||
span[1] = (byte)(value >> 16); | |||
span[2] = (byte)(value >> 8); | |||
span[3] = (byte)value; | |||
BinaryPrimitives.WriteInt32BigEndian(writer.Free, value); | |||
writer.Advance(4); | |||
} | |||
public void WriteUInt64(ulong value) | |||
{ | |||
var span = writer.Free; | |||
span[0] = (byte)(value >> 56); | |||
span[1] = (byte)(value >> 48); | |||
span[2] = (byte)(value >> 40); | |||
span[3] = (byte)(value >> 32); | |||
span[4] = (byte)(value >> 24); | |||
span[5] = (byte)(value >> 16); | |||
span[6] = (byte)(value >> 8); | |||
span[7] = (byte)value; | |||
BinaryPrimitives.WriteUInt64BigEndian(writer.Free, value); | |||
writer.Advance(8); | |||
} | |||
public void WriteUInt32(uint value) | |||
{ | |||
var span = writer.Free; | |||
span[0] = (byte)(value >> 24); | |||
span[1] = (byte)(value >> 16); | |||
span[2] = (byte)(value >> 8); | |||
span[3] = (byte)value; | |||
BinaryPrimitives.WriteUInt32BigEndian(writer.Free, value); | |||
writer.Advance(4); | |||
} | |||
public void WriteString(string value) | |||
@@ -106,22 +88,15 @@ namespace JT808.Protocol.MessagePack | |||
} | |||
public void WriteUInt16Return(ushort value, int position) | |||
{ | |||
writer.Written[position] = (byte)(value >> 8); | |||
writer.Written[position + 1] = (byte)value; | |||
BinaryPrimitives.WriteUInt16BigEndian(writer.Written.Slice(position, 2), value); | |||
} | |||
public void WriteInt32Return(int value, int position) | |||
{ | |||
writer.Written[position] = (byte)(value >> 24); | |||
writer.Written[position + 1] = (byte)(value >> 16); | |||
writer.Written[position + 2] = (byte)(value >> 8); | |||
writer.Written[position + 3] = (byte)value; | |||
BinaryPrimitives.WriteInt32BigEndian(writer.Written.Slice(position, 4), value); | |||
} | |||
public void WriteUInt32Return(uint value, int position) | |||
{ | |||
writer.Written[position] = (byte)(value >> 24); | |||
writer.Written[position + 1] = (byte)(value >> 16); | |||
writer.Written[position + 2] = (byte)(value >> 8); | |||
writer.Written[position + 3] = (byte)value; | |||
BinaryPrimitives.WriteUInt32BigEndian(writer.Written.Slice(position, 4), value); | |||
} | |||
public void WriteByteReturn(byte value, int position) | |||
{ | |||
@@ -147,19 +122,12 @@ namespace JT808.Protocol.MessagePack | |||
} | |||
public void WriteStringReturn(string value, int position) | |||
{ | |||
byte[] codeBytes = JT808Constants.Encoding.GetBytes(value); | |||
for (var i = 0; i < codeBytes.Length; i++) | |||
{ | |||
writer.Written[position + i] = codeBytes[i]; | |||
} | |||
Span<byte> codeBytes = JT808Constants.Encoding.GetBytes(value); | |||
codeBytes.CopyTo(writer.Written.Slice(position)); | |||
} | |||
public void WriteArrayReturn(ReadOnlySpan<byte> src, int position) | |||
{ | |||
foreach (var item in src) | |||
{ | |||
writer.Written[position] = item; | |||
position++; | |||
} | |||
src.CopyTo(writer.Written.Slice(position)); | |||
} | |||
/// <summary> | |||
/// yyMMddHHmmss | |||