diff --git a/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj b/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj
index 5a3f1d0..e53e54e 100644
--- a/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj
+++ b/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj
@@ -6,6 +6,14 @@
false
+
+ 7.2
+
+
+
+ 7.2
+
+
diff --git a/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs b/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs
index 750926d..4b2a93c 100644
--- a/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs
+++ b/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs
@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Text;
using Xunit;
using GBNewEnergy.Protocol.Extensions;
+using GBNewEnergy.Protocol.UpStream;
+using GBNewEnergy.Protocol.Enums;
namespace GBNewEnergy.Protocol.Test
{
@@ -15,5 +17,74 @@ namespace GBNewEnergy.Protocol.Test
byte[] body = "12 05 0F 0F 29 15 01 02 01 01 00 00 00 00 33 54 19 B1 23 06 58 01 00 06 9F 00 00 02 01 01 03 47 00 00 4E 20 47 10 D6 27 24 05 01 06 CA 3C 03 01 57 8E C3 06 01 38 0D 5C 01 01 0D 48 01 01 43 01 0B 42 07 00 00 00 00 00 00 00 00 00 08 01 01 19 B1 23 06 00 C0 00 01 C0 0D 48 0D 48 0D 48 0D 48 0D 52 0D 48 0D 48 0D 52 0D 52 0D 48 0D 48 0D 52 0D 48 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 48 0D 52 0D 48 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 48 0D 48 0D 48 0D 48 0D 52 0D 48 0D 52 0D 48 0D 52 0D 48 0D 48 0D 48 0D 5C 0D 52 0D 52 0D 52 0D 5C 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 48 0D 48 0D 52 0D 48 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 48 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 52 0D 48 0D 48 0D 48 0D 48 0D 52 0D 52 0D 48 0D 48 0D 48 0D 52 0D 48 0D 48 0D 48 0D 52 0D 48 0D 52 0D 52 09 01 01 00 48 43 43 43 43 43 43 43 43 43 43 42 43 42 42 42 42 42 43 42 42 42 42 42 42 42 43 42 42 42 43 42 42 42 42 42 42 42 42 42 42 42 42 42 42 43 42 42 43 42 42 42 42 42 42 42 42 43 42 42 43 43 43 42 43 43 43 43 43 43 43 43 43 48".ToHexBytes();
NEPackage nEPackage = new NEPackage(header, body);
}
+
+ [Fact]
+ public void NELoginUpStreamConstructor1_1()
+ {
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F"
+ // "12 06 07 11 04 1B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31"
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F 12 06 07 11 04 1B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 D7"
+ NELoginUpStream nELoginUpStream = new NELoginUpStream("LGHC4V1D3HE202652", "64743066405", 1,1,new string[] { "1"});
+ NEPackage nEPackage = new NEPackage("LGHC4V1D3HE202652", Enums.MsgId.login,Enums.AskId.cmd, nELoginUpStream, EncryptMethod.None);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ string packageHex = nEPackage.Buffer.ToHexString();
+ }
+
+ [Fact]
+ public void NELoginUpStreamConstructor1_2()
+ {
+ byte[] header = "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F".ToHexBytes();
+ byte[] body = "12 06 07 11 04 1B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 D7".ToHexBytes();
+ NEPackage nEPackage = new NEPackage(header, body);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ }
+
+ [Fact]
+ public void NELoginUpStreamConstructor2_1()
+ {
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F"
+ // "12 06 07 12 23 3B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31"
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F 12 06 07 12 23 3B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 D3"
+ NELoginUpStream nELoginUpStream = new NELoginUpStream("LGHC4V1D3HE202652", "64743066405", 1, 1, new string[] { "1" });
+ NEPackage nEPackage = new NEPackage("LGHC4V1D3HE202652", Enums.MsgId.login, Enums.AskId.cmd, nELoginUpStream, EncryptMethod.None);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ string packageHex = nEPackage.Buffer.ToHexString();
+ }
+
+ [Fact]
+ public void NELoginUpStreamConstructor2_2()
+ {
+ byte[] header = "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F".ToHexBytes();
+ byte[] body = "12 06 07 12 23 3B 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 D3".ToHexBytes();
+ NEPackage nEPackage = new NEPackage(header, body);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ }
+
+ [Fact]
+ public void NELoginUpStreamConstructor3_1()
+ {
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F"
+ // "06 07 12 37 02 00 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31"
+ // "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F 06 07 12 37 02 00 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 EC"
+ NELoginUpStream nELoginUpStream = new NELoginUpStream("LGHC4V1D3HE202652", "64743066405", 1, 1, new string[] { "1" });
+ NEPackage nEPackage = new NEPackage("LGHC4V1D3HE202652", Enums.MsgId.login, Enums.AskId.cmd, nELoginUpStream, EncryptMethod.None);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ string packageHex = nEPackage.Buffer.ToHexString();
+ }
+
+ [Fact]
+ public void NELoginUpStreamConstructor3_2()
+ {
+ byte[] header = "23 23 01 FE 4C 47 48 43 34 56 31 44 33 48 45 32 30 32 36 35 32 01 00 1F".ToHexBytes();
+ byte[] body = "06 07 12 37 02 00 00 01 36 34 37 34 33 30 36 36 34 30 35 00 00 00 00 00 00 00 00 00 01 01 31 EC".ToHexBytes();
+ NEPackage nEPackage = new NEPackage(header, body);
+ string headerHex = nEPackage.Header.ToHexString();
+ string bodiesHex = nEPackage.Bodies.Buffer.ToHexString();
+ }
}
}
diff --git a/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs b/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs
index db43a0d..f38071d 100644
--- a/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs
+++ b/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs
@@ -9,5 +9,15 @@ namespace GBNewEnergy.Protocol.Response
protected NELoginDownStream(byte[] buffer) : base(buffer)
{
}
+
+ protected NELoginDownStream(string vin) : base(vin)
+ {
+
+ }
+
+ public override void ToBuffer()
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs b/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs
index 98272fe..bbeca9a 100644
--- a/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs
+++ b/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs
@@ -6,6 +6,7 @@ namespace GBNewEnergy.Protocol.Enums
{
public enum ErrorCode
{
- BeginFlagError = 1001
+ BeginFlagError = 1001,
+ BCCCodeError = 1001
}
}
diff --git a/src/GBNewEnergy.Protocol/Extensions/BinaryExtensions.cs b/src/GBNewEnergy.Protocol/Extensions/BinaryExtensions.cs
deleted file mode 100644
index 4d32bb0..0000000
--- a/src/GBNewEnergy.Protocol/Extensions/BinaryExtensions.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Text;
-
-namespace GBNewEnergy.Protocol.Extensions
-{
- public static class BinaryExtensions
- {
-
- ///
- /// 从高位到低位转成int
- ///
- ///
- ///
- ///
- ///
- public static int ToIntH2L(this byte[] bytes, int offset, int len)
- {
- int result = 0;
- for (int i = offset; i < offset + len; i++)
- {
- result += bytes[i] * (int)Math.Pow(256, len + offset - i - 1);
- }
- return result;
- }
-
- ///
- /// 字符串到字节数组
- ///
- ///
- ///
- public static byte[] ToBytes(this string data, Encoding coding)
- {
- return coding.GetBytes(data);
- }
-
- ///
- /// 字符串到字节数组
- ///
- ///
- public static byte[] ToBytes(this string data)
- {
- return Encoding.ASCII.GetBytes(data);
- }
-
- ///
- /// 整型到字节数组
- ///
- /// int数据
- /// int填入长度
- 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;
- }
-
- ///
- /// 异或
- ///
- ///
- ///
- ///
- ///
- 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;
- }
-
- ///
- /// 字节数组转16进制字符串
- ///
- ///
- /// 默认 " "
- ///
- public static string ToHexString(this byte[] bytes,string separator=" ")
- {
- return string.Join(separator, bytes.Select(s => s.ToString("X2")));
- }
-
- ///
- /// 16进制字符串转16进制数组
- ///
- ///
- ///
- ///
- public static byte[] ToHexBytes(this string hexString, string separator = " ")
- {
- return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray();
- }
- }
-}
diff --git a/src/GBNewEnergy.Protocol/Extensions/NEExtensions.cs b/src/GBNewEnergy.Protocol/Extensions/NEExtensions.cs
new file mode 100644
index 0000000..b9687c4
--- /dev/null
+++ b/src/GBNewEnergy.Protocol/Extensions/NEExtensions.cs
@@ -0,0 +1,134 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace GBNewEnergy.Protocol.Extensions
+{
+ public static class NEExtensions
+ {
+ ///
+ /// 日期限制于2000年
+ ///
+ private const int DateLimitYear = 2000;
+
+ public static DateTime ReadDateTimeLittle(this byte[] read,int offset, int len)
+ {
+ return new DateTime(
+ read[offset] + DateLimitYear,
+ read[offset++],
+ read[offset++],
+ read[offset++],
+ read[offset++],
+ read[offset++]);
+ }
+
+ public static ushort ReadUShortH2LLittle(this byte[] read, int offset, int len)
+ {
+ int result = 0;
+ for (int i = offset; i < offset + len; i++)
+ {
+ result += read[i] * (int)Math.Pow(256, len + offset - i - 1);
+ }
+ return (ushort)result;
+ }
+
+ public static string ReadStringLittle(this byte[] read, int offset, int len,Encoding coding)
+ {
+ return coding.GetString(read, offset, len).Trim('\0');
+ }
+
+ public static string ReadStringLittle(this byte[] read, int offset, int len)
+ {
+ return Encoding.ASCII.GetString(read, offset, len).Trim('\0');
+ }
+
+ public static void WriteLittle(this byte[] write,string str, int offset, Encoding coding)
+ {
+ byte[] strByte = coding.GetBytes(str);
+ Array.Copy(strByte, 0, write, offset, strByte.Length);
+ }
+
+ public static void WriteLittle(this byte[] write, string str, int offset)
+ {
+ byte[] strByte = Encoding.ASCII.GetBytes(str);
+ Array.Copy(strByte, 0, write, offset, strByte.Length);
+ }
+
+ public static void WriteLittle(this byte[] write,int data ,int offset,int len)
+ {
+ int n = 1;
+ for (int i = 0; i < len; i++)
+ {
+ write[offset] = (byte)(data >> 8 * (len - n));
+ n++;
+ offset++;
+ }
+ }
+
+ public static void WriteLittle(this byte[] write, ushort data, int offset, int len)
+ {
+ int n = 1;
+ for (int i = 0; i < len; i++)
+ {
+ write[offset] = (byte)(data >> 8 * (len - n));
+ n++;
+ offset++;
+ }
+ }
+
+ public static void WriteLittle(this byte[] write, byte[] bytes, int offset, int len)
+ {
+ Array.Copy(bytes, 0, write, offset, len);
+ }
+
+ public static void WriteLittle(this byte[] write, DateTime date, int offset,int len)
+ {
+ write[offset] = (byte)(date.Year - DateLimitYear);
+ write[offset++] = (byte)date.Month;
+ write[offset++] = (byte)date.Day;
+ write[offset++] = (byte)date.Hour;
+ write[offset++] = (byte)date.Minute;
+ write[offset++] = (byte)date.Second;
+ }
+
+ ///
+ /// 异或
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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;
+ }
+
+ ///
+ /// 字节数组转16进制字符串
+ ///
+ ///
+ /// 默认 " "
+ ///
+ public static string ToHexString(this byte[] bytes,string separator=" ")
+ {
+ return string.Join(separator, bytes.Select(s => s.ToString("X2")));
+ }
+
+ ///
+ /// 16进制字符串转16进制数组
+ ///
+ ///
+ ///
+ ///
+ public static byte[] ToHexBytes(this string hexString, string separator = " ")
+ {
+ return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray();
+ }
+ }
+}
diff --git a/src/GBNewEnergy.Protocol/IBuffered.cs b/src/GBNewEnergy.Protocol/IBuffered.cs
index 8ea9cd8..02034a0 100644
--- a/src/GBNewEnergy.Protocol/IBuffered.cs
+++ b/src/GBNewEnergy.Protocol/IBuffered.cs
@@ -2,6 +2,6 @@
{
public interface IBuffered
{
- byte[] ToBuffer();
+ void ToBuffer();
}
}
diff --git a/src/GBNewEnergy.Protocol/NEBodies.cs b/src/GBNewEnergy.Protocol/NEBodies.cs
index 08d1018..9a47245 100644
--- a/src/GBNewEnergy.Protocol/NEBodies.cs
+++ b/src/GBNewEnergy.Protocol/NEBodies.cs
@@ -11,7 +11,7 @@ namespace GBNewEnergy.Protocol
/// VIN - 登录流水号,过期时间(每天置1)
/// 车载终端登入一次,登入流水号自动加1,从1开始循环累加,最大值为65531,循环周期为天
///
- private static readonly ConcurrentDictionary LoginNumDict;
+ protected static readonly ConcurrentDictionary LoginNumDict;
static NEBodies()
{
@@ -26,6 +26,7 @@ namespace GBNewEnergy.Protocol
///
/// 数据采集时间
+ /// 采用北京时间
///
public DateTime CurrentDateTime { get; protected set; }
@@ -36,37 +37,11 @@ namespace GBNewEnergy.Protocol
Buffer = buffer;
}
- protected NEBodies(string vin,object[] parameter)
+ protected NEBodies(string vin)
{
- 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();
- }
+ public abstract void ToBuffer();
}
}
diff --git a/src/GBNewEnergy.Protocol/NEBodiesFactory.cs b/src/GBNewEnergy.Protocol/NEBodiesFactory.cs
new file mode 100644
index 0000000..96434b0
--- /dev/null
+++ b/src/GBNewEnergy.Protocol/NEBodiesFactory.cs
@@ -0,0 +1,28 @@
+using GBNewEnergy.Protocol.Enums;
+using GBNewEnergy.Protocol.UpStream;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace GBNewEnergy.Protocol
+{
+ public class NEBodiesFactory
+ {
+ ///
+ /// 通过命令id获取数据体
+ ///
+ ///
+ ///
+ ///
+ public static NEBodies GetNEBodiesByMsgId(MsgId msgId,byte[] buf)
+ {
+ switch (msgId)
+ {
+ case MsgId.login:
+ return new NELoginUpStream(buf);
+ default:
+ return null;
+ }
+ }
+ }
+}
diff --git a/src/GBNewEnergy.Protocol/NEPackage.cs b/src/GBNewEnergy.Protocol/NEPackage.cs
index 86df19a..f9f4b53 100644
--- a/src/GBNewEnergy.Protocol/NEPackage.cs
+++ b/src/GBNewEnergy.Protocol/NEPackage.cs
@@ -2,8 +2,6 @@
using GBNewEnergy.Protocol.Exceptions;
using GBNewEnergy.Protocol.Extensions;
using System;
-using System.Collections.Generic;
-using System.Text;
namespace GBNewEnergy.Protocol
@@ -15,15 +13,53 @@ namespace GBNewEnergy.Protocol
{
public NEPackage(byte[] header,byte[] body)
{
+ // 判断头部异常
if (header[0] != BeginFlag && header[1] == BeginFlag) throw new NEException(ErrorCode.BeginFlagError, $"{header[0]},{header[1]}");
+ // 组包
+ byte[] packageBuffer = new byte[header.Length + body.Length];
+ Array.Copy(header, 0, packageBuffer, 0, header.Length);
+ Array.Copy(body, 0, packageBuffer, header.Length, body.Length);
+ // 获取数据单元长度
+ DataUnitLength = header.ReadUShortH2LLittle(22, 2);
+ // 进行BCC校验码
+ // 校验位=报文长度 - 最后一位(校验位) - 偏移量(2)
+ int checkBit = packageBuffer.Length - 1 - 2;
+ byte bCCCode = packageBuffer.ToXor(2, checkBit);
+ byte bCCCode2 = body[body.Length - 1];
+ if (bCCCode != bCCCode2) throw new NEException(ErrorCode.BCCCodeError, $"request:{bCCCode2}!=calculate:{bCCCode}");
MsgId = (MsgId)header[2];
AskId = (AskId)header[3];
- VIN = Encoding.ASCII.GetString(header, 4, 17).Trim('\0');
+ VIN = header.ReadStringLittle(4, 17);
EncryptMethod = (EncryptMethod)header[21];
- DataUnitLength = header.ToIntH2L(22, 2);
+ // 通过命令id获取数据体
+ Bodies = NEBodiesFactory.GetNEBodiesByMsgId(MsgId, body);
+ Buffer = packageBuffer;
Header = header;
}
+ public NEPackage(byte[] buf)
+ {
+ if (buf[0] != BeginFlag && buf[1] == BeginFlag) throw new NEException(ErrorCode.BeginFlagError, $"{buf[0]},{buf[1]}");
+ MsgId = (MsgId)buf[2];
+ AskId = (AskId)buf[3];
+ VIN = buf.ReadStringLittle(4, 17);
+ EncryptMethod = (EncryptMethod)buf[21];
+ DataUnitLength = buf.ReadUShortH2LLittle(22, 2);
+ // 进行BCC校验码
+ // 校验位 = 报文长度 - 最后一位(校验位) - 偏移量(2)
+ int checkBit = buf.Length - CheckBit - 2;
+ byte bCCCode = buf.ToXor(2, checkBit);
+ byte bCCCode2 = buf[buf.Length - CheckBit];
+ if (bCCCode != bCCCode2)
+ {
+ throw new NEException(ErrorCode.BCCCodeError, $"request:{bCCCode2}!=calculate:{bCCCode}");
+ }
+ Bodies = NEBodiesFactory.GetNEBodiesByMsgId(MsgId, buf);
+ Buffer = new byte[buf.Length + Bodies.Buffer.Length];
+ Array.Copy(buf, 0, Buffer, 0, buf.Length);
+ Array.Copy(Bodies.Buffer, 0, Buffer, buf.Length, Bodies.Buffer.Length);
+ }
+
public NEPackage(string vin, MsgId msgId, AskId askId, NEBodies bodies,EncryptMethod encryptMethod)
{
MsgId = msgId;
@@ -43,6 +79,10 @@ namespace GBNewEnergy.Protocol
///
public const byte BeginFlag = 0x23;
///
+ /// 校验位1字节
+ ///
+ private const int CheckBit = 1;
+ ///
/// 命令标识
///
public MsgId MsgId { get; private set; }
@@ -79,27 +119,23 @@ namespace GBNewEnergy.Protocol
public byte[] Buffer { get; private set; }
- public override string ToString()
- {
- return this.Header.ToHexString()+" " +this.Buffer.ToHexString();
- }
-
private void ToBuffer()
{
// 固定单元长度
DataUnitLength = Bodies.Buffer.Length;
- Buffer = new byte[HeaderFixedByteLength + 1 + DataUnitLength];
+ Buffer = new byte[HeaderFixedByteLength + DataUnitLength + CheckBit];
Buffer[0] = BeginFlag;
Buffer[1] = BeginFlag;
Buffer[2] = (byte)MsgId;
Buffer[3] = (byte)AskId;
- Array.Copy(VIN.ToBytes(), 0, Buffer, 4, 20);
+ Buffer.WriteLittle(VIN, 4);
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.WriteLittle(DataUnitLength, 22, 2);
+ Buffer.WriteLittle(Bodies.Buffer, 24, DataUnitLength);
+ BCCCode = Buffer.ToXor(2, (HeaderFixedByteLength + DataUnitLength - 1));
Buffer[HeaderFixedByteLength + DataUnitLength] = BCCCode;
- Array.Copy(Buffer,0, Header, 0, 22);
+ Header = new byte[HeaderFixedByteLength];
+ Array.Copy(Buffer, 0, Header, 0, HeaderFixedByteLength);
}
}
}
diff --git a/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs b/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs
index 775fcd5..987fb82 100644
--- a/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs
+++ b/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs
@@ -1,14 +1,57 @@
-using System;
+using GBNewEnergy.Protocol.Extensions;
+using System;
using System.Collections.Generic;
using System.Text;
-namespace GBNewEnergy.Protocol.Request
+namespace GBNewEnergy.Protocol.UpStream
{
- public class NELoginUpStream: NEBodies
+ public class NELoginUpStream : NEBodies
{
- protected NELoginUpStream(byte[] buffer) : base(buffer)
+ public NELoginUpStream(byte[] buffer) : base(buffer)
{
+ CurrentDateTime = buffer.ReadDateTimeLittle(0, 6);
+ LoginNum = buffer.ReadUShortH2LLittle(6, 2);
+ SIM = buffer.ReadStringLittle(8, 20);
+ BatteryCount = buffer[28];
+ BatteryLength = buffer[29];
+ List batteryNos = new List();
+ for (int i = 0; i < BatteryCount; i++)
+ {
+ batteryNos.Add(buffer.ReadStringLittle(i * BatteryLength + 30, BatteryLength));
+ }
+ BatteryNos = batteryNos;
+ }
+ public NELoginUpStream(string vin, string sim, byte batteryCount, byte batteryLength, IEnumerable batteryNos) : base(vin)
+ {
+ 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));
+ }
+ SIM = sim;
+ BatteryCount = batteryCount;
+ BatteryLength = batteryLength;
+ BatteryNos = batteryNos;
+ ToBuffer();
}
///
@@ -17,15 +60,34 @@ namespace GBNewEnergy.Protocol.Request
public string SIM { get; set; }
///
/// 电池总成数
+ /// 可充电储能子系统数
///
public byte BatteryCount { get; set; }
///
/// 电池编码长度
+ /// 可充电储能系统编码长度
///
public byte BatteryLength { get; set; }
///
/// 电池编码
+ /// 可充电储能系统编码
///
public IEnumerable BatteryNos { get; set; }
+
+ public override void ToBuffer()
+ {
+ // 根据协议说明书
+ Buffer = new byte[6 + 2 + 20 + 1 + 1 + (BatteryCount * BatteryLength)];
+ Buffer.WriteLittle(CurrentDateTime, 0, 6);
+ Buffer.WriteLittle(LoginNum, 6, 2);
+ Buffer.WriteLittle(SIM, 8);
+ Buffer[28] = BatteryCount;
+ Buffer[29] = BatteryLength;
+ if ((BatteryCount * BatteryLength) != 0)
+ {
+ string str = string.Join("", BatteryNos);
+ Buffer.WriteLittle(str, 30);
+ }
+ }
}
}
diff --git a/src/GBNewEnergy.Protocol/UpStream/NELogoutUpStream.cs b/src/GBNewEnergy.Protocol/UpStream/NELogoutUpStream.cs
new file mode 100644
index 0000000..d9ffe5f
--- /dev/null
+++ b/src/GBNewEnergy.Protocol/UpStream/NELogoutUpStream.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace GBNewEnergy.Protocol.UpStream
+{
+ public class NELogoutUpStream : NEBodies
+ {
+ protected NELogoutUpStream(byte[] buffer) : base(buffer)
+ {
+ }
+
+ protected NELogoutUpStream(string vin) : base(vin)
+ {
+ (ushort LoginNum, DateTime ExpirationTime) temp;
+ if (LoginNumDict.TryGetValue(vin, out temp))
+ {
+ LoginNum = temp.LoginNum;
+ }
+ }
+
+ public override void ToBuffer()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}