diff --git a/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj b/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj new file mode 100644 index 0000000..5a3f1d0 --- /dev/null +++ b/src/GBNewEnergy.Protocol.Test/GBNewEnergy.Protocol.Test.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + diff --git a/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs b/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs new file mode 100644 index 0000000..750926d --- /dev/null +++ b/src/GBNewEnergy.Protocol.Test/NEPackageTest.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using GBNewEnergy.Protocol.Extensions; + +namespace GBNewEnergy.Protocol.Test +{ + public class NEPackageTest + { + [Fact] + public void NEPackageConstructor() + { + byte[] header = "23 23 02 FE 54 45 53 54 32 30 31 38 30 34 31 36 30 30 30 30 31 01 02 25".ToHexBytes(); + 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); + } + } +} diff --git a/src/GBNewEnergy.Protocol/BufferedEntityBase.cs b/src/GBNewEnergy.Protocol/BufferedEntityBase.cs index 92e4e27..5652afe 100644 --- a/src/GBNewEnergy.Protocol/BufferedEntityBase.cs +++ b/src/GBNewEnergy.Protocol/BufferedEntityBase.cs @@ -3,15 +3,10 @@ using System.IO; namespace GBNewEnergy.Protocol { - public abstract class BufferedEntityBase : IBuffered, IBuffer + public abstract class BufferedEntityBase : IBuffer { public byte[] Buffer { get; protected set; } - public virtual byte[] ToBuffer() - { - return Buffer; - } - protected BufferedEntityBase(byte[] buffer) { Buffer = buffer; diff --git a/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs b/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs new file mode 100644 index 0000000..9d1f35f --- /dev/null +++ b/src/GBNewEnergy.Protocol/DownStream/NELoginDownStream.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.Response +{ + public class NELoginDownStream : NEDownStreamBase + { + + } +} diff --git a/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs b/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs new file mode 100644 index 0000000..98272fe --- /dev/null +++ b/src/GBNewEnergy.Protocol/Enums/ErrorCode.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.Enums +{ + public enum ErrorCode + { + BeginFlagError = 1001 + } +} diff --git a/src/GBNewEnergy.Protocol/Enums/MsgId.cs b/src/GBNewEnergy.Protocol/Enums/MsgId.cs index 17e7ce4..db14c56 100644 --- a/src/GBNewEnergy.Protocol/Enums/MsgId.cs +++ b/src/GBNewEnergy.Protocol/Enums/MsgId.cs @@ -4,6 +4,9 @@ using System.Text; namespace GBNewEnergy.Protocol.Enums { + /// + /// 命令单元 + /// public enum MsgId:byte { /// diff --git a/src/GBNewEnergy.Protocol/Exceptions/NEException.cs b/src/GBNewEnergy.Protocol/Exceptions/NEException.cs new file mode 100644 index 0000000..25c19b3 --- /dev/null +++ b/src/GBNewEnergy.Protocol/Exceptions/NEException.cs @@ -0,0 +1,23 @@ +using GBNewEnergy.Protocol.Enums; +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.Exceptions +{ + public class NEException:Exception + { + public NEException(ErrorCode errorCode) : base(errorCode.ToString()) + { + this.ErrorCode = errorCode; + } + + public NEException(ErrorCode errorCode, string message) : base(message) + { + this.ErrorCode = errorCode; + } + + + public ErrorCode ErrorCode { get; } + } +} diff --git a/src/GBNewEnergy.Protocol/GBNewEnergy.Protocol.csproj b/src/GBNewEnergy.Protocol/GBNewEnergy.Protocol.csproj index 9f5c4f4..349e074 100644 --- a/src/GBNewEnergy.Protocol/GBNewEnergy.Protocol.csproj +++ b/src/GBNewEnergy.Protocol/GBNewEnergy.Protocol.csproj @@ -4,4 +4,8 @@ netstandard2.0 + + + + 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/NEDownStreamBase.cs b/src/GBNewEnergy.Protocol/NEDownStreamBase.cs new file mode 100644 index 0000000..b49640c --- /dev/null +++ b/src/GBNewEnergy.Protocol/NEDownStreamBase.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol +{ + public abstract class NEDownStreamBase + { + + } +} diff --git a/src/GBNewEnergy.Protocol/NEHeader.cs b/src/GBNewEnergy.Protocol/NEHeader.cs index ba30b64..e5cfcd4 100644 --- a/src/GBNewEnergy.Protocol/NEHeader.cs +++ b/src/GBNewEnergy.Protocol/NEHeader.cs @@ -1,4 +1,5 @@ using GBNewEnergy.Protocol.Enums; +using GBNewEnergy.Protocol.Exceptions; using GBNewEnergy.Protocol.Extensions; using System; using System.Text; @@ -12,12 +13,7 @@ namespace GBNewEnergy.Protocol { public NEHeader(byte[] buffer):base(buffer) { - if (buffer[0] != BeginFlag && buffer[1] == BeginFlag) throw new Exception("error"); - MsgId =(MsgId)buffer[2]; - AskId =(AskId)buffer[3]; - VIN = Encoding.ASCII.GetString(buffer, 4, 17).Trim('\0'); - EncryptMethod =(EncryptMethod)buffer[21]; - DataUnitLength = buffer.ToIntH2L(22, 2); + } /// /// 起始符 @@ -40,9 +36,5 @@ namespace GBNewEnergy.Protocol /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 /// public EncryptMethod EncryptMethod { get; private set; } - /// - /// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 - /// - public int DataUnitLength { get; private set; } } } diff --git a/src/GBNewEnergy.Protocol/NEPackage.cs b/src/GBNewEnergy.Protocol/NEPackage.cs index 5542482..02295fe 100644 --- a/src/GBNewEnergy.Protocol/NEPackage.cs +++ b/src/GBNewEnergy.Protocol/NEPackage.cs @@ -1,8 +1,11 @@ using GBNewEnergy.Protocol.Enums; +using GBNewEnergy.Protocol.Exceptions; +using GBNewEnergy.Protocol.Extensions; using System; using System.Collections.Generic; using System.Text; + namespace GBNewEnergy.Protocol { /// @@ -12,29 +15,57 @@ namespace GBNewEnergy.Protocol { public NEPackage(byte[] header,byte[] body):base(body) { - this.NEHeader = new NEHeader(header); - Array.Copy(header, 0, OriginalPackage, 0, header.Length); - Array.Copy(body, 0, OriginalPackage, header.Length, body.Length); + if (header[0] != BeginFlag && header[1] == BeginFlag) throw new NEException(ErrorCode.BeginFlagError, $"{header[0]},{header[1]}"); + MsgId = (MsgId)header[2]; + AskId = (AskId)header[3]; + VIN = Encoding.ASCII.GetString(header, 4, 17).Trim('\0'); + EncryptMethod = (EncryptMethod)header[21]; + DataUnitLength = header.ToIntH2L(22, 2); + Header = header; } /// /// 固定为24个字节长度 /// public const int HeaderFixedByteLength = 24; /// - /// 头部 + /// 起始符 + /// + public const byte BeginFlag = 0x23; + /// + /// 命令标识 + /// + public MsgId MsgId { get; private set; } + /// + /// 应答标志 + /// + public AskId AskId { get; private set; } + /// + /// 车辆识别码 /// - public NEHeader NEHeader { get; private set; } + public string VIN { get; private set; } /// - /// 数据单元 + /// 数据加密方式 + /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 /// - public byte[] DataUnit { get; private set; } + public EncryptMethod EncryptMethod { get; private set; } /// - /// BCC 校验码 + /// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 + /// + public int DataUnitLength { get; private set; } + /// + /// BCC校验码 /// public byte BCCCode { get; private set; } /// - /// 原始包(包头+包体) + /// 头数据 /// - public byte[] OriginalPackage { get; private set; } + public byte[] Header { get; private set; } + + public NEUpStreamBase NEUpStreamBase { get;protected set; } + + public override string ToString() + { + return Header.ToHexString()+" "+this.Buffer.ToHexString(); + } } } diff --git a/src/GBNewEnergy.Protocol/NEUpStreamBase.cs b/src/GBNewEnergy.Protocol/NEUpStreamBase.cs new file mode 100644 index 0000000..26b5b1e --- /dev/null +++ b/src/GBNewEnergy.Protocol/NEUpStreamBase.cs @@ -0,0 +1,14 @@ +using GBNewEnergy.Protocol.Enums; +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol +{ + public abstract class NEUpStreamBase: IBuffered, IBuffer + { + public DateTime Utc{ get; set; } + public byte[] Buffer { get;protected set; } + public abstract void ToBuffer(); + } +} diff --git a/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs b/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs new file mode 100644 index 0000000..cb832be --- /dev/null +++ b/src/GBNewEnergy.Protocol/UpStream/NELoginUpStream.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBNewEnergy.Protocol.Request +{ + public class NELoginUpStream: NEUpStreamBase + { + /// + /// 登入流水号 + /// + public int LoginNum { get; set; } + /// + /// SIM 卡号 + /// + public string SIM { get; set; } + /// + /// 电池总成数 + /// + public byte BatteryCount { get; set; } + /// + /// 电池编码长度 + /// + public byte BatteryLength { get; set; } + /// + /// 电池编码 + /// + public IEnumerable BatteryNos { get; set; } + + public override void ToBuffer() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/GBNewEnergy.sln b/src/GBNewEnergy.sln index b4b7186..8ded8a7 100644 --- a/src/GBNewEnergy.sln +++ b/src/GBNewEnergy.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27703.2018 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GBNewEnergy.Protocol", "GBNewEnergy.Protocol\GBNewEnergy.Protocol.csproj", "{1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GBNewEnergy.Protocol", "GBNewEnergy.Protocol\GBNewEnergy.Protocol.csproj", "{1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GBNewEnergy.Protocol.Test", "GBNewEnergy.Protocol.Test\GBNewEnergy.Protocol.Test.csproj", "{AAA669F5-E689-40CA-97EF-B5BA672B11DD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU {1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU {1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}.Release|Any CPU.Build.0 = Release|Any CPU + {AAA669F5-E689-40CA-97EF-B5BA672B11DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAA669F5-E689-40CA-97EF-B5BA672B11DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAA669F5-E689-40CA-97EF-B5BA672B11DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAA669F5-E689-40CA-97EF-B5BA672B11DD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE