@@ -0,0 +1,20 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||||
<IsPackable>false</IsPackable> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||||
<PackageReference Include="xunit" Version="2.3.1" /> | |||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\GBNewEnergy.Protocol\GBNewEnergy.Protocol.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -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); | |||||
} | |||||
} | |||||
} |
@@ -3,15 +3,10 @@ using System.IO; | |||||
namespace GBNewEnergy.Protocol | namespace GBNewEnergy.Protocol | ||||
{ | { | ||||
public abstract class BufferedEntityBase : IBuffered, IBuffer | |||||
public abstract class BufferedEntityBase : IBuffer | |||||
{ | { | ||||
public byte[] Buffer { get; protected set; } | public byte[] Buffer { get; protected set; } | ||||
public virtual byte[] ToBuffer() | |||||
{ | |||||
return Buffer; | |||||
} | |||||
protected BufferedEntityBase(byte[] buffer) | protected BufferedEntityBase(byte[] buffer) | ||||
{ | { | ||||
Buffer = buffer; | Buffer = buffer; | ||||
@@ -0,0 +1,11 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Response | |||||
{ | |||||
public class NELoginDownStream : NEDownStreamBase | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Enums | |||||
{ | |||||
public enum ErrorCode | |||||
{ | |||||
BeginFlagError = 1001 | |||||
} | |||||
} |
@@ -4,6 +4,9 @@ using System.Text; | |||||
namespace GBNewEnergy.Protocol.Enums | namespace GBNewEnergy.Protocol.Enums | ||||
{ | { | ||||
/// <summary> | |||||
/// 命令单元 | |||||
/// </summary> | |||||
public enum MsgId:byte | public enum MsgId:byte | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
@@ -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; } | |||||
} | |||||
} |
@@ -4,4 +4,8 @@ | |||||
<TargetFramework>netstandard2.0</TargetFramework> | <TargetFramework>netstandard2.0</TargetFramework> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<Compile Remove="NEHeader.cs" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -2,6 +2,6 @@ | |||||
{ | { | ||||
public interface IBuffered | public interface IBuffered | ||||
{ | { | ||||
byte[] ToBuffer(); | |||||
void ToBuffer(); | |||||
} | } | ||||
} | } |
@@ -0,0 +1,11 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
public abstract class NEDownStreamBase | |||||
{ | |||||
} | |||||
} |
@@ -1,4 +1,5 @@ | |||||
using GBNewEnergy.Protocol.Enums; | using GBNewEnergy.Protocol.Enums; | ||||
using GBNewEnergy.Protocol.Exceptions; | |||||
using GBNewEnergy.Protocol.Extensions; | using GBNewEnergy.Protocol.Extensions; | ||||
using System; | using System; | ||||
using System.Text; | using System.Text; | ||||
@@ -12,12 +13,7 @@ namespace GBNewEnergy.Protocol | |||||
{ | { | ||||
public NEHeader(byte[] buffer):base(buffer) | 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); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// 起始符 | /// 起始符 | ||||
@@ -40,9 +36,5 @@ namespace GBNewEnergy.Protocol | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | ||||
/// </summary> | /// </summary> | ||||
public EncryptMethod EncryptMethod { get; private set; } | public EncryptMethod EncryptMethod { get; private set; } | ||||
/// <summary> | |||||
/// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | |||||
/// </summary> | |||||
public int DataUnitLength { get; private set; } | |||||
} | } | ||||
} | } |
@@ -1,8 +1,11 @@ | |||||
using GBNewEnergy.Protocol.Enums; | using GBNewEnergy.Protocol.Enums; | ||||
using GBNewEnergy.Protocol.Exceptions; | |||||
using GBNewEnergy.Protocol.Extensions; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
namespace GBNewEnergy.Protocol | namespace GBNewEnergy.Protocol | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
@@ -12,29 +15,57 @@ namespace GBNewEnergy.Protocol | |||||
{ | { | ||||
public NEPackage(byte[] header,byte[] body):base(body) | 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; | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// 固定为24个字节长度 | /// 固定为24个字节长度 | ||||
/// </summary> | /// </summary> | ||||
public const int HeaderFixedByteLength = 24; | public const int HeaderFixedByteLength = 24; | ||||
/// <summary> | /// <summary> | ||||
/// 头部 | |||||
/// 起始符 | |||||
/// </summary> | |||||
public const byte BeginFlag = 0x23; | |||||
/// <summary> | |||||
/// 命令标识 | |||||
/// </summary> | |||||
public MsgId MsgId { get; private set; } | |||||
/// <summary> | |||||
/// 应答标志 | |||||
/// </summary> | |||||
public AskId AskId { get; private set; } | |||||
/// <summary> | |||||
/// 车辆识别码 | |||||
/// </summary> | /// </summary> | ||||
public NEHeader NEHeader { get; private set; } | |||||
public string VIN { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// 数据单元 | |||||
/// 数据加密方式 | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
/// </summary> | /// </summary> | ||||
public byte[] DataUnit { get; private set; } | |||||
public EncryptMethod EncryptMethod { get; private set; } | |||||
/// <summary> | /// <summary> | ||||
/// BCC 校验码 | |||||
/// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | |||||
/// </summary> | |||||
public int DataUnitLength { get; private set; } | |||||
/// <summary> | |||||
/// BCC校验码 | |||||
/// </summary> | /// </summary> | ||||
public byte BCCCode { get; private set; } | public byte BCCCode { get; private set; } | ||||
/// <summary> | /// <summary> | ||||
/// 原始包(包头+包体) | |||||
/// 头数据 | |||||
/// </summary> | /// </summary> | ||||
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(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -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(); | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Request | |||||
{ | |||||
public class NELoginUpStream: NEUpStreamBase | |||||
{ | |||||
/// <summary> | |||||
/// 登入流水号 | |||||
/// </summary> | |||||
public int LoginNum { get; set; } | |||||
/// <summary> | |||||
/// SIM 卡号 | |||||
/// </summary> | |||||
public string SIM { get; set; } | |||||
/// <summary> | |||||
/// 电池总成数 | |||||
/// </summary> | |||||
public byte BatteryCount { get; set; } | |||||
/// <summary> | |||||
/// 电池编码长度 | |||||
/// </summary> | |||||
public byte BatteryLength { get; set; } | |||||
/// <summary> | |||||
/// 电池编码 | |||||
/// </summary> | |||||
public IEnumerable<string> BatteryNos { get; set; } | |||||
public override void ToBuffer() | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
} | |||||
} |
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio 15 | # Visual Studio 15 | ||||
VisualStudioVersion = 15.0.27703.2018 | VisualStudioVersion = 15.0.27703.2018 | ||||
MinimumVisualStudioVersion = 10.0.40219.1 | 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 | EndProject | ||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | 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}.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.ActiveCfg = Release|Any CPU | ||||
{1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}.Release|Any CPU.Build.0 = 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 | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||