@@ -3,7 +3,6 @@ using System.Diagnostics; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Text; | using System.Text; | ||||
using JT809.Protocol.Configs; | using JT809.Protocol.Configs; | ||||
using JT809.Protocol.Encrypt; | |||||
using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
@@ -12,31 +11,31 @@ namespace JT809.Protocol.Test.Escape | |||||
[TestClass] | [TestClass] | ||||
public class JT809EscapeImplTest:BaseTest | public class JT809EscapeImplTest:BaseTest | ||||
{ | { | ||||
public IEncrypt encrypt; | |||||
//public IEncrypt encrypt; | |||||
public JT809EscapeImplTest() | |||||
{ | |||||
encrypt = new JT809EncryptImpl(base.JT809EncryptConfig); | |||||
} | |||||
//public JT809EscapeImplTest() | |||||
//{ | |||||
// encrypt = new JT809EncryptImpl(base.JT809EncryptConfig); | |||||
//} | |||||
[TestMethod] | |||||
public void Encrypt() | |||||
{ | |||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("smallchi"); | |||||
Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
encrypt.Encrypt(buffer); | |||||
Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
} | |||||
//[TestMethod] | |||||
//public void Encrypt() | |||||
//{ | |||||
// byte[] buffer = System.Text.Encoding.UTF8.GetBytes("smallchi"); | |||||
// Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
// encrypt.Encrypt(buffer); | |||||
// Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
//} | |||||
[TestMethod] | |||||
public void Decrypt() | |||||
{ | |||||
byte[] buffer =new byte [8]{ 92, 113, 125, 112, 112, 127, 116, 117}; | |||||
Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
encrypt.Decrypt(buffer); | |||||
Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
string name = System.Text.Encoding.UTF8.GetString(buffer); | |||||
Assert.AreEqual("smallchi", name); | |||||
} | |||||
//[TestMethod] | |||||
//public void Decrypt() | |||||
//{ | |||||
// byte[] buffer =new byte [8]{ 92, 113, 125, 112, 112, 127, 116, 117}; | |||||
// Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
// encrypt.Decrypt(buffer); | |||||
// Debug.WriteLine(JsonConvert.SerializeObject(buffer.Select(s => s).ToList())); | |||||
// string name = System.Text.Encoding.UTF8.GetString(buffer); | |||||
// Assert.AreEqual("smallchi", name); | |||||
//} | |||||
} | } | ||||
} | } |
@@ -1,11 +1,11 @@ | |||||
namespace JT809.Protocol.ProtocolPacket | |||||
{ | |||||
/// <summary> | |||||
/// 报文加密标识位 b: 0 表示报文不加密,1 表示报文加密。 | |||||
/// </summary> | |||||
public enum EncryptEnum : byte | |||||
{ | |||||
No = 0X00, | |||||
Yes = 0X01, | |||||
} | |||||
} | |||||
namespace JT809.Protocol.Enums | |||||
{ | |||||
/// <summary> | |||||
/// 报文加密标识位 b: 0 表示报文不加密,1 表示报文加密。 | |||||
/// </summary> | |||||
public enum EncryptOpitions : byte | |||||
{ | |||||
None = 0X00, | |||||
Common = 0X01, | |||||
} | |||||
} |
@@ -36,10 +36,7 @@ namespace JT809.Protocol.Escape | |||||
} | } | ||||
dataList.Add(bodyBuffer[bodyBuffer.Length - 1]); | dataList.Add(bodyBuffer[bodyBuffer.Length - 1]); | ||||
var tempBuffe = dataList.ToArray(); | var tempBuffe = dataList.ToArray(); | ||||
if (encrypt != null) | |||||
{ | |||||
encrypt.Encrypt(tempBuffe); | |||||
} | |||||
return tempBuffe; | return tempBuffe; | ||||
} | } | ||||
@@ -9,8 +9,20 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Folder Include="Encrypt\" /> | |||||
<Folder Include="ProtocolPacket\Message\SlaveLink\" /> | |||||
<Compile Remove="Encrypt\**" /> | |||||
<Compile Remove="Escape\**" /> | |||||
<Compile Remove="ProtocolPacket\Message\**" /> | |||||
<EmbeddedResource Remove="Encrypt\**" /> | |||||
<EmbeddedResource Remove="Escape\**" /> | |||||
<EmbeddedResource Remove="ProtocolPacket\Message\**" /> | |||||
<None Remove="Encrypt\**" /> | |||||
<None Remove="Escape\**" /> | |||||
<None Remove="ProtocolPacket\Message\**" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Compile Remove="IEncrypt.cs" /> | |||||
<Compile Remove="IEscape.cs" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |
@@ -0,0 +1,53 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Text; | |||||
namespace JT809.Protocol.ProtocolPacket | |||||
{ | |||||
public abstract class BufferedEntityBase : IBuffered, IBuffer | |||||
{ | |||||
public byte[] Buffer { get; protected set; } | |||||
public virtual byte[] ToBuffer() | |||||
{ | |||||
using (var stream = new MemoryStream()) | |||||
{ | |||||
var writer = new BinaryWriter(stream); | |||||
OnWriteToBuffer(writer); | |||||
var reader = new BinaryReader(stream); | |||||
stream.Seek(0, SeekOrigin.Begin); | |||||
Buffer = reader.ReadBytes((int)stream.Length);//stream.GetBuffer(); | |||||
stream.Close(); | |||||
} | |||||
return Buffer; | |||||
} | |||||
protected BufferedEntityBase(params object[] properties) | |||||
{ | |||||
InitializeProperties(properties, 0); | |||||
ToBuffer(); | |||||
} | |||||
protected BufferedEntityBase(byte[] buffer) | |||||
{ | |||||
Buffer = buffer; | |||||
InitializePropertiesFromBuffer(); | |||||
} | |||||
protected abstract void InitializeProperties(object[] properties, int startIndex); | |||||
protected abstract void OnInitializePropertiesFromReadBuffer(BinaryReader reader); | |||||
protected virtual void InitializePropertiesFromBuffer() | |||||
{ | |||||
using (var stream = new MemoryStream(Buffer)) | |||||
{ | |||||
var reader = new BinaryReader(stream); | |||||
OnInitializePropertiesFromReadBuffer(reader); | |||||
stream.Close(); | |||||
} | |||||
} | |||||
protected abstract void OnWriteToBuffer(BinaryWriter writer); | |||||
} | |||||
} |
@@ -0,0 +1,100 @@ | |||||
using System.Collections.Generic; | |||||
namespace JT809.Protocol.ProtocolPacket.Extensions | |||||
{ | |||||
/// <summary> | |||||
/// 包扩展方法 | |||||
/// </summary> | |||||
public static class PackageExtensions | |||||
{ | |||||
internal static byte[] Escape(this Package packege, byte[] bytes) | |||||
{ | |||||
List<byte> dataList = new List<byte>(); | |||||
dataList.Add(bytes[0]); | |||||
for (int i = 1; i < bytes.Length - 1; i++) | |||||
{ | |||||
var item = bytes[i]; | |||||
switch (item) | |||||
{ | |||||
case 0x5b: | |||||
dataList.Add(0x5a); | |||||
dataList.Add(0x01); | |||||
break; | |||||
case 0x5a: | |||||
dataList.Add(0x5a); | |||||
dataList.Add(0x02); | |||||
break; | |||||
case 0x5d: | |||||
dataList.Add(0x5e); | |||||
dataList.Add(0x01); | |||||
break; | |||||
case 0x5e: | |||||
dataList.Add(0x5e); | |||||
dataList.Add(0x02); | |||||
break; | |||||
default: | |||||
dataList.Add(item); | |||||
break; | |||||
} | |||||
} | |||||
dataList.Add(bytes[bytes.Length - 1]); | |||||
var tempBuffe = dataList.ToArray(); | |||||
return tempBuffe; | |||||
} | |||||
internal static byte[] UnEscape(this Package packege, byte[] bytes) | |||||
{ | |||||
List<byte> dataList = new List<byte>(); | |||||
dataList.Add(bytes[0]); | |||||
for (int i = 1; i < bytes.Length - 1; i++) | |||||
{ | |||||
byte first = bytes[i]; | |||||
byte second = bytes[i + 1]; | |||||
if (first == 0x5a && second == 0x01) | |||||
{ | |||||
dataList.Add(0x5b); | |||||
i++; | |||||
} | |||||
else if (first == 0x5a && second == 0x02) | |||||
{ | |||||
dataList.Add(0x5a); | |||||
i++; | |||||
} | |||||
else if (first == 0x5e && second == 0x01) | |||||
{ | |||||
dataList.Add(0x5d); | |||||
i++; | |||||
} | |||||
else if (first == 0x5e && second == 0x02) | |||||
{ | |||||
dataList.Add(0x5e); | |||||
i++; | |||||
} | |||||
else | |||||
{ | |||||
dataList.Add(first); | |||||
} | |||||
} | |||||
dataList.Add(bytes[bytes.Length - 1]); | |||||
var tempBuffe = dataList.ToArray(); | |||||
return tempBuffe; | |||||
} | |||||
internal static ushort CRC16_CCITT(this Package packege, byte[] ucbuf, int offset, int iLen) | |||||
{ | |||||
ushort crc = 0xFFFF; | |||||
ushort polynomial = 0x1021; | |||||
for (int j = 0; j < iLen; ++j) | |||||
{ | |||||
for (int i = 0; i < 8; i++) | |||||
{ | |||||
bool bit = ((ucbuf[j + offset] >> (7 - i) & 1) == 1); | |||||
bool c15 = ((crc >> 15 & 1) == 1); | |||||
crc <<= 1; | |||||
if (c15 ^ bit) crc ^= polynomial; | |||||
} | |||||
} | |||||
crc &= 0xffff; | |||||
return crc; | |||||
} | |||||
} | |||||
} |
@@ -1,11 +1,13 @@ | |||||
using System; | |||||
using JT809.Protocol.Enums; | |||||
using System; | |||||
using System.IO; | |||||
namespace JT809.Protocol.ProtocolPacket | namespace JT809.Protocol.ProtocolPacket | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Message Header 数据头 | /// Message Header 数据头 | ||||
/// </summary> | /// </summary> | ||||
public class Header | |||||
public class Header: BufferedEntityBase | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// 固定为22个字节长度 | /// 固定为22个字节长度 | ||||
@@ -34,16 +36,31 @@ namespace JT809.Protocol.ProtocolPacket | |||||
/// <summary> | /// <summary> | ||||
/// 业务数据类型 | /// 业务数据类型 | ||||
/// </summary> | /// </summary> | ||||
public ushort BusinessID { get; private set; } | |||||
public BusinessType BusinessID { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。 | /// 下级平台接入码,上级平台给下级平台分配唯一标识码。 | ||||
/// </summary> | /// </summary> | ||||
public uint GNSSCENTERID { get; set; } | public uint GNSSCENTERID { get; set; } | ||||
public Version Version { get; private set; } | public Version Version { get; private set; } | ||||
public EncryptEnum EncryptEnum { get; private set; } | |||||
public EncryptOpitions EncryptOpitions { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// 数据加密的密匙,长度为 4 个字节。 | /// 数据加密的密匙,长度为 4 个字节。 | ||||
/// </summary> | /// </summary> | ||||
public uint EncryptKey { get; private set; } = 0X00; | public uint EncryptKey { get; private set; } = 0X00; | ||||
protected override void InitializeProperties(object[] properties, int startIndex) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
protected override void OnWriteToBuffer(BinaryWriter writer) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,11 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.ProtocolPacket | |||||
{ | |||||
public interface IBuffer | |||||
{ | |||||
byte[] Buffer { get; } | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.Protocol.ProtocolPacket | |||||
{ | |||||
public interface IBuffered | |||||
{ | |||||
byte[] ToBuffer(); | |||||
} | |||||
} |
@@ -7,8 +7,7 @@ namespace JT809.Protocol.ProtocolPacket | |||||
/// <summary> | /// <summary> | ||||
/// 抽象消息体 | /// 抽象消息体 | ||||
/// </summary> | /// </summary> | ||||
public abstract class MessageBody | |||||
public abstract class MessageBody: BufferedEntityBase | |||||
{ | { | ||||
public IEncrypt Encrypt { get; set; } | |||||
} | } | ||||
} | } |
@@ -1,20 +1,50 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.IO; | |||||
using System.Text; | using System.Text; | ||||
using JT809.Protocol.ProtocolPacket.Extensions; | |||||
namespace JT809.Protocol.ProtocolPacket | namespace JT809.Protocol.ProtocolPacket | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// 数据包 | /// 数据包 | ||||
/// </summary> | /// </summary> | ||||
public class Package | |||||
public class Package: BufferedEntityBase | |||||
{ | { | ||||
public const int NotDataLength = 26; | public const int NotDataLength = 26; | ||||
public const int CrcByteLength = 2; | |||||
public const int Crc16ByteLength = 2; | |||||
public const byte BeginFlag = 0X5B; | public const byte BeginFlag = 0X5B; | ||||
public const byte EndFlag = 0X5D; | public const byte EndFlag = 0X5D; | ||||
public Header Header { get; set; } | |||||
public MessageBody MessageBody { get; set; } | |||||
private ushort CRCCheckCode { get; set; } | |||||
public Header Header { get; private set; } | |||||
public MessageBody Body { get; private set; } | |||||
private ushort CRC16 { get; set; } | |||||
public Package(byte[] buffer) : base(buffer) | |||||
{ } | |||||
public Package(Header header, MessageBody body) : base(header, body) | |||||
{ } | |||||
protected override void InitializeProperties(object[] properties, int startIndex) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader) | |||||
{ | |||||
var content00 = Buffer; | |||||
var content01 = this.UnEscape(content00); | |||||
var crc16 = this.CRC16_CCITT(content01, 0, content01.Length - Crc16ByteLength); | |||||
CRC16 = BitConverter.ToUInt16(new[] { content01[content01.Length - 1], content01[content01.Length - 2] }, 0); | |||||
if (CRC16 != crc16) throw new InvalidDataException("CRC16 check invalid."); | |||||
} | |||||
protected override void OnWriteToBuffer(BinaryWriter writer) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
} | } | ||||
} | } |