@@ -3,7 +3,7 @@ using System.IO; | |||
namespace GBNewEnergy.Protocol | |||
{ | |||
public abstract class BufferedEntityBase : IBuffer | |||
public abstract class BufferedEntityBase : IBuffer, IBuffered | |||
{ | |||
public byte[] Buffer { get; protected set; } | |||
@@ -11,5 +11,15 @@ namespace GBNewEnergy.Protocol | |||
{ | |||
Buffer = buffer; | |||
} | |||
protected BufferedEntityBase(params object[] parameter) | |||
{ | |||
} | |||
public byte[] ToBuffer() | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -4,8 +4,10 @@ using System.Text; | |||
namespace GBNewEnergy.Protocol.Response | |||
{ | |||
public class NELoginDownStream : NEDownStreamBase | |||
public class NELoginDownStream : NEBodies | |||
{ | |||
protected NELoginDownStream(byte[] buffer) : base(buffer) | |||
{ | |||
} | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Text; | |||
namespace GBNewEnergy.Protocol.Extensions | |||
{ | |||
@@ -24,6 +25,59 @@ namespace GBNewEnergy.Protocol.Extensions | |||
return result; | |||
} | |||
/// <summary> | |||
/// 字符串到字节数组 | |||
/// </summary> | |||
/// <param name="data"></param> | |||
/// <param name="coding"></param> | |||
public static byte[] ToBytes(this string data, Encoding coding) | |||
{ | |||
return coding.GetBytes(data); | |||
} | |||
/// <summary> | |||
/// 字符串到字节数组 | |||
/// </summary> | |||
/// <param name="data"></param> | |||
public static byte[] ToBytes(this string data) | |||
{ | |||
return Encoding.ASCII.GetBytes(data); | |||
} | |||
/// <summary> | |||
/// 整型到字节数组 | |||
/// </summary> | |||
/// <param name="data">int数据</param> | |||
/// <param name="len">int填入长度</param> | |||
public static byte[] ToBytes(this int data, int len) | |||
{ | |||
byte[] bytes = new byte[len]; | |||
int n = 1; | |||
for (int i = 0; i < len; i++) | |||
{ | |||
bytes[i] = (byte)(data >> 8 * (len - n)); | |||
n++; | |||
} | |||
return bytes; | |||
} | |||
/// <summary> | |||
/// 异或 | |||
/// </summary> | |||
/// <param name="buf"></param> | |||
/// <param name="offset"></param> | |||
/// <param name="len"></param> | |||
/// <returns></returns> | |||
public static byte ToXor(this byte[] buf, int offset, int len) | |||
{ | |||
byte result = buf[offset]; | |||
for (int i = offset + 1; i < offset + len; i++) | |||
{ | |||
result = (byte)(result ^ buf[i]); | |||
} | |||
return result; | |||
} | |||
/// <summary> | |||
/// 字节数组转16进制字符串 | |||
/// </summary> | |||
@@ -5,7 +5,10 @@ | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Compile Remove="BufferedEntityBase.cs" /> | |||
<Compile Remove="NEDownStreamBase.cs" /> | |||
<Compile Remove="NEHeader.cs" /> | |||
<Compile Remove="NEUpStreamBase.cs" /> | |||
</ItemGroup> | |||
</Project> |
@@ -2,6 +2,6 @@ | |||
{ | |||
public interface IBuffered | |||
{ | |||
void ToBuffer(); | |||
byte[] ToBuffer(); | |||
} | |||
} |
@@ -0,0 +1,72 @@ | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace GBNewEnergy.Protocol | |||
{ | |||
public abstract class NEBodies : IBuffer, IBuffered | |||
{ | |||
/// <summary> | |||
/// VIN - 登录流水号,过期时间(每天置1) | |||
/// 车载终端登入一次,登入流水号自动加1,从1开始循环累加,最大值为65531,循环周期为天 | |||
/// </summary> | |||
private static readonly ConcurrentDictionary<string, (ushort LoginNum, DateTime ExpirationTime)> LoginNumDict; | |||
static NEBodies() | |||
{ | |||
LoginNumDict = new ConcurrentDictionary<string, (ushort LoginNum, DateTime ExpirationTime)>(); | |||
} | |||
/// <summary> | |||
/// 登入流水号 | |||
/// 作用:看数据是否是连续请求 | |||
/// </summary> | |||
public ushort LoginNum { get; protected set; } | |||
/// <summary> | |||
/// 数据采集时间 | |||
/// </summary> | |||
public DateTime CurrentDateTime { get; protected set; } | |||
public byte[] Buffer { get; protected set; } | |||
protected NEBodies(byte[] buffer) | |||
{ | |||
Buffer = buffer; | |||
} | |||
protected NEBodies(string vin,object[] parameter) | |||
{ | |||
if (LoginNumDict.ContainsKey(vin)) | |||
{ | |||
(ushort LoginNum, DateTime ExpirationTime) temp; | |||
if(LoginNumDict.TryGetValue(vin,out temp)) | |||
{ | |||
// 不等于当天 | |||
if(temp.ExpirationTime != DateTime.Now.Date) | |||
{ | |||
LoginNum = 1; | |||
LoginNumDict.TryUpdate(vin, (LoginNum, DateTime.Now.Date), temp); | |||
} | |||
else | |||
{// 自增1 更新字典 | |||
LoginNum = temp.LoginNum++; | |||
LoginNumDict.TryUpdate(vin, (LoginNum, DateTime.Now.Date), temp); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
LoginNum = 1; | |||
LoginNumDict.TryAdd(vin,(LoginNum, DateTime.Now.Date)); | |||
} | |||
CurrentDateTime = DateTime.Now; | |||
} | |||
public byte[] ToBuffer() | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -11,9 +11,9 @@ namespace GBNewEnergy.Protocol | |||
/// <summary> | |||
/// 新能源包 | |||
/// </summary> | |||
public class NEPackage: BufferedEntityBase | |||
public class NEPackage:IBuffer | |||
{ | |||
public NEPackage(byte[] header,byte[] body):base(body) | |||
public NEPackage(byte[] header,byte[] body) | |||
{ | |||
if (header[0] != BeginFlag && header[1] == BeginFlag) throw new NEException(ErrorCode.BeginFlagError, $"{header[0]},{header[1]}"); | |||
MsgId = (MsgId)header[2]; | |||
@@ -23,6 +23,17 @@ namespace GBNewEnergy.Protocol | |||
DataUnitLength = header.ToIntH2L(22, 2); | |||
Header = header; | |||
} | |||
public NEPackage(string vin, MsgId msgId, AskId askId, NEBodies bodies,EncryptMethod encryptMethod) | |||
{ | |||
MsgId = msgId; | |||
AskId = askId; | |||
VIN = vin; | |||
EncryptMethod = encryptMethod; | |||
Bodies = bodies; | |||
ToBuffer(); | |||
} | |||
/// <summary> | |||
/// 固定为24个字节长度 | |||
/// </summary> | |||
@@ -53,19 +64,42 @@ namespace GBNewEnergy.Protocol | |||
/// </summary> | |||
public int DataUnitLength { get; private set; } | |||
/// <summary> | |||
/// BCC校验码 | |||
/// 采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止, | |||
/// 校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密 | |||
/// </summary> | |||
public byte BCCCode { get; private set; } | |||
/// <summary> | |||
/// 头数据 | |||
/// </summary> | |||
public byte[] Header { get; private set; } | |||
/// <summary> | |||
/// 数据体 | |||
/// </summary> | |||
public NEBodies Bodies { get;protected set; } | |||
public NEUpStreamBase NEUpStreamBase { get;protected set; } | |||
public byte[] Buffer { get; private set; } | |||
public override string ToString() | |||
{ | |||
return Header.ToHexString()+" "+this.Buffer.ToHexString(); | |||
return this.Header.ToHexString()+" " +this.Buffer.ToHexString(); | |||
} | |||
private void ToBuffer() | |||
{ | |||
// 固定单元长度 | |||
DataUnitLength = Bodies.Buffer.Length; | |||
Buffer = new byte[HeaderFixedByteLength + 1 + DataUnitLength]; | |||
Buffer[0] = BeginFlag; | |||
Buffer[1] = BeginFlag; | |||
Buffer[2] = (byte)MsgId; | |||
Buffer[3] = (byte)AskId; | |||
Array.Copy(VIN.ToBytes(), 0, Buffer, 4, 20); | |||
Buffer[21] = (byte)EncryptMethod; | |||
Array.Copy(DataUnitLength.ToBytes(2), 0, Buffer, 22, 23); | |||
Array.Copy(Bodies.Buffer, 0, Buffer, 24, DataUnitLength); | |||
BCCCode = Buffer.ToXor(2, 23 + DataUnitLength); | |||
Buffer[HeaderFixedByteLength + DataUnitLength] = BCCCode; | |||
Array.Copy(Buffer,0, Header, 0, 22); | |||
} | |||
} | |||
} |
@@ -5,7 +5,7 @@ using System.Text; | |||
namespace GBNewEnergy.Protocol | |||
{ | |||
public abstract class NEUpStreamBase: IBuffered, IBuffer | |||
public abstract class NEUpStreamBase | |||
{ | |||
public DateTime Utc{ get; set; } | |||
public byte[] Buffer { get;protected set; } | |||
@@ -4,12 +4,13 @@ using System.Text; | |||
namespace GBNewEnergy.Protocol.Request | |||
{ | |||
public class NELoginUpStream: NEUpStreamBase | |||
public class NELoginUpStream: NEBodies | |||
{ | |||
/// <summary> | |||
/// 登入流水号 | |||
/// </summary> | |||
public int LoginNum { get; set; } | |||
protected NELoginUpStream(byte[] buffer) : base(buffer) | |||
{ | |||
} | |||
/// <summary> | |||
/// SIM 卡号 | |||
/// </summary> | |||
@@ -26,10 +27,5 @@ namespace GBNewEnergy.Protocol.Request | |||
/// 电池编码 | |||
/// </summary> | |||
public IEnumerable<string> BatteryNos { get; set; } | |||
public override void ToBuffer() | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |