2.修改默认日期转换为10进制 3.增加消息包测试 4.增加平台及设备流水号的默认实现 5.增加默认消息工厂处理 6.增加全局配置自定义消息及默认重写消息配置tags/1.0.0
@@ -1,24 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Extensions; | |||||
using JTNE.Protocol.Enums; | |||||
namespace JTNE.Protocol.Test | |||||
{ | |||||
public class JTNEPackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
var hex = "23 23 05 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 08 12 06 08 12 06 3A 00 01 E9".ToHexBytes(); | |||||
var package = JTNESerializer.Deserialize(hex); | |||||
Assert.Equal("LGHC4V1D3HE202652", package.VIN); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), package.AskId); | |||||
Assert.Equal((ushort)8, package.DataUnitLength); | |||||
Assert.Equal(0x01, package.EncryptMethod); | |||||
Assert.Equal(JTNEMsgId.platformlogin.ToByteValue(), package.MsgId); | |||||
} | |||||
} | |||||
} |
@@ -24,13 +24,13 @@ namespace JTNE.Protocol.Test.MessageBody | |||||
"9870" | "9870" | ||||
}; | }; | ||||
var hex = JTNESerializer.Serialize(jTNE_0X01).ToHexString(); | var hex = JTNESerializer.Serialize(jTNE_0X01).ToHexString(); | ||||
Assert.Equal("190122235556000131323334353637383939383736353433323130300304313233343435363739383730", hex); | |||||
Assert.Equal("130116173738000131323334353637383939383736353433323130300304313233343435363739383730", hex); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
var data = "190122235556000131323334353637383939383736353433323130300304313233343435363739383730".ToHexBytes(); | |||||
var data = "130116173738000131323334353637383939383736353433323130300304313233343435363739383730".ToHexBytes(); | |||||
JTNE_0x01 jTNE_0X01 = JTNESerializer.Deserialize<JTNE_0x01>(data); | JTNE_0x01 jTNE_0X01 = JTNESerializer.Deserialize<JTNE_0x01>(data); | ||||
Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X01.PDATime); | Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X01.PDATime); | ||||
Assert.Equal(1, jTNE_0X01.LoginNum); | Assert.Equal(1, jTNE_0X01.LoginNum); | ||||
@@ -16,13 +16,13 @@ namespace JTNE.Protocol.Test.MessageBody | |||||
jTNE_0X04.LogoutTime = DateTime.Parse("2019-01-22 23:55:56"); | jTNE_0X04.LogoutTime = DateTime.Parse("2019-01-22 23:55:56"); | ||||
jTNE_0X04.LogoutNum = 4444; | jTNE_0X04.LogoutNum = 4444; | ||||
var hex = JTNESerializer.Serialize(jTNE_0X04).ToHexString(); | var hex = JTNESerializer.Serialize(jTNE_0X04).ToHexString(); | ||||
Assert.Equal("190122235556115C", hex); | |||||
Assert.Equal("130116173738115C", hex); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
var data = "190122235556115C".ToHexBytes(); | |||||
var data = "130116173738115C".ToHexBytes(); | |||||
JTNE_0x04 jTNE_0X04 = JTNESerializer.Deserialize<JTNE_0x04>(data); | JTNE_0x04 jTNE_0X04 = JTNESerializer.Deserialize<JTNE_0x04>(data); | ||||
Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X04.LogoutTime); | Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X04.LogoutTime); | ||||
Assert.Equal(4444, jTNE_0X04.LogoutNum); | Assert.Equal(4444, jTNE_0X04.LogoutNum); | ||||
@@ -19,13 +19,13 @@ namespace JTNE.Protocol.Test.MessageBody | |||||
jTNE_0X05.PlatformPassword = "1234567890123456789"; | jTNE_0X05.PlatformPassword = "1234567890123456789"; | ||||
jTNE_0X05.EncryptMethod = 0x00; | jTNE_0X05.EncryptMethod = 0x00; | ||||
var hex = JTNESerializer.Serialize(jTNE_0X05).ToHexString(); | var hex = JTNESerializer.Serialize(jTNE_0X05).ToHexString(); | ||||
Assert.Equal("1901222355561A0A536D616C6C43686935313800313233343536373839303132333435363738390000", hex); | |||||
Assert.Equal("1301161737381A0A536D616C6C43686935313800313233343536373839303132333435363738390000", hex); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
var data = "1901222355561A0A536D616C6C43686935313800313233343536373839303132333435363738390000".ToHexBytes(); | |||||
var data = "1301161737381A0A536D616C6C43686935313800313233343536373839303132333435363738390000".ToHexBytes(); | |||||
JTNE_0x05 jTNE_0X05 = JTNESerializer.Deserialize<JTNE_0x05>(data); | JTNE_0x05 jTNE_0X05 = JTNESerializer.Deserialize<JTNE_0x05>(data); | ||||
Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X05.LoginTime); | Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X05.LoginTime); | ||||
Assert.Equal(6666, jTNE_0X05.LoginNum); | Assert.Equal(6666, jTNE_0X05.LoginNum); | ||||
@@ -16,13 +16,13 @@ namespace JTNE.Protocol.Test.MessageBody | |||||
jTNE_0X06.LogoutTime = DateTime.Parse("2019-01-22 23:55:56"); | jTNE_0X06.LogoutTime = DateTime.Parse("2019-01-22 23:55:56"); | ||||
jTNE_0X06.LogoutNum = 6666; | jTNE_0X06.LogoutNum = 6666; | ||||
var hex = JTNESerializer.Serialize(jTNE_0X06).ToHexString(); | var hex = JTNESerializer.Serialize(jTNE_0X06).ToHexString(); | ||||
Assert.Equal("1901222355561A0A", hex); | |||||
Assert.Equal("1301161737381A0A", hex); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
var data = "1901222355561A0A".ToHexBytes(); | |||||
var data = "1301161737381A0A".ToHexBytes(); | |||||
JTNE_0x06 jTNE_0X06 = JTNESerializer.Deserialize<JTNE_0x06>(data); | JTNE_0x06 jTNE_0X06 = JTNESerializer.Deserialize<JTNE_0x06>(data); | ||||
Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X06.LogoutTime); | Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X06.LogoutTime); | ||||
Assert.Equal(6666, jTNE_0X06.LogoutNum); | Assert.Equal(6666, jTNE_0X06.LogoutNum); | ||||
@@ -0,0 +1,56 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x01_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.login.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
JTNE_0x01 jTNE_0X01 = new JTNE_0x01(); | |||||
jTNE_0X01.PDATime = DateTime.Parse("2019-01-22 23:55:56"); | |||||
jTNE_0X01.LoginNum = 1; | |||||
jTNE_0X01.BatteryLength = 0x04; | |||||
jTNE_0X01.SIM = "12345678998765432100"; | |||||
jTNE_0X01.BatteryNos = new List<string>() | |||||
{ | |||||
"1234", | |||||
"4567", | |||||
"9870" | |||||
}; | |||||
jTNEPackage.Bodies = jTNE_0X01; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232301FE313233343536373839000000000000000001002A130116173738000131323334353637383939383736353433323130300304313233343435363739383730FD", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232301FE313233343536373839000000000000000001002A130116173738000131323334353637383939383736353433323130300304313233343435363739383730FD".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.login.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
JTNE_0x01 jTNE_0X01 = jTNEPackage.Bodies as JTNE_0x01; | |||||
Assert.Equal(DateTime.Parse("2019-01-22 23:55:56"), jTNE_0X01.PDATime); | |||||
Assert.Equal(1, jTNE_0X01.LoginNum); | |||||
Assert.Equal(0x04, jTNE_0X01.BatteryLength); | |||||
Assert.Equal("12345678998765432100", jTNE_0X01.SIM); | |||||
Assert.Equal(3, jTNE_0X01.BatteryCount); | |||||
Assert.Equal("1234", jTNE_0X01.BatteryNos[0]); | |||||
Assert.Equal("4567", jTNE_0X01.BatteryNos[1]); | |||||
Assert.Equal("9870", jTNE_0X01.BatteryNos[2]); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,41 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x04_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.loginout.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
JTNE_0x04 jTNE_0X04 = new JTNE_0x04(); | |||||
jTNE_0X04.LogoutTime = DateTime.Parse("2019-01-23 23:55:56"); | |||||
jTNE_0X04.LogoutNum = 1; | |||||
jTNEPackage.Bodies = jTNE_0X04; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232304FE31323334353637383900000000000000000100081301171737380001DE", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232304FE31323334353637383900000000000000000100081301171737380001DE".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.loginout.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
JTNE_0x04 jTNE_0X04 = jTNEPackage.Bodies as JTNE_0x04; | |||||
Assert.Equal(DateTime.Parse("2019-01-23 23:55:56"), jTNE_0X04.LogoutTime); | |||||
Assert.Equal(1, jTNE_0X04.LogoutNum); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,46 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x05_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.platformlogin.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
JTNE_0x05 jTNE_0X05 = new JTNE_0x05(); | |||||
jTNE_0X05.LoginTime = DateTime.Parse("2019-01-23 23:55:56"); | |||||
jTNE_0X05.LoginNum = 6666; | |||||
jTNE_0X05.PlatformUserName = "SmallChi518"; | |||||
jTNE_0X05.PlatformPassword = "1234567890123456789"; | |||||
jTNEPackage.Bodies = jTNE_0X05; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232305FE31323334353637383900000000000000000100291301171737381A0A536D616C6C43686935313800313233343536373839303132333435363738390001FF", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232305FE31323334353637383900000000000000000100291301171737381A0A536D616C6C43686935313800313233343536373839303132333435363738390001FF".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.platformlogin.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
JTNE_0x05 jTNE_0X05 = jTNEPackage.Bodies as JTNE_0x05; | |||||
Assert.Equal(DateTime.Parse("2019-01-23 23:55:56"), jTNE_0X05.LoginTime); | |||||
Assert.Equal(6666, jTNE_0X05.LoginNum); | |||||
Assert.Equal("SmallChi518", jTNE_0X05.PlatformUserName); | |||||
Assert.Equal("1234567890123456789", jTNE_0X05.PlatformPassword); | |||||
Assert.Equal(0x01, jTNE_0X05.EncryptMethod); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,41 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x06_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.platformlogout.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
JTNE_0x06 jTNE_0X06 = new JTNE_0x06(); | |||||
jTNE_0X06.LogoutTime = DateTime.Parse("2019-01-23 23:55:56"); | |||||
jTNE_0X06.LogoutNum = 1; | |||||
jTNEPackage.Bodies = jTNE_0X06; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232306FE31323334353637383900000000000000000100081301171737380001DC", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232306FE31323334353637383900000000000000000100081301171737380001DC".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.platformlogout.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
JTNE_0x06 jTNE_0X06 = jTNEPackage.Bodies as JTNE_0x06; | |||||
Assert.Equal(DateTime.Parse("2019-01-23 23:55:56"), jTNE_0X06.LogoutTime); | |||||
Assert.Equal(1, jTNE_0X06.LogoutNum); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x07_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.heartbeat.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232307FE3132333435363738390000000000000000010000C9", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232307FE3132333435363738390000000000000000010000C9".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.heartbeat.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
Assert.Null(jTNEPackage.Bodies); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.MessageBody; | |||||
namespace JTNE.Protocol.Test.Package | |||||
{ | |||||
public class JTNE_0x08_PackageTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = JTNEAskId.CMD.ToByteValue(); | |||||
jTNEPackage.MsgId = JTNEMsgId.checktime.ToByteValue(); | |||||
jTNEPackage.VIN = "123456789"; | |||||
var hex = JTNESerializer.Serialize(jTNEPackage).ToHexString(); | |||||
Assert.Equal("232308FE3132333435363738390000000000000000010000C6", hex); | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
var data = "232308FE3132333435363738390000000000000000010000C6".ToHexBytes(); | |||||
JTNEPackage jTNEPackage = JTNESerializer.Deserialize(data); | |||||
Assert.Equal(JTNEAskId.CMD.ToByteValue(), jTNEPackage.AskId); | |||||
Assert.Equal(JTNEMsgId.checktime.ToByteValue(), jTNEPackage.MsgId); | |||||
Assert.Equal("123456789", jTNEPackage.VIN); | |||||
Assert.Null(jTNEPackage.Bodies); | |||||
} | |||||
} | |||||
} |
@@ -19,8 +19,12 @@ namespace JTNE.Protocol.Enums | |||||
BCCCodeError = 1002, | BCCCodeError = 1002, | ||||
/// <summary> | /// <summary> | ||||
/// 没有标记 | /// 没有标记 | ||||
/// <see cref="JT808.Protocol.Attributes.JT808FormatterAttribute"/> | |||||
/// <see cref="JTNE.Protocol.Attributes.JTNEFormatterAttribute"/> | |||||
/// </summary> | /// </summary> | ||||
GetFormatterAttributeError = 1003, | GetFormatterAttributeError = 1003, | ||||
/// <summary> | |||||
/// 解析数据体错误 | |||||
/// </summary> | |||||
BodiesParseError=1004, | |||||
} | } | ||||
} | } |
@@ -1,4 +1,6 @@ | |||||
using System; | |||||
using JTNE.Protocol.Attributes; | |||||
using JTNE.Protocol.MessageBody; | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
@@ -12,6 +14,7 @@ namespace JTNE.Protocol.Enums | |||||
/// <summary> | /// <summary> | ||||
/// 车辆登入 | /// 车辆登入 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x01))] | |||||
login = 0x01, | login = 0x01, | ||||
/// <summary> | /// <summary> | ||||
/// 实时信息上传 | /// 实时信息上传 | ||||
@@ -24,22 +27,27 @@ namespace JTNE.Protocol.Enums | |||||
/// <summary> | /// <summary> | ||||
/// 车辆登出 | /// 车辆登出 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x04))] | |||||
loginout = 0x04, | loginout = 0x04, | ||||
/// <summary> | /// <summary> | ||||
/// 平台登入 | /// 平台登入 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x05))] | |||||
platformlogin = 0x05, | platformlogin = 0x05, | ||||
/// <summary> | /// <summary> | ||||
/// 平台登出 | /// 平台登出 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x06))] | |||||
platformlogout = 0x06, | platformlogout = 0x06, | ||||
/// <summary> | /// <summary> | ||||
/// 心跳 | /// 心跳 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x07))] | |||||
heartbeat = 0x07, | heartbeat = 0x07, | ||||
/// <summary> | /// <summary> | ||||
/// 终端校时 | /// 终端校时 | ||||
/// </summary> | /// </summary> | ||||
[JTNEBodiesType(typeof(JTNE_0x08))] | |||||
checktime = 0x08, | checktime = 0x08, | ||||
/// <summary> | /// <summary> | ||||
/// 查询命令 | /// 查询命令 | ||||
@@ -17,6 +17,15 @@ namespace JTNE.Protocol.Exceptions | |||||
this.ErrorCode = errorCode; | this.ErrorCode = errorCode; | ||||
} | } | ||||
public JTNEException(JTNEErrorCode errorCode, Exception ex) : base(ex.Message, ex) | |||||
{ | |||||
ErrorCode = errorCode; | |||||
} | |||||
public JTNEException(JTNEErrorCode errorCode, string message, Exception ex) : base(ex.Message, ex) | |||||
{ | |||||
ErrorCode = errorCode; | |||||
} | |||||
public JTNEErrorCode ErrorCode { get; } | public JTNEErrorCode ErrorCode { get; } | ||||
} | } | ||||
} | } |
@@ -21,7 +21,7 @@ namespace JTNE.Protocol.Extensions | |||||
/// <param name="offset"></param> | /// <param name="offset"></param> | ||||
/// <param name="format">D2: 10 X2:16</param> | /// <param name="format">D2: 10 X2:16</param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
public static DateTime ReadDateTime6Little(ReadOnlySpan<byte> buf, ref int offset,string format= "X2") | |||||
public static DateTime ReadDateTime6Little(ReadOnlySpan<byte> buf, ref int offset,string format= "D2") | |||||
{ | { | ||||
DateTime d = UTCBaseTime; | DateTime d = UTCBaseTime; | ||||
try | try | ||||
@@ -49,7 +49,7 @@ namespace JTNE.Protocol.Extensions | |||||
/// <param name="offset"></param> | /// <param name="offset"></param> | ||||
/// <param name="format">D2: 10 X2:16</param> | /// <param name="format">D2: 10 X2:16</param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
public static DateTime ReadDateTime4Little(ReadOnlySpan<byte> buf, ref int offset, string format = "X2") | |||||
public static DateTime ReadDateTime4Little(ReadOnlySpan<byte> buf, ref int offset, string format = "D2") | |||||
{ | { | ||||
DateTime d = UTCBaseTime; | DateTime d = UTCBaseTime; | ||||
try | try | ||||
@@ -86,7 +86,7 @@ namespace JTNE.Protocol.Extensions | |||||
/// <param name="offset"></param> | /// <param name="offset"></param> | ||||
/// <param name="format"></param> | /// <param name="format"></param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
public static DateTime ReadDateTime5Little(ReadOnlySpan<byte> buf, ref int offset, string format = "X2") | |||||
public static DateTime ReadDateTime5Little(ReadOnlySpan<byte> buf, ref int offset, string format = "D2") | |||||
{ | { | ||||
DateTime dateTime = new DateTime( | DateTime dateTime = new DateTime( | ||||
@@ -121,7 +121,7 @@ namespace JTNE.Protocol.Extensions | |||||
/// <param name="date"></param> | /// <param name="date"></param> | ||||
/// <param name="fromBase">BCD:10 HEX:16</param> | /// <param name="fromBase">BCD:10 HEX:16</param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
public static int WriteDateTime6Little(byte[] bytes, int offset, DateTime date,int fromBase=16) | |||||
public static int WriteDateTime6Little(byte[] bytes, int offset, DateTime date,int fromBase=10) | |||||
{ | { | ||||
bytes[offset] = Convert.ToByte(date.ToString("yy"), fromBase); | bytes[offset] = Convert.ToByte(date.ToString("yy"), fromBase); | ||||
bytes[offset + 1] = Convert.ToByte(date.ToString("MM"), fromBase); | bytes[offset + 1] = Convert.ToByte(date.ToString("MM"), fromBase); | ||||
@@ -0,0 +1,93 @@ | |||||
using JTNE.Protocol.Enums; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Extensions | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public static class JTNEPackageExtensions | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <typeparam name="TJTNEBodies"></typeparam> | |||||
/// <param name="msgId"></param> | |||||
/// <param name="askId"></param> | |||||
/// <param name="vin"></param> | |||||
/// <param name="bodies"></param> | |||||
/// <returns></returns> | |||||
public static JTNEPackage Create<TJTNEBodies>(this JTNEMsgId msgId,string vin, JTNEAskId askId, TJTNEBodies bodies) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = askId.ToByteValue(); | |||||
jTNEPackage.MsgId = msgId.ToByteValue(); | |||||
jTNEPackage.Bodies = bodies; | |||||
jTNEPackage.VIN = vin; | |||||
// todo:加密处理 | |||||
return jTNEPackage; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="msgId"></param> | |||||
/// <param name="vin"></param> | |||||
/// <param name="askId"></param> | |||||
/// <returns></returns> | |||||
public static JTNEPackage Create(this JTNEMsgId msgId, string vin, JTNEAskId askId) | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = askId.ToByteValue(); | |||||
jTNEPackage.MsgId = msgId.ToByteValue(); | |||||
jTNEPackage.VIN = vin; | |||||
// todo:加密处理 | |||||
return jTNEPackage; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <typeparam name="TJTNEBodies"></typeparam> | |||||
/// <param name="msgId"></param> | |||||
/// <param name="vin"></param> | |||||
/// <param name="askId"></param> | |||||
/// <param name="bodies"></param> | |||||
/// <returns></returns> | |||||
public static JTNEPackage CreateCustomMsgId<TJTNEBodies>(this byte msgId, string vin, JTNEAskId askId, TJTNEBodies bodies) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = askId.ToByteValue(); | |||||
jTNEPackage.MsgId = msgId; | |||||
jTNEPackage.Bodies = bodies; | |||||
jTNEPackage.VIN = vin; | |||||
// todo:加密处理 | |||||
return jTNEPackage; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="msgId"></param> | |||||
/// <param name="askId"></param> | |||||
/// <param name="vin"></param> | |||||
/// <returns></returns> | |||||
public static JTNEPackage CreateCustomMsgId(this byte msgId, string vin, JTNEAskId askId) | |||||
{ | |||||
JTNEPackage jTNEPackage = new JTNEPackage(); | |||||
jTNEPackage.AskId = askId.ToByteValue(); | |||||
jTNEPackage.MsgId = msgId; | |||||
jTNEPackage.VIN = vin; | |||||
// todo:加密处理 | |||||
return jTNEPackage; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,97 @@ | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.Exceptions; | |||||
using JTNE.Protocol.Extensions; | |||||
using JTNE.Protocol.Internal; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Formatters | |||||
{ | |||||
public class JTNEHeaderPackageFormatter : IJTNEFormatter<JTNEHeaderPackage> | |||||
{ | |||||
public JTNEHeaderPackage Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | |||||
{ | |||||
int offset = 0; | |||||
// 1.进行固定头校验 | |||||
if (bytes[offset] != JTNEPackage.BeginFlag && bytes[offset + 1] == JTNEPackage.BeginFlag) | |||||
throw new JTNEException(JTNEErrorCode.BeginFlagError, $"{bytes[offset]},{bytes[offset + 1]}"); | |||||
// 2.进行BCC校验码 | |||||
// 校验位 = 报文长度 - 最后一位(校验位) | |||||
if (!JTNEGlobalConfigs.Instance.SkipCRCCode) | |||||
{ | |||||
byte bCCCode = bytes[bytes.Length - 1]; | |||||
byte bCCCode2 = bytes.ToXor(2, bytes.Length - 1); | |||||
if (bCCCode != bCCCode2) | |||||
throw new JTNEException(JTNEErrorCode.BCCCodeError, $"request:{bCCCode}!=calculate:{bCCCode2}"); | |||||
} | |||||
JTNEHeaderPackage jTNEPackage = new JTNEHeaderPackage(); | |||||
offset += 2; | |||||
// 3.命令标识 | |||||
jTNEPackage.MsgId = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | |||||
// 4.应答标识 | |||||
jTNEPackage.AskId = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | |||||
// 5.VIN | |||||
jTNEPackage.VIN = JTNEBinaryExtensions.ReadStringLittle(bytes, ref offset, 17); | |||||
// 6.数据加密方式 | |||||
jTNEPackage.EncryptMethod = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | |||||
// 7.数据单元长度是数据单元的总字节数 | |||||
jTNEPackage.DataUnitLength = JTNEBinaryExtensions.ReadUInt16Little(bytes, ref offset); | |||||
// 8.数据体 | |||||
// 8.1.根据数据加密方式进行解码 | |||||
// todo: 8.2.解析出对应数据体 | |||||
if (jTNEPackage.DataUnitLength > 0) | |||||
{ | |||||
Type jTNEBodiesImplType = JTNEMsgIdFactory.GetBodiesImplTypeByMsgId(jTNEPackage.MsgId); | |||||
if (jTNEBodiesImplType != null) | |||||
{ | |||||
int bodyReadSize = 0; | |||||
try | |||||
{ | |||||
jTNEPackage.Bodies = bytes.Slice(offset, jTNEPackage.DataUnitLength).ToArray(); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
throw new JTNEException(JTNEErrorCode.BodiesParseError, ex); | |||||
} | |||||
offset += bodyReadSize; | |||||
} | |||||
} | |||||
// 9.校验码 | |||||
jTNEPackage.BCCCode = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | |||||
readSize = offset; | |||||
return jTNEPackage; | |||||
} | |||||
public int Serialize(ref byte[] bytes, int offset, JTNEHeaderPackage value) | |||||
{ | |||||
// 1.起始符1 | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.BeginFlag1); | |||||
// 2.起始符2 | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.BeginFlag2); | |||||
// 3.命令标识 | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.MsgId); | |||||
// 4.应答标识 | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.AskId); | |||||
// 5.VIN | |||||
offset += JTNEBinaryExtensions.WriteStringPadRightLittle(bytes, offset, value.VIN, 17); | |||||
// 6.数据加密方式 | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.EncryptMethod); | |||||
if (value.Bodies != null) | |||||
{ | |||||
// 7.数据体 | |||||
offset += JTNEBinaryExtensions.WriteUInt16Little(bytes, offset, (ushort)value.Bodies.Length); | |||||
// 8.处理数据体 | |||||
offset += JTNEBinaryExtensions.WriteBytesLittle(bytes, offset, value.Bodies); | |||||
} | |||||
else | |||||
{ | |||||
offset += JTNEBinaryExtensions.WriteUInt16Little(bytes, offset, 0); | |||||
} | |||||
// 9.校验码 | |||||
var bccCode = bytes.ToXor(2, offset); | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, bccCode); | |||||
return offset; | |||||
} | |||||
} | |||||
} |
@@ -1,6 +1,7 @@ | |||||
using JTNE.Protocol.Enums; | using JTNE.Protocol.Enums; | ||||
using JTNE.Protocol.Exceptions; | using JTNE.Protocol.Exceptions; | ||||
using JTNE.Protocol.Extensions; | using JTNE.Protocol.Extensions; | ||||
using JTNE.Protocol.Internal; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
@@ -9,11 +10,13 @@ namespace JTNE.Protocol.Formatters | |||||
{ | { | ||||
public class JTNEPackageFormatter : IJTNEFormatter<JTNEPackage> | public class JTNEPackageFormatter : IJTNEFormatter<JTNEPackage> | ||||
{ | { | ||||
private const byte FixedDataBodyLength = 2; | |||||
public JTNEPackage Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | public JTNEPackage Deserialize(ReadOnlySpan<byte> bytes, out int readSize) | ||||
{ | { | ||||
int offset = 0; | int offset = 0; | ||||
// 1.进行固定头校验 | // 1.进行固定头校验 | ||||
if (bytes[offset] != JTNEPackage.BeginFlag && bytes[offset+1] == JTNEPackage.BeginFlag) | |||||
if (bytes[offset] != JTNEPackage.BeginFlag && bytes[offset + 1] == JTNEPackage.BeginFlag) | |||||
throw new JTNEException(JTNEErrorCode.BeginFlagError, $"{bytes[offset]},{bytes[offset + 1]}"); | throw new JTNEException(JTNEErrorCode.BeginFlagError, $"{bytes[offset]},{bytes[offset + 1]}"); | ||||
// 2.进行BCC校验码 | // 2.进行BCC校验码 | ||||
// 校验位 = 报文长度 - 最后一位(校验位) | // 校验位 = 报文长度 - 最后一位(校验位) | ||||
@@ -31,15 +34,34 @@ namespace JTNE.Protocol.Formatters | |||||
// 4.应答标识 | // 4.应答标识 | ||||
jTNEPackage.AskId = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | jTNEPackage.AskId = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | ||||
// 5.VIN | // 5.VIN | ||||
jTNEPackage.VIN = JTNEBinaryExtensions.ReadStringLittle(bytes, ref offset,17); | |||||
jTNEPackage.VIN = JTNEBinaryExtensions.ReadStringLittle(bytes, ref offset, 17); | |||||
// 6.数据加密方式 | // 6.数据加密方式 | ||||
jTNEPackage.EncryptMethod = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | jTNEPackage.EncryptMethod = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | ||||
// 7.数据单元长度是数据单元的总字节数 | // 7.数据单元长度是数据单元的总字节数 | ||||
jTNEPackage.DataUnitLength = JTNEBinaryExtensions.ReadUInt16Little(bytes, ref offset); | jTNEPackage.DataUnitLength = JTNEBinaryExtensions.ReadUInt16Little(bytes, ref offset); | ||||
// 8.数据体 | // 8.数据体 | ||||
// 8.1.根据数据加密方式进行解码 | // 8.1.根据数据加密方式进行解码 | ||||
// 8.2.解析出对应数据体 | |||||
jTNEPackage.Bodies = JTNEBinaryExtensions.ReadBytesLittle(bytes, ref offset, jTNEPackage.DataUnitLength); | |||||
// todo: 8.2.解析出对应数据体 | |||||
if (jTNEPackage.DataUnitLength > 0) | |||||
{ | |||||
Type jTNEBodiesImplType = JTNEMsgIdFactory.GetBodiesImplTypeByMsgId(jTNEPackage.MsgId); | |||||
if (jTNEBodiesImplType != null) | |||||
{ | |||||
int bodyReadSize = 0; | |||||
try | |||||
{ | |||||
jTNEPackage.Bodies = JTNEFormatterResolverExtensions.JTNEDynamicDeserialize( | |||||
JTNEFormatterExtensions.GetFormatter(jTNEBodiesImplType), | |||||
bytes.Slice(offset, jTNEPackage.DataUnitLength), | |||||
out bodyReadSize); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
throw new JTNEException(JTNEErrorCode.BodiesParseError, ex); | |||||
} | |||||
offset += bodyReadSize; | |||||
} | |||||
} | |||||
// 9.校验码 | // 9.校验码 | ||||
jTNEPackage.BCCCode = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | jTNEPackage.BCCCode = JTNEBinaryExtensions.ReadByteLittle(bytes, ref offset); | ||||
readSize = offset; | readSize = offset; | ||||
@@ -57,17 +79,33 @@ namespace JTNE.Protocol.Formatters | |||||
// 4.应答标识 | // 4.应答标识 | ||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.AskId); | offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.AskId); | ||||
// 5.VIN | // 5.VIN | ||||
offset += JTNEBinaryExtensions.WriteStringPadRightLittle(bytes, offset, value.VIN,17); | |||||
offset += JTNEBinaryExtensions.WriteStringPadRightLittle(bytes, offset, value.VIN, 17); | |||||
// 6.数据加密方式 | // 6.数据加密方式 | ||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.MsgId); | |||||
// 7.数据单元长度是数据单元的总字节数 | |||||
// 7.1.先解析出数据体 | |||||
// 7.2.判断是否有加密 | |||||
offset += JTNEBinaryExtensions.WriteUInt16Little(bytes, offset,(ushort)value.Bodies.Length); | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, value.EncryptMethod); | |||||
// 7.记录存储数据长度的当前偏移量 | |||||
int tmpOffset = offset; | |||||
offset += FixedDataBodyLength; | |||||
// 8.数据体 | // 8.数据体 | ||||
offset += JTNEBinaryExtensions.WriteBytesLittle(bytes, offset,value.Bodies); | |||||
// 9.校验码 | |||||
var bccCode = bytes.ToXor(2, offset - 2); | |||||
Type jTNEBodiesImplType = JTNEMsgIdFactory.GetBodiesImplTypeByMsgId(value.MsgId); | |||||
int messageBodyOffset = 0; | |||||
if (jTNEBodiesImplType != null) | |||||
{ | |||||
if (value.Bodies != null) | |||||
{ | |||||
// 8.1 处理数据体 | |||||
// todo: 8.2.判断是否有加密 | |||||
messageBodyOffset = JTNEFormatterResolverExtensions.JTNEDynamicSerialize( | |||||
JTNEFormatterExtensions.GetFormatter(jTNEBodiesImplType), | |||||
ref bytes, | |||||
offset, | |||||
value.Bodies); | |||||
// 9.通过tmpOffset反写数据单元长度 | |||||
JTNEBinaryExtensions.WriteUInt16Little(bytes, tmpOffset, (ushort)(messageBodyOffset - offset)); | |||||
offset = messageBodyOffset; | |||||
} | |||||
} | |||||
// 10.校验码 | |||||
var bccCode = bytes.ToXor(2, offset); | |||||
offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, bccCode); | offset += JTNEBinaryExtensions.WriteByteLittle(bytes, offset, bccCode); | ||||
return offset; | return offset; | ||||
} | } | ||||
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Interfaces | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public interface IDeviceMsgSNDistributed : IMsgSNDistributed | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Interfaces | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public interface IMsgSNDistributed | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
ushort Increment(); | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Interfaces | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public interface IPlatformMsgSNDistributed: IMsgSNDistributed | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
using JTNE.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JTNE.Protocol.Internal | |||||
{ | |||||
internal class DefaultDeviceMsgSNDistributedImpl : IDeviceMsgSNDistributed | |||||
{ | |||||
int _counter = 0; | |||||
public ushort Increment() | |||||
{ | |||||
return (ushort)Interlocked.Increment(ref _counter); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
using JTNE.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JTNE.Protocol.Internal | |||||
{ | |||||
internal class DefaultPlatformMsgSNDistributedImpl : IPlatformMsgSNDistributed | |||||
{ | |||||
int _counter = 0; | |||||
public ushort Increment() | |||||
{ | |||||
return (ushort)Interlocked.Increment(ref _counter); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,48 @@ | |||||
using JTNE.Protocol.Attributes; | |||||
using JTNE.Protocol.Enums; | |||||
using JTNE.Protocol.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JTNE.Protocol.Internal | |||||
{ | |||||
internal static class JTNEMsgIdFactory | |||||
{ | |||||
private static readonly Dictionary<byte, Type> map; | |||||
static JTNEMsgIdFactory() | |||||
{ | |||||
map = new Dictionary<byte, Type>(); | |||||
InitMap(); | |||||
} | |||||
internal static Type GetBodiesImplTypeByMsgId(byte msgId) =>map.TryGetValue(msgId, out Type type) ? type : null; | |||||
private static void InitMap() | |||||
{ | |||||
foreach(var item in Enum.GetNames(typeof(JTNEMsgId))) | |||||
{ | |||||
JTNEMsgId msgId = item.ToEnum<JTNEMsgId>(); | |||||
JTNEBodiesTypeAttribute jT808BodiesTypeAttribute = msgId.GetAttribute<JTNEBodiesTypeAttribute>(); | |||||
map.Add((byte)msgId, jT808BodiesTypeAttribute?.JT808BodiesType); | |||||
} | |||||
} | |||||
internal static void SetMap<TJTNEBodies>(byte msgId) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
if(!map.ContainsKey(msgId)) | |||||
map.Add(msgId, typeof(TJTNEBodies)); | |||||
} | |||||
internal static void ReplaceMap<TJTNEBodies>(byte msgId) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
if (!map.ContainsKey(msgId)) | |||||
map.Add(msgId, typeof(TJTNEBodies)); | |||||
else | |||||
map[msgId] = typeof(TJTNEBodies); | |||||
} | |||||
} | |||||
} |
@@ -22,7 +22,7 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | ||||
<DocumentationFile>D:\My Project\JTNewEnergy\src\JTNE.Protocol\JTNE.Protocol.xml</DocumentationFile> | |||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\JTNE.Protocol.xml</DocumentationFile> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -1,56 +0,0 @@ | |||||
<?xml version="1.0"?> | |||||
<doc> | |||||
<assembly> | |||||
<name>JTNE.Protocol</name> | |||||
</assembly> | |||||
<members> | |||||
<member name="T:JTNE.Protocol.JTNEPackage"> | |||||
<summary> | |||||
新能源包 | |||||
</summary> | |||||
</member> | |||||
<member name="F:JTNE.Protocol.JTNEPackage.HeaderFixedByteLength"> | |||||
<summary> | |||||
固定为24个字节长度 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.BeginFlag"> | |||||
<summary> | |||||
起始符 | |||||
0x23 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.MsgId"> | |||||
<summary> | |||||
命令标识 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.AskId"> | |||||
<summary> | |||||
应答标志 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.VIN"> | |||||
<summary> | |||||
车辆识别码 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.EncryptMethod"> | |||||
<summary> | |||||
数据加密方式 | |||||
0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.DataUnitLength"> | |||||
<summary> | |||||
数据单元长度是数据单元的总字节数,有效值范围:0-65531 | |||||
</summary> | |||||
</member> | |||||
<member name="P:JTNE.Protocol.JTNEPackage.BCCCode"> | |||||
<summary> | |||||
采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止, | |||||
校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密 | |||||
</summary> | |||||
</member> | |||||
</members> | |||||
</doc> |
@@ -1,4 +1,6 @@ | |||||
using System; | |||||
using JTNE.Protocol.Interfaces; | |||||
using JTNE.Protocol.Internal; | |||||
using System; | |||||
using System.Text; | using System.Text; | ||||
namespace JTNE.Protocol | namespace JTNE.Protocol | ||||
@@ -15,6 +17,8 @@ namespace JTNE.Protocol | |||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | ||||
Encoding = Encoding.UTF8; | Encoding = Encoding.UTF8; | ||||
SkipCRCCode = false; | SkipCRCCode = false; | ||||
DeviceMsgSNDistributed = new DefaultDeviceMsgSNDistributedImpl(); | |||||
PlatformMsgSNDistributed = new DefaultPlatformMsgSNDistributedImpl(); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// 字符串编码 | /// 字符串编码 | ||||
@@ -32,13 +36,44 @@ namespace JTNE.Protocol | |||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 设备流水号 | |||||
/// </summary> | |||||
public IDeviceMsgSNDistributed DeviceMsgSNDistributed { get; private set; } | |||||
/// <summary> | |||||
/// 平台流水号 | |||||
/// </summary> | |||||
public IPlatformMsgSNDistributed PlatformMsgSNDistributed { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// 跳过校验码 | /// 跳过校验码 | ||||
/// 测试的时候需要手动修改值,避免验证 | /// 测试的时候需要手动修改值,避免验证 | ||||
/// 默认:false | /// 默认:false | ||||
/// </summary> | /// </summary> | ||||
public bool SkipCRCCode { get; private set; } | public bool SkipCRCCode { get; private set; } | ||||
/// <summary> | |||||
/// 注册自定义消息 | |||||
/// </summary> | |||||
/// <typeparam name="TJTNEBodies"></typeparam> | |||||
/// <param name="msgId"></param> | |||||
/// <returns></returns> | |||||
public JTNEGlobalConfigs Register_CustomMsgId<TJTNEBodies>(byte customMsgId) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
JTNEMsgIdFactory.SetMap<TJTNEBodies>(customMsgId); | |||||
return instance.Value; | |||||
} | |||||
/// <summary> | |||||
/// 重写消息 | |||||
/// </summary> | |||||
/// <typeparam name="TJTNEBodies"></typeparam> | |||||
/// <param name="overwriteMsgId"></param> | |||||
/// <returns></returns> | |||||
public JTNEGlobalConfigs Overwrite_MsgId<TJTNEBodies>(byte overwriteMsgId) | |||||
where TJTNEBodies : JTNEBodies | |||||
{ | |||||
JTNEMsgIdFactory.ReplaceMap<TJTNEBodies>(overwriteMsgId); | |||||
return instance.Value; | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// 设置跳过校验码 | /// 设置跳过校验码 | ||||
/// 场景:测试的时候,可能需要手动改数据,所以测试的时候有用 | /// 场景:测试的时候,可能需要手动改数据,所以测试的时候有用 | ||||
@@ -50,5 +85,25 @@ namespace JTNE.Protocol | |||||
instance.Value.SkipCRCCode = skipCRCCode; | instance.Value.SkipCRCCode = skipCRCCode; | ||||
return instance.Value; | return instance.Value; | ||||
} | } | ||||
/// <summary> | |||||
/// 设置设备流水号 | |||||
/// </summary> | |||||
/// <param name="deviceMsgSNDistributed"></param> | |||||
/// <returns></returns> | |||||
public JTNEGlobalConfigs SetDeviceMsgSNDistributed(IDeviceMsgSNDistributed deviceMsgSNDistributed) | |||||
{ | |||||
instance.Value.DeviceMsgSNDistributed = deviceMsgSNDistributed; | |||||
return instance.Value; | |||||
} | |||||
/// <summary> | |||||
/// 设置平台流水号 | |||||
/// </summary> | |||||
/// <param name="platformMsgSNDistributed"></param> | |||||
/// <returns></returns> | |||||
public JTNEGlobalConfigs SetPlatformMsgSNDistributed(IPlatformMsgSNDistributed platformMsgSNDistributed) | |||||
{ | |||||
instance.Value.PlatformMsgSNDistributed = platformMsgSNDistributed; | |||||
return instance.Value; | |||||
} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,56 @@ | |||||
using JTNE.Protocol.Attributes; | |||||
using JTNE.Protocol.Formatters; | |||||
using System; | |||||
using System.IO; | |||||
namespace JTNE.Protocol | |||||
{ | |||||
/// <summary> | |||||
/// 新能源包 | |||||
/// </summary> | |||||
[JTNEFormatter(typeof(JTNEHeaderPackageFormatter))] | |||||
public class JTNEHeaderPackage | |||||
{ | |||||
/// <summary> | |||||
/// 起始符1 | |||||
/// </summary> | |||||
public byte BeginFlag1 { get; set; } = JTNEPackage.BeginFlag; | |||||
/// <summary> | |||||
/// 起始符2 | |||||
/// </summary> | |||||
public byte BeginFlag2 { get; set; } = JTNEPackage.BeginFlag; | |||||
/// <summary> | |||||
/// 命令标识 | |||||
/// <see cref="JTNE.Protocol.Enums.JTNEMsgId"/> | |||||
/// </summary> | |||||
public byte MsgId { get; set; } | |||||
/// <summary> | |||||
/// 应答标志 | |||||
/// <see cref="JTNE.Protocol.Enums.JTNEAskId"/> | |||||
/// </summary> | |||||
public byte AskId { get; set; } | |||||
/// <summary> | |||||
/// 车辆识别码 | |||||
/// </summary> | |||||
public string VIN { get; set; } | |||||
/// <summary> | |||||
/// 数据加密方式 (默认不加密) | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
/// <see cref="JTNE.Protocol.Enums.JTNEEncryptMethod"/> | |||||
/// </summary> | |||||
public byte EncryptMethod { get; set; } = 0x01; | |||||
/// <summary> | |||||
/// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | |||||
/// </summary> | |||||
public ushort DataUnitLength { get; set; } | |||||
/// <summary> | |||||
/// 数据体 | |||||
/// </summary> | |||||
public byte[] Bodies { get; set; } | |||||
/// <summary> | |||||
/// 采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止, | |||||
/// 校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密 | |||||
/// </summary> | |||||
public byte BCCCode { get; set; } | |||||
} | |||||
} |
@@ -11,20 +11,15 @@ namespace JTNE.Protocol | |||||
[JTNEFormatter(typeof(JTNEPackageFormatter))] | [JTNEFormatter(typeof(JTNEPackageFormatter))] | ||||
public class JTNEPackage | public class JTNEPackage | ||||
{ | { | ||||
/// <summary> | |||||
/// 固定为24个字节长度 | |||||
/// </summary> | |||||
//public const int HeaderFixedByteLength = 24; | |||||
public const byte BeginFlag = 0x23; | public const byte BeginFlag = 0x23; | ||||
/// <summary> | /// <summary> | ||||
/// 起始符1 | /// 起始符1 | ||||
/// </summary> | /// </summary> | ||||
public byte BeginFlag1 { get; set; } = 0x23; | |||||
public byte BeginFlag1 { get; set; } = BeginFlag; | |||||
/// <summary> | /// <summary> | ||||
/// 起始符2 | /// 起始符2 | ||||
/// </summary> | /// </summary> | ||||
public byte BeginFlag2 { get; set; } = 0x23; | |||||
public byte BeginFlag2 { get; set; } = BeginFlag; | |||||
/// <summary> | /// <summary> | ||||
/// 命令标识 | /// 命令标识 | ||||
/// <see cref="JTNE.Protocol.Enums.JTNEMsgId"/> | /// <see cref="JTNE.Protocol.Enums.JTNEMsgId"/> | ||||
@@ -40,11 +35,11 @@ namespace JTNE.Protocol | |||||
/// </summary> | /// </summary> | ||||
public string VIN { get; set; } | public string VIN { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// 数据加密方式 | |||||
/// 数据加密方式 (默认不加密) | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | ||||
/// <see cref="JTNE.Protocol.Enums.JTNEEncryptMethod"/> | /// <see cref="JTNE.Protocol.Enums.JTNEEncryptMethod"/> | ||||
/// </summary> | /// </summary> | ||||
public byte EncryptMethod { get; set; } | |||||
public byte EncryptMethod { get; set; } = 0x01; | |||||
/// <summary> | /// <summary> | ||||
/// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | /// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | ||||
/// </summary> | /// </summary> | ||||
@@ -52,7 +47,7 @@ namespace JTNE.Protocol | |||||
/// <summary> | /// <summary> | ||||
/// 数据体 | /// 数据体 | ||||
/// </summary> | /// </summary> | ||||
public byte[] Bodies { get; set; } | |||||
public JTNEBodies Bodies { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// 采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止, | /// 采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止, | ||||
/// 校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密 | /// 校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密 | ||||
@@ -30,8 +30,10 @@ namespace JTNE.Protocol.MessageBody | |||||
/// </summary> | /// </summary> | ||||
public string PlatformPassword { get; set; } | public string PlatformPassword { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// 加密规则 | |||||
/// 数据加密方式 (默认不加密) | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
/// <see cref="JTNE.Protocol.Enums.JTNEEncryptMethod"/> | |||||
/// </summary> | /// </summary> | ||||
public byte EncryptMethod{ get; set; } | |||||
public byte EncryptMethod { get; set; } = 0x01; | |||||
} | } | ||||
} | } |