@@ -0,0 +1,288 @@ | |||||
## Ignore Visual Studio temporary files, build results, and | |||||
## files generated by popular Visual Studio add-ons. | |||||
## | |||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore | |||||
# User-specific files | |||||
*.suo | |||||
*.user | |||||
*.userosscache | |||||
*.sln.docstates | |||||
# User-specific files (MonoDevelop/Xamarin Studio) | |||||
*.userprefs | |||||
# Build results | |||||
[Dd]ebug/ | |||||
[Dd]ebugPublic/ | |||||
[Rr]elease/ | |||||
[Rr]eleases/ | |||||
x64/ | |||||
x86/ | |||||
bld/ | |||||
[Bb]in/ | |||||
[Oo]bj/ | |||||
[Ll]og/ | |||||
# Visual Studio 2015 cache/options directory | |||||
.vs/ | |||||
# Uncomment if you have tasks that create the project's static files in wwwroot | |||||
#wwwroot/ | |||||
# MSTest test Results | |||||
[Tt]est[Rr]esult*/ | |||||
[Bb]uild[Ll]og.* | |||||
# NUNIT | |||||
*.VisualState.xml | |||||
TestResult.xml | |||||
# Build Results of an ATL Project | |||||
[Dd]ebugPS/ | |||||
[Rr]eleasePS/ | |||||
dlldata.c | |||||
# .NET Core | |||||
project.lock.json | |||||
project.fragment.lock.json | |||||
artifacts/ | |||||
**/Properties/launchSettings.json | |||||
*_i.c | |||||
*_p.c | |||||
*_i.h | |||||
*.ilk | |||||
*.meta | |||||
*.obj | |||||
*.pch | |||||
*.pdb | |||||
*.pgc | |||||
*.pgd | |||||
*.rsp | |||||
*.sbr | |||||
*.tlb | |||||
*.tli | |||||
*.tlh | |||||
*.tmp | |||||
*.tmp_proj | |||||
*.log | |||||
*.vspscc | |||||
*.vssscc | |||||
.builds | |||||
*.pidb | |||||
*.svclog | |||||
*.scc | |||||
# Chutzpah Test files | |||||
_Chutzpah* | |||||
# Visual C++ cache files | |||||
ipch/ | |||||
*.aps | |||||
*.ncb | |||||
*.opendb | |||||
*.opensdf | |||||
*.sdf | |||||
*.cachefile | |||||
*.VC.db | |||||
*.VC.VC.opendb | |||||
# Visual Studio profiler | |||||
*.psess | |||||
*.vsp | |||||
*.vspx | |||||
*.sap | |||||
# TFS 2012 Local Workspace | |||||
$tf/ | |||||
# Guidance Automation Toolkit | |||||
*.gpState | |||||
# ReSharper is a .NET coding add-in | |||||
_ReSharper*/ | |||||
*.[Rr]e[Ss]harper | |||||
*.DotSettings.user | |||||
# JustCode is a .NET coding add-in | |||||
.JustCode | |||||
# TeamCity is a build add-in | |||||
_TeamCity* | |||||
# DotCover is a Code Coverage Tool | |||||
*.dotCover | |||||
# Visual Studio code coverage results | |||||
*.coverage | |||||
*.coveragexml | |||||
# NCrunch | |||||
_NCrunch_* | |||||
.*crunch*.local.xml | |||||
nCrunchTemp_* | |||||
# MightyMoose | |||||
*.mm.* | |||||
AutoTest.Net/ | |||||
# Web workbench (sass) | |||||
.sass-cache/ | |||||
# Installshield output folder | |||||
[Ee]xpress/ | |||||
# DocProject is a documentation generator add-in | |||||
DocProject/buildhelp/ | |||||
DocProject/Help/*.HxT | |||||
DocProject/Help/*.HxC | |||||
DocProject/Help/*.hhc | |||||
DocProject/Help/*.hhk | |||||
DocProject/Help/*.hhp | |||||
DocProject/Help/Html2 | |||||
DocProject/Help/html | |||||
# Click-Once directory | |||||
publish/ | |||||
# Publish Web Output | |||||
*.[Pp]ublish.xml | |||||
*.azurePubxml | |||||
# TODO: Comment the next line if you want to checkin your web deploy settings | |||||
# but database connection strings (with potential passwords) will be unencrypted | |||||
*.pubxml | |||||
*.publishproj | |||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to | |||||
# checkin your Azure Web App publish settings, but sensitive information contained | |||||
# in these scripts will be unencrypted | |||||
PublishScripts/ | |||||
# NuGet Packages | |||||
*.nupkg | |||||
# The packages folder can be ignored because of Package Restore | |||||
**/packages/* | |||||
# except build/, which is used as an MSBuild target. | |||||
!**/packages/build/ | |||||
# Uncomment if necessary however generally it will be regenerated when needed | |||||
#!**/packages/repositories.config | |||||
# NuGet v3's project.json files produces more ignorable files | |||||
*.nuget.props | |||||
*.nuget.targets | |||||
# Microsoft Azure Build Output | |||||
csx/ | |||||
*.build.csdef | |||||
# Microsoft Azure Emulator | |||||
ecf/ | |||||
rcf/ | |||||
# Windows Store app package directories and files | |||||
AppPackages/ | |||||
BundleArtifacts/ | |||||
Package.StoreAssociation.xml | |||||
_pkginfo.txt | |||||
# Visual Studio cache files | |||||
# files ending in .cache can be ignored | |||||
*.[Cc]ache | |||||
# but keep track of directories ending in .cache | |||||
!*.[Cc]ache/ | |||||
# Others | |||||
ClientBin/ | |||||
~$* | |||||
*~ | |||||
*.dbmdl | |||||
*.dbproj.schemaview | |||||
*.jfm | |||||
*.pfx | |||||
*.publishsettings | |||||
orleans.codegen.cs | |||||
# Since there are multiple workflows, uncomment next line to ignore bower_components | |||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||||
#bower_components/ | |||||
# RIA/Silverlight projects | |||||
Generated_Code/ | |||||
# Backup & report files from converting an old project file | |||||
# to a newer Visual Studio version. Backup files are not needed, | |||||
# because we have git ;-) | |||||
_UpgradeReport_Files/ | |||||
Backup*/ | |||||
UpgradeLog*.XML | |||||
UpgradeLog*.htm | |||||
# SQL Server files | |||||
*.mdf | |||||
*.ldf | |||||
*.ndf | |||||
# Business Intelligence projects | |||||
*.rdl.data | |||||
*.bim.layout | |||||
*.bim_*.settings | |||||
# Microsoft Fakes | |||||
FakesAssemblies/ | |||||
# GhostDoc plugin setting file | |||||
*.GhostDoc.xml | |||||
# Node.js Tools for Visual Studio | |||||
.ntvs_analysis.dat | |||||
node_modules/ | |||||
# Typescript v1 declaration files | |||||
typings/ | |||||
# Visual Studio 6 build log | |||||
*.plg | |||||
# Visual Studio 6 workspace options file | |||||
*.opt | |||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | |||||
*.vbw | |||||
# Visual Studio LightSwitch build output | |||||
**/*.HTMLClient/GeneratedArtifacts | |||||
**/*.DesktopClient/GeneratedArtifacts | |||||
**/*.DesktopClient/ModelManifest.xml | |||||
**/*.Server/GeneratedArtifacts | |||||
**/*.Server/ModelManifest.xml | |||||
_Pvt_Extensions | |||||
# Paket dependency manager | |||||
.paket/paket.exe | |||||
paket-files/ | |||||
# FAKE - F# Make | |||||
.fake/ | |||||
# JetBrains Rider | |||||
.idea/ | |||||
*.sln.iml | |||||
# CodeRush | |||||
.cr/ | |||||
# Python Tools for Visual Studio (PTVS) | |||||
__pycache__/ | |||||
*.pyc | |||||
# Cake - Uncomment if you are using it | |||||
# tools/** | |||||
# !tools/packages.config | |||||
# Telerik's JustMock configuration file | |||||
*.jmconfig | |||||
# BizTalk build output | |||||
*.btp.cs | |||||
*.btm.cs | |||||
*.odx.cs | |||||
*.xsd.cs |
@@ -0,0 +1,21 @@ | |||||
MIT License | |||||
Copyright (c) 2018 SmallChi | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE. |
@@ -0,0 +1,20 @@ | |||||
using System; | |||||
using System.IO; | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
public abstract class BufferedEntityBase : IBuffered, IBuffer | |||||
{ | |||||
public byte[] Buffer { get; protected set; } | |||||
public virtual byte[] ToBuffer() | |||||
{ | |||||
return Buffer; | |||||
} | |||||
protected BufferedEntityBase(byte[] buffer) | |||||
{ | |||||
Buffer = buffer; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,29 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Enums | |||||
{ | |||||
/// <summary> | |||||
/// 应答标志 | |||||
/// </summary> | |||||
public enum AskId:byte | |||||
{ | |||||
/// <summary> | |||||
/// 接收到的信息正确 | |||||
/// </summary> | |||||
success=0x01, | |||||
/// <summary> | |||||
/// 设置未成功 | |||||
/// </summary> | |||||
error=0x02, | |||||
/// <summary> | |||||
/// VIN重复错误 | |||||
/// </summary> | |||||
vin_repeat_error=0x03, | |||||
/// <summary> | |||||
/// 数据包为命令包,而非应答包 | |||||
/// </summary> | |||||
cmd=0xFE | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Enums | |||||
{ | |||||
/// <summary> | |||||
/// 数据单元加密方式 | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
/// </summary> | |||||
public enum EncryptMethod:byte | |||||
{ | |||||
None= 0x01, | |||||
RSA= 0x02, | |||||
AES128=0x03, | |||||
Exception = 0xFE, | |||||
Invalid= 0xFF | |||||
} | |||||
} |
@@ -0,0 +1,46 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol.Enums | |||||
{ | |||||
public enum MsgId:byte | |||||
{ | |||||
/// <summary> | |||||
/// 车辆登入 | |||||
/// </summary> | |||||
login = 0x01, | |||||
/// <summary> | |||||
/// 实时信息上传 | |||||
/// </summary> | |||||
uploadim = 0x02, | |||||
/// <summary> | |||||
/// 心跳 | |||||
/// </summary> | |||||
heartbeat = 0x03, | |||||
/// <summary> | |||||
/// 补传信息上传 | |||||
/// </summary> | |||||
uploadsup = 0x04, | |||||
/// <summary> | |||||
/// 车辆登出 | |||||
/// </summary> | |||||
loginout = 0x05, | |||||
/// <summary> | |||||
/// 终端校时 | |||||
/// </summary> | |||||
checktime = 0x08, | |||||
/// <summary> | |||||
/// 查询应答 | |||||
/// </summary> | |||||
query = 0x80, | |||||
/// <summary> | |||||
/// 设置应答 | |||||
/// </summary> | |||||
settings = 0x81, | |||||
/// <summary> | |||||
/// 控制应答 | |||||
/// </summary> | |||||
control = 0x82 | |||||
} | |||||
} |
@@ -0,0 +1,49 @@ | |||||
using System; | |||||
using System.IO; | |||||
using System.Linq; | |||||
namespace GBNewEnergy.Protocol.Extensions | |||||
{ | |||||
public static class BinaryExtensions | |||||
{ | |||||
/// <summary> | |||||
/// 从高位到低位转成int | |||||
/// </summary> | |||||
/// <param name="buf"></param> | |||||
/// <param name="offset"></param> | |||||
/// <param name="len"></param> | |||||
/// <returns></returns> | |||||
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; | |||||
} | |||||
/// <summary> | |||||
/// 字节数组转16进制字符串 | |||||
/// </summary> | |||||
/// <param name="bytes"></param> | |||||
/// <param name="separator">默认 " "</param> | |||||
/// <returns></returns> | |||||
public static string ToHexString(this byte[] bytes,string separator=" ") | |||||
{ | |||||
return string.Join(separator, bytes.Select(s => s.ToString("X2"))); | |||||
} | |||||
/// <summary> | |||||
/// 16进制字符串转16进制数组 | |||||
/// </summary> | |||||
/// <param name="hexString"></param> | |||||
/// <param name="separator"></param> | |||||
/// <returns></returns> | |||||
public static byte[] ToHexBytes(this string hexString, string separator = " ") | |||||
{ | |||||
return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,7 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netstandard2.0</TargetFramework> | |||||
</PropertyGroup> | |||||
</Project> |
@@ -0,0 +1,7 @@ | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
public interface IBuffer | |||||
{ | |||||
byte[] Buffer { get; } | |||||
} | |||||
} |
@@ -0,0 +1,7 @@ | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
public interface IBuffered | |||||
{ | |||||
byte[] ToBuffer(); | |||||
} | |||||
} |
@@ -0,0 +1,48 @@ | |||||
using GBNewEnergy.Protocol.Enums; | |||||
using GBNewEnergy.Protocol.Extensions; | |||||
using System; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
/// <summary> | |||||
/// 头部 | |||||
/// </summary> | |||||
public class NEHeader: BufferedEntityBase | |||||
{ | |||||
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> | |||||
public const byte BeginFlag = 0x23; | |||||
/// <summary> | |||||
/// 命令标识 | |||||
/// </summary> | |||||
public MsgId MsgId { get; private set; } | |||||
/// <summary> | |||||
/// 应答标志 | |||||
/// </summary> | |||||
public AskId AskId { get; private set; } | |||||
/// <summary> | |||||
/// 车辆识别码 | |||||
/// </summary> | |||||
public string VIN { get; private set; } | |||||
/// <summary> | |||||
/// 数据加密方式 | |||||
/// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效 | |||||
/// </summary> | |||||
public EncryptMethod EncryptMethod { get; private set; } | |||||
/// <summary> | |||||
/// 数据单元长度是数据单元的总字节数,有效值范围:0-65531 | |||||
/// </summary> | |||||
public int DataUnitLength { get; private set; } | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
using GBNewEnergy.Protocol.Enums; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace GBNewEnergy.Protocol | |||||
{ | |||||
/// <summary> | |||||
/// 新能源包 | |||||
/// </summary> | |||||
public class NEPackage: BufferedEntityBase | |||||
{ | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 固定为24个字节长度 | |||||
/// </summary> | |||||
public const int HeaderFixedByteLength = 24; | |||||
/// <summary> | |||||
/// 头部 | |||||
/// </summary> | |||||
public NEHeader NEHeader { get; private set; } | |||||
/// <summary> | |||||
/// 数据单元 | |||||
/// </summary> | |||||
public byte[] DataUnit { get; private set; } | |||||
/// <summary> | |||||
/// BCC 校验码 | |||||
/// </summary> | |||||
public byte BCCCode { get; private set; } | |||||
/// <summary> | |||||
/// 原始包(包头+包体) | |||||
/// </summary> | |||||
public byte[] OriginalPackage { get; private set; } | |||||
} | |||||
} |
@@ -0,0 +1,25 @@ | |||||
| |||||
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}" | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|Any CPU = Debug|Any CPU | |||||
Release|Any CPU = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{1934F3A6-1396-46C2-BFD6-1E2DC1A26E3A}.Debug|Any CPU.ActiveCfg = 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.Build.0 = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
GlobalSection(ExtensibilityGlobals) = postSolution | |||||
SolutionGuid = {E7AF20B3-4327-4DF7-B503-9FE08AA92A75} | |||||
EndGlobalSection | |||||
EndGlobal |