commit 68225ce7ae65db8cd5b6fc76ad63b4a773a137a5 Author: SmallChi <564952747@qq.com> Date: Wed Jun 26 22:55:30 2019 +0800 重新出发 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e759b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,330 @@ +## 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/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# 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 + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.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 + +# Visual Studio Trace Files +*.e2e + +# 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 + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# 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 +# Note: 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 +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/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 +*.appx + +# 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 + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# 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 +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# 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 + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1fa2f4c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: csharp +solution: JT808.Protocol.sln +dotnet: 2.2.101 +os: linux +mono: none +dist: trusty2 +script: + - dotnet restore src/JT808.Protocol.sln + - dotnet build src/JT808.Protocol.Test/JT808.Protocol.Test.csproj + - dotnet test src/JT808.Protocol.Test/JT808.Protocol.Test.csproj +after_success: + - echo successful build! +branches: + only: + - master diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67b52f7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 SmallChi(Koike) + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb88beb --- /dev/null +++ b/README.md @@ -0,0 +1,377 @@ +# JT808协议 + +[![MIT Licence](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/SmallChi/JT808/blob/master/LICENSE)[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FSmallChi%2FJT808.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FSmallChi%2FJT808?ref=badge_shield)[![Build Status](https://travis-ci.org/SmallChi/JT808.svg?branch=master)](https://travis-ci.org/SmallChi/JT808) + +## 前提条件 + +1. 掌握进制转换:二进制转十六进制; +2. 掌握BCD编码、Hex编码; +3. 掌握各种位移、异或; +4. 掌握常用反射; +5. 掌握快速ctrl+c、ctrl+v; +6. 掌握Span\的基本用法 +7. 掌握以上装逼技能,就可以开始搬砖了。 + +## JT808数据结构解析 + +### 数据包[JT808Package] + +| 头标识 | 数据头 | 数据体 | 校验码 | 尾标识 | +| :----: | :---------: | :---------: | :-------: | :----: | +| Begin | JT808Header | JT808Bodies | CheckCode | End | +| 7E | - | - | - | 7E | + +### 数据头[JT808Header] + +| 消息ID | 消息体属性 | 终端手机号 | 消息流水号 | +| :----: | :----------------------------: | :-------------: | :--------: | +| MsgId | JT808HeaderMessageBodyProperty | TerminalPhoneNo | MsgNum | + +#### 数据头-消息体属性[JT808HeaderMessageBodyProperty] + +| 是否分包 | 加密标识 | 消息体长度 | 消息总包数 | 包序号 | +| :------: | :------: | :--------: | :---------: | :----------: | +| IsPackge | Encrypt | DataLength | PackgeCount | PackageIndex | + +#### 消息体属性[JT808Bodies] + +> 根据对应消息ID:MsgId + +***注意:数据内容(除去头和尾标识)进行转义判断*** + +转义规则如下: + +1. 若数据内容中有出现字符 0x7e 的,需替换为字符 0x7d 紧跟字符 0x02; +2. 若数据内容中有出现字符 0x7d 的,需替换为字符 0x7d 紧跟字符 0x01; + +反转义的原因:确认JT808协议的TCP消息边界。 + +### 举个栗子1 + +#### 1.组包: + +> MsgId 0x0200:位置信息汇报 + +``` package + +JT808Package jT808Package = new JT808Package(); + +jT808Package.Header = new JT808Header +{ + MsgId = Enums.JT808MsgId.位置信息汇报, + MsgNum = 126, + TerminalPhoneNo = "123456789012" +}; + +JT808_0x0200 jT808_0x0200 = new JT808_0x0200(); +jT808_0x0200.AlarmFlag = 1; +jT808_0x0200.Altitude = 40; +jT808_0x0200.GPSTime = DateTime.Parse("2018-10-15 10:10:10"); +jT808_0x0200.Lat = 12222222; +jT808_0x0200.Lng = 132444444; +jT808_0x0200.Speed = 60; +jT808_0x0200.Direction = 0; +jT808_0x0200.StatusFlag = 2; +jT808_0x0200.JT808LocationAttachData = new Dictionary(); + +jT808_0x0200.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 +{ + Mileage = 100 +}); + +jT808_0x0200.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 +{ + Oil = 125 +}); + +jT808Package.Bodies = jT808_0x0200; + +byte[] data = JT808Serializer.Serialize(jT808Package); + +var hex = data.ToHexString(); + +// 输出结果Hex: +// 7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E +``` + +#### 2.手动解包: + +``` unpackage +1.原包: +7E 02 00 00 26 12 34 56 78 90 12 00 (7D 02) 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 (7D 01) 13 7E + +2.进行反转义 +7D 02 ->7E +7D 01 ->7D +反转义后 +7E 02 00 00 26 12 34 56 78 90 12 00 7E 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 13 7E + +3.拆解 +7E --头标识 +02 00 --数据头->消息ID +00 26 --数据头->消息体属性 +12 34 56 78 90 12 --数据头->终端手机号 +00 7E --数据头->消息流水号 +00 00 00 01 --消息体->报警标志 +00 00 00 02 --消息体->状态位标志 +00 BA 7F 0E --消息体->纬度 +07 E4 F1 1C --消息体->经度 +00 28 --消息体->海拔高度 +00 3C --消息体->速度 +00 00 --消息体->方向 +18 10 15 10 10 10 --消息体->GPS时间 +01 --消息体->附加信息->里程 +04 --消息体->附加信息->长度 +00 00 00 64 --消息体->附加信息->数据 +02 --消息体->附加信息->油量 +02 --消息体->附加信息->长度 +00 7D --消息体->附加信息->数据 +13 --检验码 +7E --尾标识 +``` + +#### 3.程序解包: + +``` unpackage2 +//1.转成byte数组 +byte[] bytes = "7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E".ToHexBytes(); + +//2.将数组反序列化 +var jT808Package = JT808Serializer.Deserialize(bytes); + +//3.数据包头 +Assert.Equal(Enums.JT808MsgId.位置信息汇报, jT808Package.Header.MsgId); +Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); +Assert.Equal(126, jT808Package.Header.MsgNum); +Assert.Equal("123456789012", jT808Package.Header.TerminalPhoneNo); +Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); +Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); +Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); +Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); + +//4.数据包体 +JT808_0x0200 jT808_0x0200 = (JT808_0x0200)jT808Package.Bodies; +Assert.Equal((uint)1, jT808_0x0200.AlarmFlag); +Assert.Equal((uint)40, jT808_0x0200.Altitude); +Assert.Equal(DateTime.Parse("2018-10-15 10:10:10"), jT808_0x0200.GPSTime); +Assert.Equal(12222222, jT808_0x0200.Lat); +Assert.Equal(132444444, jT808_0x0200.Lng); +Assert.Equal(60, jT808_0x0200.Speed); +Assert.Equal(0, jT808_0x0200.Direction); +Assert.Equal((uint)2, jT808_0x0200.StatusFlag); +//4.1.附加信息1 +Assert.Equal(100, ((JT808_0x0200_0x01)jT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); +//4.2.附加信息2 +Assert.Equal(125, ((JT808_0x0200_0x02)jT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); +``` + +### 举个栗子2 + +``` create package +// 使用消息Id的扩展方法创建JT808Package包 +JT808Package jT808Package = Enums.JT808MsgId.位置信息汇报.Create("123456789012", + new JT808_0x0200 { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-10-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary + { + { JT808_0x0200_BodyBase.AttachId0x01,new JT808_0x0200_0x01{Mileage = 100}}, + { JT808_0x0200_BodyBase.AttachId0x02,new JT808_0x0200_0x02{Oil = 125}} + } +}); + +byte[] data = JT808Serializer.Serialize(jT808Package); + +var hex = data.ToHexString(); +//输出结果Hex: +//7E 02 00 00 26 12 34 56 78 90 12 00 01 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 6C 7E +``` + +### 举个栗子3 + +``` config +// 初始化配置 +IJT808Config jT808Config = DefaultGlobalConfig.Create(); +// 注册自定义消息外部程序集 +jT808Config.Register(Assembly.GetExecutingAssembly()); +// 跳过校验和验证 +jT808Config.SkipCRCCode = true; +// 根据不同的设备终端号,添加自定义消息Id +jT808Config.MsgIdFactory.CustomSetMap(0x91, "1234567891"); +jT808Config.MsgIdFactory.CustomSetMap(0x91, "1234567892"); +// 初始化序列化实例 +JT808Serializer JT808Serializer = new JT808Serializer(jT808Coonfig); +``` + +### 举个栗子4 + +#### 遇到的问题-多设备多协议的自定义位置附加信息 + +场景: +一个设备厂商对应多个设备类型,不同设备类型可能存在相同的自定义位置附加信息Id,导致自定义附加信息Id冲突,无法解析。 + +***解决方式:*** + +1.凡是解析自定义附加信息Id协议的,先进行分割存储,然后在根据外部的设备类型进行统一处理; + +2.可以根据设备类型做个工厂,解耦对公共序列化器的依赖。 + +[可以参考Simples的Demo4](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo4.cs) + +> 要是哪位大佬还有其他的解决方式,请您告知我下,谢谢您了。 + +### 举个栗子5 + +#### 遇到的问题-多媒体数据上传进行分包处理 + +场景: +设备在上传多媒体数据的时候,由于数据比较多,一次上传不了,所以采用分包方式处理。 + +***解决方式:*** + +1. 第一包数据上来采用平常的方式去解析数据; + +2. 当N包数据上来,采用统一分包消息体去接收数据,最后在合并成一条。 + +> 普及知识点:一般行业分包是按256的整数倍,太多不行,太少也不行,必须刚刚好。 + +[可以参考Simples的Demo5](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo5.cs) + +### 举个栗子6 + +#### 遇到的问题-多设备多协议的消息ID冲突 + +场景: +由于每个设备厂商不同,导致设备的私有协议可能使用相同的消息ID作为指令,导致平台解析不了。 + +***解决方式:*** + +对于设备来说,设备终端号是唯一标识,可以通过使用设备终端号和消息ID去查询对应的序列化器。 + +[可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) + +## NuGet安装 + +| Package Name | Version | Downloads | +| --------------------- | -------------------------------------------------- | --------------------------------------------------- | +| Install-Package JT808 | ![JT808](https://img.shields.io/nuget/v/JT808.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.svg) | +| Install-Package JT808.Extensions.DependencyInjection | ![JT808](https://img.shields.io/nuget/v/JT808.Extensions.DependencyInjection.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.Extensions.DependencyInjection.svg) | + +## 使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真) + +``` ini + +BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17763.557 (1809/October2018Update/Redstone5) +Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores + [Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + Job-FVMQGI : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + Job-LGLQDK : .NET Core 2.2.5 (CoreCLR 4.6.27617.05, CoreFX 4.6.27618.01), 64bit RyuJIT + +Platform=AnyCpu Runtime=Clr Server=False + +``` +| Method | Toolchain | Categories | N | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------------------- |-------------- |----------------- |------- |---------------:|---------------:|---------------:|------------:|------:|------:|-------------:| +| **0x0200_All_AttachId_Serialize** | **Default** | **0x0200Serializer** | **100** | **2,738.7 us** | **35.0088 us** | **32.7472 us** | **35.1563** | **-** | **-** | **216.41 KB** | +| 0x0200_All_AttachId_Deserialize | Default | 0x0200Serializer | 100 | 3,538.1 us | 11.0285 us | 10.3161 us | 101.5625 | - | - | 642.21 KB | +| 0x0200_All_AttachId_Serialize | .NET Core 2.2 | 0x0200Serializer | 100 | 2,363.2 us | 20.2865 us | 18.9760 us | 35.1563 | - | - | 216.41 KB | +| 0x0200_All_AttachId_Deserialize | .NET Core 2.2 | 0x0200Serializer | 100 | 3,164.9 us | 6.5366 us | 6.1143 us | 85.9375 | - | - | 529.69 KB | +| **0x0200_All_AttachId_Serialize** | **Default** | **0x0200Serializer** | **10000** | **274,593.1 us** | **1,039.6220 us** | **921.5978 us** | **3500.0000** | **-** | **-** | **21644.48 KB** | +| 0x0200_All_AttachId_Deserialize | Default | 0x0200Serializer | 10000 | 350,085.6 us | 970.7176 us | 908.0098 us | 10000.0000 | - | - | 64225.99 KB | +| 0x0200_All_AttachId_Serialize | .NET Core 2.2 | 0x0200Serializer | 10000 | 234,316.8 us | 465.8545 us | 412.9679 us | 3333.3333 | - | - | 21640.63 KB | +| 0x0200_All_AttachId_Deserialize | .NET Core 2.2 | 0x0200Serializer | 10000 | 320,220.8 us | 1,991.8278 us | 1,863.1570 us | 8000.0000 | - | - | 52968.75 KB | +| **0x0200_All_AttachId_Serialize** | **Default** | **0x0200Serializer** | **100000** | **2,712,565.1 us** | **18,460.3868 us** | **17,267.8572 us** | **35000.0000** | **-** | **-** | **216412.65 KB** | +| 0x0200_All_AttachId_Deserialize | Default | 0x0200Serializer | 100000 | 3,592,549.6 us | 38,841.1809 us | 36,332.0647 us | 104000.0000 | - | - | 642194.54 KB | +| 0x0200_All_AttachId_Serialize | .NET Core 2.2 | 0x0200Serializer | 100000 | 2,464,747.5 us | 10,310.9610 us | 9,140.3984 us | 35000.0000 | - | - | 216406.25 KB | +| 0x0200_All_AttachId_Deserialize | .NET Core 2.2 | 0x0200Serializer | 100000 | 3,258,521.7 us | 19,946.9515 us | 17,682.4529 us | 86000.0000 | - | - | 529687.5 KB | +| | | | | | | | | | | | +| **0x0100Serialize** | **Default** | **0x0100Serializer** | **100** | **327.8 us** | **4.3377 us** | **4.0575 us** | **15.1367** | **-** | **-** | **93.75 KB** | +| 0x0100Deserialize | Default | 0x0100Serializer | 100 | 334.6 us | 1.9826 us | 1.6556 us | 21.4844 | - | - | 132.03 KB | +| 0x0100Serialize | .NET Core 2.2 | 0x0100Serializer | 100 | 249.6 us | 1.6019 us | 1.4985 us | 13.6719 | - | - | 85.94 KB | +| 0x0100Deserialize | .NET Core 2.2 | 0x0100Serializer | 100 | 270.0 us | 0.9267 us | 0.7235 us | 21.4844 | - | - | 132.03 KB | +| **0x0100Serialize** | **Default** | **0x0100Serializer** | **10000** | **32,514.3 us** | **244.6675 us** | **228.8622 us** | **1500.0000** | **-** | **-** | **9375.11 KB** | +| 0x0100Deserialize | Default | 0x0100Serializer | 10000 | 34,035.9 us | 194.8483 us | 182.2612 us | 2133.3333 | - | - | 13203.35 KB | +| 0x0100Serialize | .NET Core 2.2 | 0x0100Serializer | 10000 | 24,874.6 us | 35.8662 us | 33.5493 us | 1375.0000 | - | - | 8593.75 KB | +| 0x0100Deserialize | .NET Core 2.2 | 0x0100Serializer | 10000 | 28,835.0 us | 286.1119 us | 253.6307 us | 2125.0000 | - | - | 13203.13 KB | +| **0x0100Serialize** | **Default** | **0x0100Serializer** | **100000** | **341,547.6 us** | **4,437.9179 us** | **3,934.0986 us** | **15000.0000** | **-** | **-** | **93753.05 KB** | +| 0x0100Deserialize | Default | 0x0100Serializer | 100000 | 348,338.5 us | 3,373.6509 us | 3,155.7151 us | 21000.0000 | - | - | 132033.48 KB | +| 0x0100Serialize | .NET Core 2.2 | 0x0100Serializer | 100000 | 255,128.1 us | 2,711.3270 us | 2,536.1770 us | 13500.0000 | - | - | 85937.5 KB | +| 0x0100Deserialize | .NET Core 2.2 | 0x0100Serializer | 100000 | 284,679.7 us | 3,831.0625 us | 3,396.1371 us | 21000.0000 | - | - | 132031.25 KB | + +## JT808终端通讯协议消息对照表 + +| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 | +| :---: | :-----------: | :------: | :------: | :----------------------------: | +| 1 | 0x0001 | √ | √ | 终端通用应答 | +| 2 | 0x8001 | √ | √ | 平台通用应答 | +| 3 | 0x0002 | √ | √ | 终端心跳 | +| 4 | 0x8003 | √ | √ | 补传分包请求 | +| 5 | 0x0100 | √ | √ | 终端注册 | +| 6 | 0x8100 | √ | √ | 终端注册应答 | +| 7 | 0x0003 | √ | √ | 终端注销 | +| 8 | 0x0102 | √ | √ | 终端鉴权 | +| 9 | 0x8103 | √ | √ | 设置终端参数 | +| 10 | 0x8104 | √ | √ | 查询终端参数 | +| 11 | 0x0104 | √ | √ | 查询终端参数应答 | +| 12 | 0x8105 | √ | √ | 终端控制 | +| 13 | 0x8106 | √ | √ | 查询指定终端参数 | +| 14 | 0x8107 | √ | 消息体为空| 查询终端属性 | +| 15 | 0x0107 | √ | √ | 查询终端属性应答 | +| 16 | 0x8108 | √ | √ | 下发终端升级包 | +| 17 | 0x0108 | √ | √ | 终端升级结果通知 | +| 18 | 0x0200 | √ | √ | 位置信息汇报 | +| 19 | 0x8201 | √ | √ | 位置信息查询 | +| 20 | 0x0201 | √ | √ | 位置信息查询应答 | +| 21 | 0x8202 | √ | √ | 临时位置跟踪控制 | +| 22 | 0x8203 | √ | √ | 人工确认报警消息 | +| 23 | 0x8300 | √ | √ | 文本信息下发 | +| 24 | 0x8301 | √ | √ | 事件设置 | +| 25 | 0x0301 | √ | √ | 事件报告 | +| 26 | 0x8302 | √ | √ | 提问下发 | +| 27 | 0x0302 | √ | √ | 提问应答 | +| 28 | 0x8303 | √ | √ | 信息点播菜单设置 | +| 29 | 0x0303 | √ | √ | 信息点播/取消 | +| 30 | 0x8304 | √ | √ | 信息服务 | +| 31 | 0x8400 | √ | √ | 电话回拨 | +| 32 | 0x8401 | √ | √ | 设置电话本 | +| 33 | 0x8500 | √ | √ | 车辆控制 | +| 34 | 0x0500 | √ | √ | 车辆控制应答 | +| 35 | 0x8600 | √ | √ | 设置圆形区域 | +| 36 | 0x8601 | √ | √ | 删除圆形区域 | +| 37 | 0x8602 | √ | √ | 设置矩形区域 | +| 38 | 0x8603 | √ | √ | 删除矩形区域 | +| 39 | 0x8604 | √ | √ | 设置多边形区域 | +| 40 | 0x8605 | √ | √ | 删除多边形区域 | +| 41 | 0x8606 | √ | √ | 设置路线 | +| 42 | 0x8607 | √ | √ | 删除路线 | +| 43 | 0x8700 | x | 下个版本 | 行驶记录仪数据采集命令 | +| 44 | 0x0700 | x | 下个版本 | 行驶记录仪数据上传 | +| 45 | 0x8701 | x | 下个版本 | 行驶记录仪参数下传命令 | +| 46 | 0x0701 | √ | √ | 电子运单上报 | +| 47 | 0x0702 | √ | √ | 驾驶员身份信息采集上报 | +| 48 | 0x8702 | √ | 消息体为空| 上报驾驶员身份信息请求 | +| 49 | 0x0704 | √ | √ | 定位数据批量上传 | +| 50 | 0x0705 | √ | √ | CAN 总线数据上传 | +| 51 | 0x0800 | √ | √ | 多媒体事件信息上传 | +| 52 | 0x0801 | √ | √ | 多媒体数据上传 | +| 53 | 0x8800 | √ | √ | 多媒体数据上传应答 | +| 54 | 0x8801 | √ | √ | 摄像头立即拍摄命令 | +| 55 | 0x0805 | √ | √ | 摄像头立即拍摄命令应答 | +| 56 | 0x8802 | √ | √ | 存储多媒体数据检索 | +| 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | +| 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | +| 59 | 0x8804 | √ | √ | 录音开始命令 | +| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 | +| 61 | 0x8900 | √ | √ | 数据下行透传 | +| 62 | 0x0900 | √ | √ | 数据上行透传 | +| 63 | 0x0901 | √ | √ | 数据压缩上报 | +| 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | +| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | +| 66 | 0x8F00~0x8FFF | 保留 | 保留 | 平台下行消息保留 | +| 67 | 0x0F00~0x0FFF | 保留 | 保留 | 终端上行消息保留 | diff --git a/doc/808809补充协议.pdf b/doc/808809补充协议.pdf new file mode 100644 index 0000000..0e7ccc5 Binary files /dev/null and b/doc/808809补充协议.pdf differ diff --git a/doc/GBT-19056.pdf b/doc/GBT-19056.pdf new file mode 100644 index 0000000..12d9b38 Binary files /dev/null and b/doc/GBT-19056.pdf differ diff --git a/doc/JT808.pdf b/doc/JT808.pdf new file mode 100644 index 0000000..461a393 --- /dev/null +++ b/doc/JT808.pdf @@ -0,0 +1,5482 @@ +%PDF-1.4 +%μῦ + +1 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +2 0 obj +[3 0 R 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R 57 0 R 58 0 R 59 0 R 60 0 R 61 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R 67 0 R 68 0 R 69 0 R 70 0 R 71 0 R 72 0 R 73 0 R 74 0 R 75 0 R 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R] +endobj + +3 0 obj +<>/A 82 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +4 0 obj +<>/A 83 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +5 0 obj +<>/A 84 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +6 0 obj +<>/A 85 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +7 0 obj +<>/A 86 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +8 0 obj +<>/A 87 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +9 0 obj +<>/A 88 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +10 0 obj +<>/A 89 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +11 0 obj +<>/A 90 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +12 0 obj +<>/A 91 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +13 0 obj +<>/A 92 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +14 0 obj +<>/A 93 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +15 0 obj +<>/A 94 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +16 0 obj +<>/A 95 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +17 0 obj +<>/A 96 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +18 0 obj +<>/A 97 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +19 0 obj +<>/A 98 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +20 0 obj +<>/A 99 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +21 0 obj +<>/A 100 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +22 0 obj +<>/A 101 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +23 0 obj +<>/A 102 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +24 0 obj +<>/A 103 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +25 0 obj +<>/A 104 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +26 0 obj +<>/A 105 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +27 0 obj +<>/A 106 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +28 0 obj +<>/A 107 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +29 0 obj +<>/A 108 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +30 0 obj +<>/A 109 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +31 0 obj +<>/A 110 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +32 0 obj +<>/A 111 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +33 0 obj +<>/A 112 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +34 0 obj +<>/A 113 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +35 0 obj +<>/A 114 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +36 0 obj +<>/A 115 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +37 0 obj +<>/A 116 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +38 0 obj +<>/A 117 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +39 0 obj +<>/A 118 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +40 0 obj +<>/A 119 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +41 0 obj +<>/A 120 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +42 0 obj +<>/A 121 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +43 0 obj +<>/A 122 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +44 0 obj +<>/A 123 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +45 0 obj +<>/A 124 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +46 0 obj +<>/A 125 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +47 0 obj +<>/A 126 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +48 0 obj +<>/A 127 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +49 0 obj +<>/A 128 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +50 0 obj +<>/A 129 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +51 0 obj +<>/A 130 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +52 0 obj +<>/A 131 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +53 0 obj +<>/A 132 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +54 0 obj +<>/A 133 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +55 0 obj +<>/A 134 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +56 0 obj +<>/A 135 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +57 0 obj +<>/A 136 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +58 0 obj +<>/A 137 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +59 0 obj +<>/A 138 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +60 0 obj +<>/A 139 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +61 0 obj +<>/A 140 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +62 0 obj +<>/A 141 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +63 0 obj +<>/A 142 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +64 0 obj +<>/A 143 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +65 0 obj +<>/A 144 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +66 0 obj +<>/A 145 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +67 0 obj +<>/A 146 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +68 0 obj +<>/A 147 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +69 0 obj +<>/A 148 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +70 0 obj +<>/A 149 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +71 0 obj +<>/A 150 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +72 0 obj +<>/A 151 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +73 0 obj +<>/A 152 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +74 0 obj +<>/A 153 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +75 0 obj +<>/A 154 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +76 0 obj +<>/A 155 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +77 0 obj +<>/A 156 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +78 0 obj +<>/A 157 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +79 0 obj +<>/A 158 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +80 0 obj +<>/A 159 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +81 0 obj +<> +stream +HMF!AGU_`6XX'IaCr-˞֌lƒzGjP}jw=TXXAT> e1ʁ ZWVߟ 6+W_[*~r)~R~-!(s(ok TYa-xBk1_ON/?5]F_'f+*hY=9wDb%ڒd}3Dk].e$f4)o&eMzќVϼhv r]4><N{!nx)yj KKZF,sPo%>'>#`Ap:I E>YtUyO; 21SngcoGu{&µuCI6Ov}j3ݎ˦! .,&\nF:=Ey!Q%؅Yk}B,ø []t9#r/񘍹]F +dT +3簶)|kеB[/1GdՋ6IҾӅS!C Z=k[ddV7Ect wƲ|X}wߒKkCs]ZE Qktτ4N%}, *׷ f2dEStt*F>Q"ho*DL !KgL/zS,5mLnfG[1d2c9hld@`lpKti׀pa&BBv!/˕f2dgG]_B1, 0![ D4png]$ȅ:Hٌ^^tH-gFQ0'e i;fcZmpԥ0xnӛ='`C--cnص5[hq똄u I\)w`1XGw!1$}eWbu c!O͎.0clо.Ą+sU 5PMvp8 0ć 6# ۯ`[bfendstream +endobj + +82 0 obj +<> +endobj + +83 0 obj +<> +endobj + +84 0 obj +<> +endobj + +85 0 obj +<> +endobj + +86 0 obj +<> +endobj + +87 0 obj +<> +endobj + +88 0 obj +<> +endobj + +89 0 obj +<> +endobj + +90 0 obj +<> +endobj + +91 0 obj +<> +endobj + +92 0 obj +<> +endobj + +93 0 obj +<> +endobj + +94 0 obj +<> +endobj + +95 0 obj +<> +endobj + +96 0 obj +<> +endobj + +97 0 obj +<> +endobj + +98 0 obj +<> +endobj + +99 0 obj +<> +endobj + +100 0 obj +<> +endobj + +101 0 obj +<> +endobj + +102 0 obj +<> +endobj + +103 0 obj +<> +endobj + +104 0 obj +<> +endobj + +105 0 obj +<> +endobj + +106 0 obj +<> +endobj + +107 0 obj +<> +endobj + +108 0 obj +<> +endobj + +109 0 obj +<> +endobj + +110 0 obj +<> +endobj + +111 0 obj +<> +endobj + +112 0 obj +<> +endobj + +113 0 obj +<> +endobj + +114 0 obj +<> +endobj + +115 0 obj +<> +endobj + +116 0 obj +<> +endobj + +117 0 obj +<> +endobj + +118 0 obj +<> +endobj + +119 0 obj +<> +endobj + +120 0 obj +<> +endobj + +121 0 obj +<> +endobj + +122 0 obj +<> +endobj + +123 0 obj +<> +endobj + +124 0 obj +<> +endobj + +125 0 obj +<> +endobj + +126 0 obj +<> +endobj + +127 0 obj +<> +endobj + +128 0 obj +<> +endobj + +129 0 obj +<> +endobj + +130 0 obj +<> +endobj + +131 0 obj +<> +endobj + +132 0 obj +<> +endobj + +133 0 obj +<> +endobj + +134 0 obj +<> +endobj + +135 0 obj +<> +endobj + +136 0 obj +<> +endobj + +137 0 obj +<> +endobj + +138 0 obj +<> +endobj + +139 0 obj +<> +endobj + +140 0 obj +<> +endobj + +141 0 obj +<> +endobj + +142 0 obj +<> +endobj + +143 0 obj +<> +endobj + +144 0 obj +<> +endobj + +145 0 obj +<> +endobj + +146 0 obj +<> +endobj + +147 0 obj +<> +endobj + +148 0 obj +<> +endobj + +149 0 obj +<> +endobj + +150 0 obj +<> +endobj + +151 0 obj +<> +endobj + +152 0 obj +<> +endobj + +153 0 obj +<> +endobj + +154 0 obj +<> +endobj + +155 0 obj +<> +endobj + +156 0 obj +<> +endobj + +157 0 obj +<> +endobj + +158 0 obj +<> +endobj + +159 0 obj +<> +endobj + +160 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +161 0 obj +[162 0 R 163 0 R 164 0 R 165 0 R 166 0 R 167 0 R 168 0 R 169 0 R 170 0 R 171 0 R 172 0 R 173 0 R 174 0 R 175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R 182 0 R 183 0 R 184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R 239 0 R 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R 250 0 R 251 0 R 252 0 R 253 0 R] +endobj + +162 0 obj +<>/A 255 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +163 0 obj +<>/A 256 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +164 0 obj +<>/A 257 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +165 0 obj +<>/A 258 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +166 0 obj +<>/A 259 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +167 0 obj +<>/A 260 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +168 0 obj +<>/A 261 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +169 0 obj +<>/A 262 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +170 0 obj +<>/A 263 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +171 0 obj +<>/A 264 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +172 0 obj +<>/A 265 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +173 0 obj +<>/A 266 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +174 0 obj +<>/A 267 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +175 0 obj +<>/A 268 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +176 0 obj +<>/A 269 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +177 0 obj +<>/A 270 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +178 0 obj +<>/A 271 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +179 0 obj +<>/A 272 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +180 0 obj +<>/A 273 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +181 0 obj +<>/A 274 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +182 0 obj +<>/A 275 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +183 0 obj +<>/A 276 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +184 0 obj +<>/A 277 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +185 0 obj +<>/A 278 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +186 0 obj +<>/A 279 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +187 0 obj +<>/A 280 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +188 0 obj +<>/A 281 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +189 0 obj +<>/A 282 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +190 0 obj +<>/A 283 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +191 0 obj +<>/A 284 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +192 0 obj +<>/A 285 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +193 0 obj +<>/A 286 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +194 0 obj +<>/A 287 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +195 0 obj +<>/A 288 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +196 0 obj +<>/A 289 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +197 0 obj +<>/A 290 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +198 0 obj +<>/A 291 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +199 0 obj +<>/A 292 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +200 0 obj +<>/A 293 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +201 0 obj +<>/A 294 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +202 0 obj +<>/A 295 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +203 0 obj +<>/A 296 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +204 0 obj +<>/A 297 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +205 0 obj +<>/A 298 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +206 0 obj +<>/A 299 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +207 0 obj +<>/A 300 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +208 0 obj +<>/A 301 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +209 0 obj +<>/A 302 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +210 0 obj +<>/A 303 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +211 0 obj +<>/A 304 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +212 0 obj +<>/A 305 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +213 0 obj +<>/A 306 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +214 0 obj +<>/A 307 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +215 0 obj +<>/A 308 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +216 0 obj +<>/A 309 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +217 0 obj +<>/A 310 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +218 0 obj +<>/A 311 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +219 0 obj +<>/A 312 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +220 0 obj +<>/A 313 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +221 0 obj +<>/A 314 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +222 0 obj +<>/A 315 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +223 0 obj +<>/A 316 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +224 0 obj +<>/A 317 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +225 0 obj +<>/A 318 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +226 0 obj +<>/A 319 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +227 0 obj +<>/A 320 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +228 0 obj +<>/A 321 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +229 0 obj +<>/A 322 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +230 0 obj +<>/A 323 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +231 0 obj +<>/A 324 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +232 0 obj +<>/A 325 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +233 0 obj +<>/A 326 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +234 0 obj +<>/A 327 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +235 0 obj +<>/A 328 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +236 0 obj +<>/A 329 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +237 0 obj +<>/A 330 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +238 0 obj +<>/A 331 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +239 0 obj +<>/A 332 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +240 0 obj +<>/A 333 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +241 0 obj +<>/A 334 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +242 0 obj +<>/A 335 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +243 0 obj +<>/A 336 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +244 0 obj +<>/A 337 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +245 0 obj +<>/A 338 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +246 0 obj +<>/A 339 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +247 0 obj +<>/A 340 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +248 0 obj +<>/A 341 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +249 0 obj +<>/A 342 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +250 0 obj +<>/A 343 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +251 0 obj +<>/A 344 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +252 0 obj +<>/A 345 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +253 0 obj +<>/A 346 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +254 0 obj +<> +stream +HMoFເC虝/0%"=RҢ Z;.M} d%`}js/P}InV?6PWs~v**/a_h+lW ݿM4 Cnl~v?mn;{S}ǎ#Gߧ;"5܀nѿ_x慂A&<0T +^OM,xc4dٌbtv wBLilCCx4l 7oi#4)2&'YWa.j {惸l_ 8?8Чq:;I5yfjXԚZdM8 +ըFJUI*)UeV!@{T@1h'&EC6{h sYf̫R$D)U-N6/&b ϢYTZ5gyn^լIz=GyZ)Ufyj J10X,ݻr6N f̂vy]yV+Tmp<UԪ2L]+y30S^| TK#I 8 H)MVeA.#l'Hj$̂~& 0ֽhKh83#kyX Gy[sd6<3m?1w-W\y +f6-sl +a>,\9, nd,SU1h5Y+]B/Ot(gop3'8|_vni%܂6<|ͭ)|ְxkhQrk@WK4%3$%iA 4 I]3] sdF;IIZ -^P +QjKk 328 IZRֶ} hcK9$5iAO<,G?]4@S20K@mOwt}+0@hٚYj{"-sG XL~ڞ}ꯋ@S2m%'>L1h5Y 3Xfmq|0yΆ^E2ŨϩF:UA*/|*^jiTӨz/x2uUqUK4%oc.jfIe 81q<>&b Et䏂__Z 4UNr~%LF0RT8^PBNdVTW2% mbfCurK4%sYi+hj, }&KƠ;>#ŝ@)jX% h)ܧcg-g dnȲ(UvmNu{-*JR\Ff00vֵ7\|ag\)5"Bf .IL.syxۼvga; jT #*$:6UUϫPKT Q$uBs,ZF M?Pendstream +endobj + +255 0 obj +<> +endobj + +256 0 obj +<> +endobj + +257 0 obj +<> +endobj + +258 0 obj +<> +endobj + +259 0 obj +<> +endobj + +260 0 obj +<> +endobj + +261 0 obj +<> +endobj + +262 0 obj +<> +endobj + +263 0 obj +<> +endobj + +264 0 obj +<> +endobj + +265 0 obj +<> +endobj + +266 0 obj +<> +endobj + +267 0 obj +<> +endobj + +268 0 obj +<> +endobj + +269 0 obj +<> +endobj + +270 0 obj +<> +endobj + +271 0 obj +<> +endobj + +272 0 obj +<> +endobj + +273 0 obj +<> +endobj + +274 0 obj +<> +endobj + +275 0 obj +<> +endobj + +276 0 obj +<> +endobj + +277 0 obj +<> +endobj + +278 0 obj +<> +endobj + +279 0 obj +<> +endobj + +280 0 obj +<> +endobj + +281 0 obj +<> +endobj + +282 0 obj +<> +endobj + +283 0 obj +<> +endobj + +284 0 obj +<> +endobj + +285 0 obj +<> +endobj + +286 0 obj +<> +endobj + +287 0 obj +<> +endobj + +288 0 obj +<> +endobj + +289 0 obj +<> +endobj + +290 0 obj +<> +endobj + +291 0 obj +<> +endobj + +292 0 obj +<> +endobj + +293 0 obj +<> +endobj + +294 0 obj +<> +endobj + +295 0 obj +<> +endobj + +296 0 obj +<> +endobj + +297 0 obj +<> +endobj + +298 0 obj +<> +endobj + +299 0 obj +<> +endobj + +300 0 obj +<> +endobj + +301 0 obj +<> +endobj + +302 0 obj +<> +endobj + +303 0 obj +<> +endobj + +304 0 obj +<> +endobj + +305 0 obj +<> +endobj + +306 0 obj +<> +endobj + +307 0 obj +<> +endobj + +308 0 obj +<> +endobj + +309 0 obj +<> +endobj + +310 0 obj +<> +endobj + +311 0 obj +<> +endobj + +312 0 obj +<> +endobj + +313 0 obj +<> +endobj + +314 0 obj +<> +endobj + +315 0 obj +<> +endobj + +316 0 obj +<> +endobj + +317 0 obj +<> +endobj + +318 0 obj +<> +endobj + +319 0 obj +<> +endobj + +320 0 obj +<> +endobj + +321 0 obj +<> +endobj + +322 0 obj +<> +endobj + +323 0 obj +<> +endobj + +324 0 obj +<> +endobj + +325 0 obj +<> +endobj + +326 0 obj +<> +endobj + +327 0 obj +<> +endobj + +328 0 obj +<> +endobj + +329 0 obj +<> +endobj + +330 0 obj +<> +endobj + +331 0 obj +<> +endobj + +332 0 obj +<> +endobj + +333 0 obj +<> +endobj + +334 0 obj +<> +endobj + +335 0 obj +<> +endobj + +336 0 obj +<> +endobj + +337 0 obj +<> +endobj + +338 0 obj +<> +endobj + +339 0 obj +<> +endobj + +340 0 obj +<> +endobj + +341 0 obj +<> +endobj + +342 0 obj +<> +endobj + +343 0 obj +<> +endobj + +344 0 obj +<> +endobj + +345 0 obj +<> +endobj + +346 0 obj +<> +endobj + +347 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +348 0 obj +[349 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R 356 0 R 357 0 R 358 0 R 359 0 R 360 0 R 361 0 R 362 0 R 363 0 R 364 0 R 365 0 R 366 0 R 367 0 R 368 0 R 369 0 R 370 0 R 371 0 R 372 0 R 373 0 R 374 0 R 375 0 R 376 0 R 377 0 R 378 0 R 379 0 R 380 0 R 381 0 R 382 0 R 383 0 R 384 0 R] +endobj + +349 0 obj +<>/A 386 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +350 0 obj +<>/A 387 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +351 0 obj +<>/A 388 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +352 0 obj +<>/A 389 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +353 0 obj +<>/A 390 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +354 0 obj +<>/A 391 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +355 0 obj +<>/A 392 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +356 0 obj +<>/A 393 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +357 0 obj +<>/A 394 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +358 0 obj +<>/A 395 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +359 0 obj +<>/A 396 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +360 0 obj +<>/A 397 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +361 0 obj +<>/A 398 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +362 0 obj +<>/A 399 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +363 0 obj +<>/A 400 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +364 0 obj +<>/A 401 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +365 0 obj +<>/A 402 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +366 0 obj +<>/A 403 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +367 0 obj +<>/A 404 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +368 0 obj +<>/A 405 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +369 0 obj +<>/A 406 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +370 0 obj +<>/A 407 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +371 0 obj +<>/A 408 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +372 0 obj +<>/A 409 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +373 0 obj +<>/A 410 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +374 0 obj +<>/A 411 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +375 0 obj +<>/A 412 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +376 0 obj +<>/A 413 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +377 0 obj +<>/A 414 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +378 0 obj +<>/A 415 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +379 0 obj +<>/A 416 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +380 0 obj +<>/A 417 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +381 0 obj +<>/A 418 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +382 0 obj +<>/A 419 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +383 0 obj +<>/A 420 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +384 0 obj +<>/A 421 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +385 0 obj +<> +stream +HOoJ%C3;3G*9|{8 u Y HQ)8zͿ| +/fj.  o&QX)L\L5`f&*i6r.7B29$ə6Z/V7x;h.{NBއ;;_7jh:Y7;k<;D6`%.Zv54KU9*.E=M5R%DKdza{Ё;QTΆd U}Z Ux +Gw}R%>aJoeeQ/EI0h-sO`^K%Y$š>"EkT! V`p2P{[U2{^Ng.Y:NeN2g3,1'\,5D |7ًops?nUs؟6;54Dr9*+#V{O=AOG-{s's_ cTeZ 9-W I{E~:.gS (&i n;sK+MP"s%.0tBuTϷ-Sc$~)x$ Zr&ؼ:Y*ё9nN@H}sρ;[[b, +xg]oN}iB2.;v r!V,R Ȯc{ȏkZ S**pgY"b`u ǧЙΗ%t%ԑ@u651+[;WLFeΖ9$t G[endstream +endobj + +386 0 obj +<> +endobj + +387 0 obj +<> +endobj + +388 0 obj +<> +endobj + +389 0 obj +<> +endobj + +390 0 obj +<> +endobj + +391 0 obj +<> +endobj + +392 0 obj +<> +endobj + +393 0 obj +<> +endobj + +394 0 obj +<> +endobj + +395 0 obj +<> +endobj + +396 0 obj +<> +endobj + +397 0 obj +<> +endobj + +398 0 obj +<> +endobj + +399 0 obj +<> +endobj + +400 0 obj +<> +endobj + +401 0 obj +<> +endobj + +402 0 obj +<> +endobj + +403 0 obj +<> +endobj + +404 0 obj +<> +endobj + +405 0 obj +<> +endobj + +406 0 obj +<> +endobj + +407 0 obj +<> +endobj + +408 0 obj +<> +endobj + +409 0 obj +<> +endobj + +410 0 obj +<> +endobj + +411 0 obj +<> +endobj + +412 0 obj +<> +endobj + +413 0 obj +<> +endobj + +414 0 obj +<> +endobj + +415 0 obj +<> +endobj + +416 0 obj +<> +endobj + +417 0 obj +<> +endobj + +418 0 obj +<> +endobj + +419 0 obj +<> +endobj + +420 0 obj +<> +endobj + +421 0 obj +<> +endobj + +422 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +423 0 obj +<> +stream +HWˮ+* %ml,2Fd3)J)_۽dKש"u.|_e|\>qBnŭ{1.A;C町@??tI_v royQ +l~i1ɔ_&BL BQ4|.*˫lAhP#~*"W]ye[cIԒƬkzbd:! BK6N3Y<O+{h^]z㶝~[{WbnyZ97Al8;s%&/VF{DvUFݮw}f%eK~8o1 N_-\&bDntF)$@jF0ᮑH'ӀgPʣħa5HP `,(eܞ$Qr2֑ 4, 9^lͶXvfS%?`(aR(NqYaGՏIG)tky/IcLk0QvY8 Ũf0dP^|(B0 T}nOG!˯B<Xj KxQC#wf(5 AyYOh홤FJ>;N V: IᩩUdLGs 5Ow!-&nQ:sH +\vݢ:zvDmI3 SU*yVWJTzN]^KS= W=,>Z6{|zշedɇ(}QLbEC IGJil[AdiWRp;ix4>"-KV6Z^1aa:RI%3PU +35&@9]Y1X\GI4p%*mTwes.=(*meS\qF1>GaDp> +stream +HWYw\G;fFmFYȒi]e[lɖw'ccX Ί@H $@!b xpCxt\$/H[]uuwus)wх,Y>$?|z1s^Vo?sKE^:}Sw:wzF.1xp.@L;k>q{?!&/Ln _ +'N>߯ЪeÓ|ǜs?8].^P^s./ +Ū"h"yͅ~wKjcv 0wmt νyuRVW4zNMVir2׶#q+gJIڳ?oHLX~UTƪ^\; #Sw:e'tW +YW +1"zQQ4D%EcB4U4ј=cJ,is0V2ƌ-0ֈVD^z%-z+ +]t+5]Д/FRa\lN_sRT1ZDm:łJmξR{:JMp))bRJ蒢[dyRKQ@B)jIQ+E]Q>)K]"EnˤhZ.E~+/EbPY*AeTր ZPY*Ael@elP-T@elTvnP*{A T{@er/C>P9 *G@r*GAeTqP9*'A3P |T΂JPsLʇAAP@aP(\G@QPy T'@IP\@ P$< *O\ < *ς@<*@ EP*_A%P *_ˠ +| T*k P&t omP|T*AGcPyT~*%P*?AKPyTʯ@נPy T~+T;ab*xK+q댏׹=6i!W``e@v=6g[*EnFz'9ٽ5VOasѮ6=ڕ02ԣy9}##'/"`[L\k9Uw```kE+8"X X" WX]9bMױr`+' oiú!*}IsgtNk̏:;Ufzn>c4HC"X(XD[;[1{3L!6;c-m:lc6~0^[i_Bv\Mi07B̵24mU &5Uyٕ2v6[IN޿î ]Dӭ.vyw\vzL<0~؎qb=  m+q=Y K.$9%Qkꓦ +agvxs-4mڟΕ{fWui3;Y8r3Uml>q 1cEJ{Msm82~=Ozn\9?yu{~y]9cmm{g70SdNt~HaTal=:~C2ĻV^ w:ҷGjؕs]`m@fpS8|om.x]?I"wވ2M !tߦ Kqoz]lŜI=<#}]C_mxO v 6㳔mm:d1)P%3+lXp,zp~<7\MruQ6Qϱm39j8[g76'ecQ33tn੃8Qd)@ĕ% +GH< $ޏ^S؉\,]Uk5WDGiǺKΤ_썏IVzO{73ϴD'å}}-нSK +>>Wx o7+y-6Dtlk^3 6yϋ#y#]!.v k}/e\W<~gCp?U-,%Imʚ#mST>xc6<=U|#o2P{]K;9D#k vb ɾW 9dx=^x?X_j/iV:^ DR\'{pylp!yooײ6X|_dž> 6m%:lMƙO?Bvf)+F|G:ϻA|?~ݻ|+oQj* >S Fgok/36;-Ԗ֙>Cg%#D·(JY/2<QޗDxגpm#|!czLz[>E?~_2RoO}&x2+Hoo#}C?]Z94N s`] {C;4i##:ܓmFsy06439DZۚ@ ] J[k+pQ挽s;_Nn? qaRxs{?^psI[GM@H4{SQz8JތK AmRxԃ_IIZ4NTz̟/(}|N ggx :B&'Ŕ۵}usE_zh_xba<q]&}Xɋ(uk8 +R;řح֡2㶩|=շWT^OEû^w+ܳ/u'>akDOt\?{ /y:]Tw{Nyٺo~6VaNEۯhޗ⻩w>)9?bX׶zصo.QTk3~u@v?4ѾQ%;zr=xɣG3w=5}[яэd0+3{΢Im=hnEFl0OD{6a3N̾}A3q(nߑ0/Ex+&!/hV\@6뿣̄?Sr䏅C t֏2g~W bcmٞ6N"J=c\G#΄ߏ2WNM8Fނ=;&[}h+=m/~DމJl9ģx#s:xrNEeo%w%8779Acyn flSeޣ71\|xL ݶF?3ؼkl2> }bOL+[A ~-sdM?dnalmպ_$]EDI;!ю]z25C/~z55uF=LJ(3wwL}ּRe LF#_ +s*~+㷈>k/ϥD;&Xwj=pg;uw1[?24ghtۍvxnǬ0Nl͝Ab/k*7ci=3 b#`lvxE+ADԂaF?0 +L]NZLjﭏ5}ŽgyXm}W݉(5\Ss |!hoz>ߗmonhFݎՁDok}GmpJn=#8H69qUNC|IrKeώ~Dm7}Dgy ҳэ9735]<[\yke_/j٘/2şhѮ1z=|94^{:ڵb"! >͈ jkAu62Fs[s~c<)a8e1nc`/oF76?.J<2OD| +pfwּϻ5\rLxwB&J,1=yeNHIcRr,J+DQEo*qmh>;|ek3sYؿ=7|~E{c:J_J;eM(=6/.9wFOu;Q:ߘOQpbǝmo|ፂg>NKF₼: +8k=OL@=>j]i(3ñykQm?T4F3mc|]橞Y}07e$Q\g0$0dB6Y|=̌ _x$殩ӏ>iw<{^hxtE?瞵^=;s_&syۤ)ZOou,qӉ/jWι7oD^2Xbbދ\9`7tKOs>h}-}ytA7lk|~|S z6݉;VhXcKͽVg?{wX֗iwbP˺bE'M.s,`^]Iwjq'Aoogt")u6C9GѳzЍ> Θ/98c;0˶N{F茬|˂zi +/zN21P[]kK\%l?J}^{WjA*ƴ}gyλvx`3Xlt4. {#% tM̱C}#vX66Y^.A{x/ͻczA쟪s^HdYw]'PSh}loDzs,ci+۩=}^>ױ+>i{QV;};fk2]/lm,mXOqckX=Īy!ڛRdc5x}Vs|';`|X<19y/kp*;)雹瑶?xJݫ !t}6"&2~X})!-urO$tK>+oyrXb|Kʫ>Qy|q.:ݭu՝ ?}7>h3g~[VfߛXd z3wb`%8x)F7FpݧA1jԻ/a/1ewtƸθe `Xte."<ﱇ0{,=DqϬڸ~pk ?AҘws(,w|Sx=;9=o cuZߩuGGK+՘yϣx:M,3 ʳ-[oԧ}qS::ysbYS}圯ua?|5|+u|mחX$ا9-=6qm#tֹקh[>*.r6vߨc],ó(z 9{Vөc=R#=%N<$Mch{{o+k'yǞXSC2/ 3wսO/0]<% 3>߱]ҡ%9KurnfkEX⑊M<],uU߻;!o}G8\ְ{Sq0ogރ]}M,xczg>4̺h, 9~bo +/З]]Kw{b+K{rm,&1${9c½o/~ƴĕEw3~$u4.w?Xƽ8 .Ƈ z7yNZK{o[hl㙍΃=W:wϮ鼶y+݊ ǔg5[E.ۅձ5Nz OfS4ܿ)<]j{qOdX_Sw]I^?Ӌf^x??};,t{/+Xc#>fu>Vٷh}*mzv}M'|rIvguߋ}.wgPltY=c,s1nֳ߱&x>?4"Py~.%׼(Ϻ|ѻkKO{|7>3Nw)u&zjG8uݔmzE|L{}sF~!F"~]qe?s,t}ٳvz?缾{=rMeWcw%gU:©xq5~)v=|_j:y},$ܫ<\Г惃xQ2ȟk,kzc,m\\KwO>cYS,kT g'o}MfpS:/ &G 2k/ :5Z8~~L~?;:8-o% DZnѰ=2?f޻Y5G~C%ia=s;=sHEfɊ1/ZȟI4S὆VkbqRߍ_/{R"wO-9̋-^ԋzդK{{J}.|ݵo_ 5YW5iYI$v_&zLFj.3.ګsq4XGho;xYcbY{Vz<t筡Ɓjv>sV|bE֋YtBƜ +m#\x;%^[;w2[7nEVVwOo'1YSy@/_K!%_3v`&6qg-Z^bgv}L摿})Rd~}{S` +ce[Fm>tgن9uνEw,RVࡋG_n1E*7 bwh;[$|%>dl(Zt#<'2_xoq@15: k^cE7Ѣ>sKE<}ƾ >ľ^ӂ[YYW|H6f>wOIgIygJ4ؖg\/Vy7}.oyM~ /b0EԼ{{s+EGNGocG{g3=}?KgRZ D;%b!s;Ym03e?clgw3gy~tDs?sӓ8f,|F}czѽÓw^[x5v?!+O-g1aqz$ z-/g{g +6d'7^w\c4.6'GS)<89_ +Qgkxw.QM?t܌s)Fɹ}z_?GG٢COE]`Oz,ݷ_<~pRX:`Gs"qZwmfq!!GkǸX}"ݧw> 7;J'9w!6仁 E#.~=&1Fzc1kJou~?\xIןr"^^ÞVɫURwy3ܑ.ؒԔh\]%zΜqxVDLƜY77 u=9.t\VYkyy. |_~}VhXLK{6?fssw%6s?sW`,߻\^nܲ6mw]5w=󼼿E=85Z$90{؟wֻ+}9xჵ3sbj9>c&3o䅿K\?Oc3Ϝ؟ywU8}&̓U7t績+VwWΣ=os^Ϭ<˺a%Znp~*~~{so1Ž?;I~J< ك#aFC_ANxnۈ3|w>F-2i:Ojb#M1g ECGԽ֜Xg}nH:_G4$^PB7AWW'2'mܜ/sdISGfI[ޟu>VS:Ng-d9O>?G{wsC'g}Vgh>qǡw{}x0{?~LoOS|s)lFopN^ܛqL[y?%>bhKaK97G_KzV7ء#l:!v8u=/Uϯ~tvϘglL3GmڑYkvLz%6xgq]4g#g /ܣ9=wL˽;>E]}pMy>ݗ97EsxbXhC9w˃bx3{%si3].9WY=ܼV+1y}F&z|V]S= 5/Ї<{= pM%VP2w9joﻇ s&˿&^@&#c֝<}79=Փ⣝s3&98~m<:7Fޣ݌~gQK(/ٺ~F6 Rok _DG==m;4Gȸf1%9Ƹ[tZ}ɶdl]'yS|}٣a ,9 x9hY:v_}-~DrZϜcAI=3[ʇe|]'}\BcPnz}=wX i!ZU|nMy꺳?/kc>8Ivy>'==-`#{L||1ߏ//hGA/h2xLi[{{$wwGsdx,tϴs:^`s@tem֡Oך3g$wQC:wM5F}Μ: LJ nv)ΎԱs|#}߹eSs3{{Yϕr,5?'~05I2大;Csǧ$zV,A-XeGy#mNbMLU?VW.G}~?֏?o/ u}I߬_&)#5=3;ib +sƀd`"SXB0 +@aWη;Y]e#guFA]ʽ1~|+.v6U-bt ~yENӋph۠},7qv]MQ76ҡ=p{4 =RVO}f.d~RhMŌ̿>{[o*8k0֒ihX[S7!V_Xp5C;2Vs,j"dJ|zB{-峮jn傍zVl:ό$O1tye=kWam_3ͧ +0 w1v[z33.~ gKѩbb :@%=tguݮ]=sf>z㝈\.͟ebk#UrKN(Ͽ18kočl둒[cN~2k}߄Z4q+s{}]p s +;G]וyeC>_/yߝod29iay0}?iaRQ܏_scwɖox V<o64:y>.7 +5 wŭ:\C% 1OǮ1m8>qZ|qe|y>-+nja9;JmoP/Z*qJf-eNGk_0W0?}1xf׺ksB;&e\JΞy'){0s_|ZlR +" cIWh[ͳџz_{|Gd}1xOgoͲۥ˵y}o#N[>ڣ/Bx%6K,̯˳:ݡuX[0io7c1ӭZoHJ0TMQs2Chqy6=v6v6ۯ^ tF_υ7|=Cq=`~h۠g ;([_c:>&{;߫3-$RUsy.y}~tBt>JU/fNxQݭ~AVYuE㝦˝I>o1`crǀ,.= yF?&6I[F`|ƻd-7>-??~C`*/<l~nm27Hۿux߿5f l_ƀXl! 2ڳ6'@p8_PJFɋMft9#&/6~[`F) ._s8-gUf~[Y4ƉhVWm}'` ̛?Ӿ[ȝg8M.鵽ü@oa lOh{/6.F`'2p&@w h ]{WtBuD'U:8if{Lu uн/]:>q ƕo[k xA} 0~Ms5|.FзIΨtG+=藱2hT #yxn(ͱv܊[1x࿉}4U6@gN?k}Nhbx#oƱ6 _=ћh_Bj78`57״PisG6F= l5W9hչ> 랮[C1ʑҲTEsIqZi{*K[})| +/SW1LxI3Ӿ?w3p>ra/ KMsWXr5E{Ů5MI ږ{[kXk$6K.jV-:heƳxˢk oa61?m|-3ֿdSu؞$_H:zW*}}>N_jbrq,{t+ VId57%}7IOjgjjV'V3эf-?fZgsm y-|5)غt#{˿<ڝIL¦_Ok Wj(~':&Т|=O+i^=95n]?}]3:ir^}S45ZFy?^7zo-ָN?0>S<=o> ݬu\ꞚlM4.{*1:pTy8MJyGVMd,|N:"\hlJ].`-y+LXk\NSǖO >4FއZK oQ[iO贞\ߩChw#W;j-ύ2> .sE\*afތ90ZL0165g5 -=Ǡ:6v_v(_CнUlnk˸KaKʔX!>ɤ݃I)9jz4~\D(SC6O<ė#ozq1jrwh㩷es9a_X~ DO 3^$v<-vK\13_]Wr__.Brp3 HB$!pE BS@(`P0`K,UNq`hg*-N;ԎE;hGv~~?3XϾ{o߾}S?=wv!߳#f1?i 4 {[:vo1ƴl= '^S#cwj, m&X̱6!?p?$y|7l^Q?2QZu=5R;^OOF|WJd{ h5& 62x?Pm4zߥC,sL;Ӻ³١Uݮo+}.eRIԝguc=}YѼ>ܧ@o쾠7ڟQ[BjHgE'3iw(wcd\̝\'z!{δoԷ-sD uMP yoT4<nt\?$]+Vxg(z*Tsw2>uowG%琭y pF0Gu)WCQdkU&{0H䮿2_a($ܝ5bEcNR w˃7`ȡZw>~OU]e0k\M7օ]Kf +ϳ枞&MP[kSd`'yi>m=+aL +I&ZhciݰN1<}>=$'dcm!&?LV2]1ٟOM>]+e(0:N]~#}j*]qS~,X.\&`es8ž2ښ +p<͢BvzSڟyQ2WAZL{3 +j{p'0 4sg~k3p"]/2|i蝔lt A1^:lЗߕOOw9wA<W1Y3py-6&Cȼa0~NɈ[6/o3' szM7=KM? ?.BEwx:s?g%)WcOm'7yzoNݠG@OBЏ_ӈ׋?+S0FH×v.[ ֘ۮ~)F|͵kzݏzҹ\~Yuy!sley:4ce-|o0g;V*Ù9TMEvڋ} 4 !5h.m^;r11ll߁V\;b~< XyNDZ/01:?>v +ktzN--ӊu h*b6C޺]4\@C߯ߊuo]KC{/d + +k?ȉzu^!I@H%_y @o-6v̡[1ež1NV`? ?vf}2 +<{Xiy s؏xnao| vnv~-+IEicd&K5*mV9b j)}32>aOMn0ѓ#u+'&C^dKkS.=Z/W1Fz6:MžŀA1B4_Dn=j\G1P^s{Ch[A=;{ؕpv*4uuL(kU^|0.*>WF<2b,媨;65W.7("\i=114h_OѻMK551t,3rl0}(gZ#Ẏ=8NSR} k"]y0WMd/1y_H_tOs븾k2d*a5?t;4D8󘹼MYj6cFl3mf[ᛇHAhGӷM^hJ@SX&/jk=P +ȗA'R}PG"OJ92@xX)uD4ԍC3v Q5hnFSUapEJ#V&?ZFI Z+cȏ:GAe2I&o2%p%h-D3;栙= ML4ӛLM]m42CK/H$Eϕ;d2_摿SBw]r, ۴nXfݣhYfhV=f +4˗>ul/\U 5Z&eyD֒ + +GU6z@8}uϳh4];|)4ۿmh؂fs:8*&42ZA<6Y6H +!ȶE!Lv'Cvw$mщSf[FVjjʢT{giXNb,%L4i% 6J4Y地Im["ڲ-6LJV?ics>1-٪vUE2 ª j6nEUu|fDXd-ImEmE#:Yg}"iPtΌcgΊ5'+)il_>|Xw(5U~ѭ+S +yKl**S#1UI3Hg[Rc,&sf֓n?W:wwKܯgέܦp[;j\o.rnan9j[~;OZE'ٍߕ:?'3y酹N?jkn>oČ +endstream +endobj + +425 0 obj +<>>/FontStretch/Normal/FontFile2 424 0 R/FontWeight 400/Flags 7/Descent -140/FontBBox[0 -137 1000 859]/Ascent 859/FontFamily(MS Mincho)/CapHeight 709/XHeight 450/Type/FontDescriptor/ItalicAngle 0/Lang/ja/StemH 34>> +endobj + +426 0 obj +<>/DW 1000/Type/Font>> +endobj + +427 0 obj +<> +stream +HTP1n0 + :H0AvW$PS-}%IЁ$x᎔#@9V>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +429 0 obj +<> +stream +HVK6qhOT@۲䐐%\@~}$f`nҧzH0|=pz~;r'. oӡ(/_ +~f`.> ?\:F$ƿ>a{ #D/8S=Uĉd%yb; .*Akb)Yϲ!,g#1YقJ,Dcm Ɗ#H1NT?" .H<Egqx9/*[vf)^bеV<:~?ҡ5ar{PurJ"P`1%S[% g0䦰9}B"Q0 L]6nDPA +/"er C2%WS%*m3P4OY%X6ѽ)ie%C80ӖFGanM\ 'GmAީ: ) })zHkT/0Qvv<Ne*6\hQG$+:lOF$"PL[ L/0hNt1dG|fq0woZ4kj+U1*iR P$-c+5~۳=uƑzo-7be$eU=}L)8dkeq5!JbJHޔ{ζsiIpkI\mSè[1,K=Dycߦtmnv}-u+[iQڃ:>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +431 0 obj +<> +stream +HWM6 ϯ1)^E[[ڹE-@/͡@~}IZ$MÌ="G +.wzy^aGb k^<@9qLxuy5럗BTm0CI "ѧ8'\0{|߽\דF]|B'ӭ{?EDMp].OsqP0 nY9B.s X*ӂd{'JUΥ5zTj6cǜـ۸ &݄MÓ%@O}um׺mr~u- tM%.uJ957$?xb%g^gOR5G+hN#Ƙ>8*I * V<-m +Yl +uR#Bk-b=[ +AQYn͵Euob;.x$zT 3pZiג.YOSQi5NOmL#FVem-2KTy'ܛ+b|g#AV,ou@ʡ؍%uwIMs=[<(v`fn&v_Oq1o_<HDf$JJ. (3xT/MW[rZNoDfmP [}B\ dp6:9mB^ŲhbHGuf)KDk -w*ьޙ0&7 +eMmo4}MdM`tfɓQy 졽z[iJvD_~>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +433 0 obj +[434 0 R] +endobj + +434 0 obj +<>/A 436 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +435 0 obj +<> +stream +HWɎGWP)2raê` ƌl :XzVP]]$|l>4Wx ϗ~yuCۆAG7wV[=7HHDbԆ@KuI1*@F>FN$]@|G`XCbeeȘc%3kNMYàk4dlUb}`ȭE02K0s{Ʌjs%0LysaRc4b-i $&ݚ@%+)bH`GI/6W#^XU*B/֐0w!ƻ\&i6 &4\?6.ӣ#4.cAaGNKR@ ŭMQpbEއ"Z*n*TJЮEG:dGŮ#{JжJKғ{00!xg$%Ŋ/r3r .`SKlarZF5ZuG^n̞%]2L7맩5I.wE CN.Y/IAH+ K"IX\t0G˜8[21܅ .\#F{QtWY+VMRk,҄r"21Z'/I 1IA׈!Z)≘+"pPE~<þݱV@+/ڍ πm!v{# `kR2VW Fb`g *Invӿ.=a0[`.)  m y]*#ĭ$YdN-zU`)UQMm\cjWgRT^ٜG@y٩ڑUhR2orn$ן'sQbTOA&tͥ̋'/⮝oն۔ȱHR3.?#=SBXܵ2gg#)ϰyF J\ż2Cм߀!SII󌣺jvǮ-hMUѡ@41%]=JS骚XFHIe7n4q=Ư&v-9n8FVL^{?^O|ϧj>1axFM=𴿴>GRJn`u-( w@zir`rq1gn?[Dc BS,;~}9Pi4ig0Tt]w)<> Ng9}-\Ge:f6C!@7'pp8-?S'u&^W-b!Q"nF> bއ,<|%Bʗ>CS7g/'qk^c +=r {8570ֳrwL#:]}tk}T hy ,͙h.l^b7,v5uGf- + +;wfh=sB&$t ~p ᗈGèb=`!{L)M c[nkxm..f6ءr;8cdT +KN?f={1L)+cFq)]H;ioy=|wxzV~yˤA (-|M"ʸUӪI4ЁXy.w;ѪL>Ѻ-U٪9Oendstream +endobj + +436 0 obj +<> +endobj + +437 0 obj +<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +438 0 obj +[439 0 R] +endobj + +439 0 obj +<>/A 441 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +440 0 obj +<> +stream +HWˊ,WPyz |n0y0{10 O(Le2EuU+ND~^>;e||zGI HHи pRg?Nj7#w_~*$5~eړ,dEoۡ'BU dZ :̶BQ PĜb))}5"Z,`#E?}&K!D9,{R1Q?xk$L۝_g`rK:.mÒ%cR]QhyEcdF[IU3eӬCQN)L^ +R&3T6&T( _zD]R6}HuR]12$FP9қ`|9Ȭc2V&-WV~b8O3Q +OXd)&~$#ʍneXd +N@M:9BٸIic=ֆ KS1{E|lZ~h(yAfijWH6byc D(,єh 7q`c.^+# K =pj,Nļ^6?hc2/pyBj@Cק^ q4rsw܉uYΙI<5e71_?8t+ž^-2N/G-YDꟇlU%VbIR-Nv&v/".wբ&|DPFC=Jh'*w[rr/<%ąQJ0>=?7\=$)C8ݢtQg҉ 0= y4 *4%Z'xFXV+}6rhR&xqmSq͋wsu0cy|k6ê? +'~S'Sh !Qendstream +endobj + +441 0 obj +<> +endobj + +442 0 obj +<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +443 0 obj +[444 0 R] +endobj + +444 0 obj +<>/A 446 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +445 0 obj +<> +stream +HWɎWS jÀ˧dƇ/Is,tU2c_n}_˭>>pFsy|i?&moj,i^^ixYۋM>6Sk6& wvFvg +cdb4&Rס}%WjT X] iis M["Uƭhg ${iY|rw),sߛU8D|?kVjN2 +Rd톢5ި6IZpU}Q2 +i^$@CNVMK +"{QW}8+ƮԼ2ch}ݍ6=q.`OƦWν1efw6v0gkŚ9=nW^֨ZBo?W8n]X$ܶ.EfpmPF(AU&բNka(¢[Vw[-]Nep+VJlp!])RkkHROf 1,tJDW`fsΊ.(GcI"RNpc''jt9\ꤷIGmtGt*.Z/ϰ]c办U'V + B=ALC]e nv9ˑɾL4 dRc~E7BSxL,OlF##D]Cd+@+dSN/r4CdQy +֎%[=Y*uߠ)Y˔O 3H"iiy|-<>o9dBV{8W/9@-7<$1==P F*6(ltq"GOy,oEzTA a>_pT (9EWI (N },jhp6ϚhD:?0a̗u6qЄ?=)6c8diBZ4@Kl99| > +ҫ S˿ + #6it s]\HI[̼*kj>/20f;Lw xdml7#SkK66 z{av?d݁)2C_ ~`iak/`KTX:#nr.iuzal~_ȫ[VmFbt.] %p-Y[. hVUORnn:0ۭq}jw1!i~~(5:L#JGƝ^NS0~$ȷSc{@Ƽre,u%ƍ %?.PZ.S9`+œ~m/ Yٳ\#4ꪀ],r tTn&\ 25X _kcd@-Up&32DYf0u ՃHj%k7Cgn?NΑKBREW{?i> KFVxK/OD%3c9%zT4'{IBST-UT92p1Q85(78dpt*c9.}|q^•:0:Ǜ==;)wՔ)u)s#7CӞHy@,e'TTOTr$_8P +06^(fFz2Ϙ?BbH@2录2SҒʓ;.ls`ġ+Ӣ-I ܫ {(EOMϣٔ]Gf&HM+1$ߒ8;~z{XTs3*Ĩ'>fd?Sm4O``gϠU"KeU%KUjסz̿ښ>mغrC%&3>'W|L]endstream +endobj + +446 0 obj +<> +endobj + +447 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +448 0 obj +<> +stream +HWKFϯq7aZ2 8vrZB1 bSUkyg4v׻J5OҜ޼}VOt9\Ti.\?Mo 5vzhד۠Z+4ކ2rϪUJr\~5pm,7ΛA8zG6Nih5'סA*Z6`@46Bz`?pv lcDO䰸 HܱGmٺ[$WPaQ=QA2ٛ/Jn֛تK۷F땪CBT0Z_*aaP)ť9G{֑֭r ҇J p~Z:m (jR84re[R:k{5WGe>S Ftm +qY_ܓ QzOZ(_0O z,Y */|Iu? }cJ֋Tt+餬"^oˠ6A+<%|`2X*M!rUG Njhߥ*^9?]>.p5ɞ$) 2`﷦,rp4$7 ;jې +4@"րK B׎t>9ӫ?Π#kUI*0v&6jڙs=)FH3J!ʏ䓴*~z=\s1E8x̶,թ(\,UvX ع>7(VQr]C`)LF}!6*,pϒ=@PJSn"$bPڧ_D%h6~it=(-WҰR#^)dimDREf]b-̾}~wRh<;c5\#/w25#bx'1& ZZ +\7w|–7!`&[JF +<}JH֑&/A=VHI?pko͗U:u+hƧ5S &X-ӢhGLw2c%-$>sci/4A-KNxͭTTd j@] bZ?Sb.B)l8q;%aFm[,;@WAxلe0DVG|PՁ/wX+UjK/{I?GWlYd>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +450 0 obj +<> +stream +HWM6 W-)RX.ks[=z +ח-q;&qƖ( ??A]O/+4\?As䫹~mtMߒj4n>5]<[>-^el!@ĦצeL| s3Y[vЬf4+b  c{ʛWRx F,0z*S z|tV.ER,{ކ]o"@Zib``@FCu>$: 4A zS,0p7*}ttJrLtbY֜U#LC=_{YKg] +(?I,IFwV#QX1%Ab0Dπ =` Zab!"4A5+oN'BC!+3=Ra"vGB=L인Rkgڋ<QHoP Oh`4  -}^<JѾy*D#\J Y-Ԫϰ z᣸|΄tE`09bSt swWg]MD^V%r Z% B'Au9oi})[k;^(7(hesw塊,, Ug%y?3E>aŷꩃɚ7fZTJL/V0RTR Ja5Oa^6H/ӕ>2vs"d([\\NʄN\(zCւA4ڷuKh y 8Ręz/]Ϟ`r%;6dS3y(ɏ=>+n*+EQ׶'*,GtaH9vK jKXmic))A\{PqBr`S&a`=&)*fd28v(镩*%tbӆBjP +haܨ;ɮVm $.o1{{kwcY0|2]]<}#i`G'TL#,v8i/Ϯ(LĮffb#y1$1d`Ej(!*`QG^=[qB7zDyq׽9G +s)\m}ְ^W9x='߭P^endstream +endobj + +451 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +452 0 obj +<> +stream +HWM4Wd9{R5Rb't4  @b[ s'iv:c4L~{LWT/C{9<_.Tqu'e.?VT]br*Bk;iUY>LuT_Q01l~'r֟'- -QPؔطI>qE&ӜyIљB(m1֓m-Fs옼/Q6!jo,(DK.v}yEq4(vV GmNXݹX&g̩a;d8]2 mͭ7=IqMg={46뛎zQ,Fdto픣*:.ߍ:9ךeu:u׺kSynpnaĆ;q 0 RAkфpV-Z(mثX@ T-xnܚԕ}ˬ; 0nY"%eR+(=7 d'rȑ@M|O*pv⨖F&6^egLwO՚NJ@"rl8vR:^CNV݆S]'խ}n6h>(eAn9=BqnVY}+aPcmb.14L#ئ4&qgсFN`SӘRܵGAGqrD:(od:JuMfT-A15,` 1hSk}r4&5۬sGH"XCĚG=ыS:h: XC>v ư?o3{j\Pi{BWʮ'x:q7eWޙV%R}'#aQSZ@ +/р0r@֜%R_c/p!=HDAnTt4):M,UaZ nީ o ;/&ÊVi7r뢸x7`ɈkhN?ˢJ 2bo Ϸ #`y!ó"Uyu Z?a4{ěRMzn)8QjTyЯE^Y/$%kz*H0h @Z= y^j+.(?LeA +.=^֛d6-N5^'y餲(;}9s*rv7‹ȭY<Ħv˦( h@.s惷F'WC`o/;Rendstream +endobj + +453 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +454 0 obj +<> +stream +HWM6 W-)Q_@0%ۋTtsa.Z@}IRc2;=Y"I l~oO?@!O34؜;@s՜4Gj?ɻV`-PsH"9]cOIRl2[mMh-yb ;oR|4'r!R +0a g|>ٶTsTRA}+8L,,TQOls9HtQ\Cf':)^ucB^;4 Bnѐ.N~@rZx͂+P sI3Vgf :u`ɻ" Iy%Ť6K;=O#-HT!ap5db[Ha{ٹ4 {,l%'k=eОEHWeŽE0$J B "1Leve9l(ԆNb]LE +'5rk]Z&q^^0xLk%CGA$W?pIP8tg=sES~aW{0אZ5:_w!OrnO^q +^n5 +vj}e1ouJxc5bS?k/_PkbRk>B SjDf6W0QT,!n:؉WкEAYxԮ5v2\y*ʿПyŚ箝$ٰDި{sRٴU6Z{90W:燮N߿L{ 0yb?+0CJ9֚W]Uߎ *7||Dc#Xs!aW*kN=}n +tJM\vMH1&ǠG.ڽ`m~MVC.UmɟKuSu[`K{SɻK4$ k q!~eFñ\]3X\9sU\wl\}`*HY kh}WV,Q+\o VTʹiiN][X1hcުB#cEIpil$^jl9LP:8)P* +嫉 r+@r7Dt>3%)ABi?~pVFKT}OxIsq,(5P2˷nD)7t8>"d$MW:Z#",|9(٭f8`]endstream +endobj + +455 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +456 0 obj +[457 0 R 458 0 R 459 0 R] +endobj + +457 0 obj +<>/A 461 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +458 0 obj +<>/A 462 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +459 0 obj +<>/A 463 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +460 0 obj +<> +stream +HWK#Wqր7 K}n 86 UlVRgwl4#uWϏ*~</vz'n@Egpua2h_5*p )E'Ӡ|/r ,?\4~ ezF9`fWQ\&N]mwu FmSq}^SQkRF!/Ėс +ZCL_uF/#+gCODN +q^\UlC2sjW~h l3ܜ!ǸL$%_XUcYB Nj׭J{C> :z7 wVVoZ£*dJ3|xG< R鮑9'g-u/5;MUa +j`\VuCV:VviӠq|"S\|H,H;-YR,e"i]q9(}T*x /w6SQm5ؘ7D$ :."ҵA5}WTRj_%zE#>LO9drm.()0^G0FVaQ6iVy^A"*m-q|L9E:̑:ԱGutԑmVTd;@KU{:R{Oҷi"mwU*v#(`y6ƅmMD+n8':7ӳ}ĉu[eoW3%JקDmvV"תEkERM ojNisuSI;)DZJ)mr6i7 2XޡRVǹ7ÀӘ1*2? 鿳Rwz|d? 9A,,v" #jߩ""6Dnm{mG v(E$bO$ٛ?~]:x\̎E֛e sjCv֎*lT;d̪ eiI6vǎa4 +٤"'У͝&; ^'a 9:;GewEwNs +vLkFa!=}(Vl .#;<=Lm\M1TajJzQӀc\[r9ue g> +endobj + +462 0 obj +<> +endobj + +463 0 obj +<> +endobj + +464 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +465 0 obj +[466 0 R 467 0 R] +endobj + +466 0 obj +<>/A 469 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +467 0 obj +<>/A 470 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +468 0 obj +<> +stream +HWˮ$ WrkDz 3@d1^ׇԣZUM]E~P,R9ԡ~U/?6пп?:DzS,)}~xvW#6G@^?~/{ Fgg@&X2w?' !5!6w=״:N*j aE=z7xG5/ sk yE2գ'X357ڸ~Lmz:1^F1莫QfX]!4VQm0SЎشNeuF֜d+#PE(A*2 JɈ07 -m6\^D/M/٤ etl&*Q/6\nWTalF=6 op4 lr D<cEc\jZ|=>rt `BV,f]h[6ynh/[MTH1~tXA2OS~s*-M2 K[JY7@-t!zVDdWBD$&T"@!o58&{A&\҃dߚlN'|L淙qgKqJZ3p<\`ES[P3zpÍ?CtRAt2Sr͑d<WG w\ C6;X={/"gR̊CTj69q-U(N\4ßζ{ +کCW\t##T%u_t1@yQzMv &]wHW5]wqӾ}]N-H /&B ~؏%8Y H~g>M8*ښ*1X<9X$_juU\DWChR1b\]Zq1j1޽zQs.< (HXOL?t +p[h(u!pB?b:#ciK{::[DDڒ 3:S)Ҥי€,cX[uxm~/ u*O =ˢbu y4FKsm HO_::ѓsS+zN85HܵPKET7!j&#wG)G.}}NWH[kΐ}3Cwgݚ X!]~+J94d6y33xvpxJTAe*A k *`8\pnkMZ3#;5%)-t6pYu&Z@yeb|o!AXW|mϩb OHXW_ <,̺qN/OSy+e 뀜Mn/:gƋq)dEx"\f*K*jK~5u:i@!ttW$ yVnx ;t5؅'֚@]GmҫoJ>`4)v]Mh̀:y^M6 +~I3Qmㆾ:O~= 3u~xԹ>U睭r4͇Yo&~)Ii_qSHrRl@v}7jϧL$}Q S,BARs͌K. xH0Tp 4K;??X󃵎=E}`a$۹d{\髒;iIE԰p͘=Z[Jfz湎:I :R3=%Ȭ݌‘Oy)_gQ eԴ8)/8RDW(k߻ sGΑ  j!CltF f4iK&VdRbnkГjz3'_x:~T#?Pkٵ-pev. #jwaU IӤOH0v78NcЛQ?Qf._ʽ4v0~N$ٝLJ/ܟ?f]-;dSBJcaH4)1P[w*kL&}D??ߒcl{#@],w OǶ"_)|UJY_]Ay^:>^y7z^x|.Rs"@% 8%#z&\wmCq3ØiVf3ʇ^4NGqQWRSǭȠ!· +e>le#v,Zda<u::S/6o } 0Xendstream +endobj + +469 0 obj +<> +endobj + +470 0 obj +<> +endobj + +471 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +472 0 obj +[473 0 R 474 0 R 475 0 R 476 0 R] +endobj + +473 0 obj +<>/A 478 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +474 0 obj +<>/A 479 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +475 0 obj +<>/A 480 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +476 0 obj +<>/A 481 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +477 0 obj +<> +stream +HWɎ#G+X5  ( f[c`_?- CUh*I|I2T'ם>?p?}U?twuwS]w?_ߺw@ﭢ|r4ѝ <{Exz(V)?.]Ҏ2ɱ5߂08MjfRif OMo:gCM|O?L[oH6FcHo{+$j$*{4S<PԽhCezd6*pI" [잨.Z#?8*8RIͷOFdx PR摢j iRnMfxă՝Q]ӭ4mϘf3)ǁ% +29Ur K `nNVo_+kS[=gnsvpT|x=jj>DSk|փ$f+djIAI.x_BUov@d Ϊ$ +hmd$N&е9lÑl5TVIƼU< y[fj?5j,ŬӗvVS7a8Q 0@˹xH6yvǓ5r3VOР+M2I9ڜ - X\cիl)\lp qDAMҀA8v|=)I,k8/v+Ӗv\cH9r貰 y8}hT7rTGG:ѿSg:Y<YUCx_QyZlHeVN־}F?C[ŗ͹_m1j9$[lt཮߂ ,qoK7_UQdJ**r5.F%*lw/6%\u'ٞW;*-߰p~yP N+2E9ޔKzq^HDbÒb@9 _"9jzendstream +endobj + +478 0 obj +<> +endobj + +479 0 obj +<> +endobj + +480 0 obj +<> +endobj + +481 0 obj +<> +endobj + +482 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +483 0 obj +<> +stream +HWˎ# +t\L2FdWf>ޅe`_oj)XRbj(*dEɲvn˟b?//ݻǝ_??/{gO? Yd<39ٰg So?~Ydl)%}$7BazLZ_+J Ol!|d|K9F"˟w.'3![3?yv?^cy?I_@ 09yE tEDMԂө4NJL +҇bB4y`QjuqS8ǔ`ƹ ?zqn!pdϱXwwL9™nJ xhe{gjd{̴>:0NdO!l[YM-R_Ge]H;ˡ~¼d*6+oOt>$;c Tu TLЩ pT&qsJ+ڍp +wDUM7Nm7~ 7R|^6ۃ '_G yb[Ncpsc~{^m/|y~$Zn}lꇎGp w&>czt0b, +u8;䝹Iu`;& Cض33ó|!_'̍5Z%iT1} *=0Hݩ8VK,hE4R#nj'~[C<6;~g} x+wԾ"R[Xmr=8^G*7G5ڦc +A=8{1eCJG7L 5TEcTDTMdo%w4JTn{'U?gVFq)f0PHBgjV:Mq:~`O!l6Bmgyt-I,v&T{PaPS5qPtW#nr}x{tPX-D00|0qi=[0ߐ'sL&d>][~ ~/M:W5Xu*0D}7LRJx*8S)L>< +TWjZB[B@bTR¨Dڍ y }yxx&%bPFF\Ł RG $ +2SN1k݈$0 mq5X]¼YRnn. v;o/':YشkkԾxe_^yxmULu)T*T8V+8t#nl7.s1[MuIR.͏ONmy+6H|H +k CT:otE$0 ίmaS'6pFMNn5[S38RYk$1*)aTbt>>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +485 0 obj +<> +stream +HW+ oCm- ^ zPU;Nh4S$uNXf?ӗ? ?z//`t2ov6a:)O_LoG1˿Nӗz[hb&so/1+cۋѾCn3zd_-r*˟N)1!<"b4OX"!'*>&QQ)kAiTnwTobyRރ +W8?|ehq i Mc6Dv#E#cHe?򤳣w`{xm^f H3 = ;ZI@ODd;S^b.&@U8 p&+ +&"?DӶ_\D7%!%%$jd#g"}G)+-jr*k%zCq ݼ!`I5d7tvhTr՝=%Q!~_x7 X6cC>瓐ØdTH"KDf7Ig*&muIJ!bq8 ;cx3a9S~^?@SdGtʖhTrw!rT='Nz%bg=C"C:Sqd4f1V^G}ϐ0NF8QW HÐV{ٸm +$R@D_͐]L"TE]6&oԉC2)(GC}iY^Kc^h _eS28 @eI-}:e;ZDǍy]L۞To:=$v{*Q }KDvGg*l!&[:JdD1|l  vWXr6S2UVTvI;UTɷ뤠wd~aG}dfc :n^_&9hkŕO!E\H zRO@~ng*JL15qd[x=U8 pv) h>9G-k;^yi[lz|Ҽ@h=h˸w ́'!2C=Uo)A2)(GCtpҴ-an:RvPz)C-X>8hCɍondYSrjH3-Z+CeOrF'ʝXYbSslÕ` שXOFz8;6t=its}] Ո@Hʠ4Kfv*-Sܝȭj)KA9%2z{]c普}MwiJR$龣"; uwdS_LAWPd$IرtyD5O$T +zc?`OS6158M ?Cߵ0@`54GLrQ|{l5D=.l L8"=שD*Q5Zl8}=%Q}}[݇0Seun󹺐fFk2$;sm +;\q qmq7G^TJ4"KC YDn6Cjۊ5K̓R([hS$3j3h +R$v2SvfLŬr4$bq8 ;3c6y[= +t!.wm2&-Se&STij6mmzrJ2QeدPcދϧstV!HDV3ɢt&'0t&bq8 ;Ss|\K M [aԄhq砊{Vdh,9|k-skKA{J +ڣ*svtaO]e%%e'$[V_Hiz+YrTKEbב"ؙrǤRd$I.aģ;T|널"\;үEfcX&} YDjaPJn7x^1^ΞiN;dSdu26kTfrrBROxdG7Y>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +487 0 obj +[488 0 R 489 0 R] +endobj + +488 0 obj +<>/A 491 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +489 0 obj +<>/A 492 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +490 0 obj +<> +stream +HWˎ +hzd;@.dd "@>vPnOp>:"2';c8}ßvvNfu_ F` ~~wh;`C܍fCʣ?iv!(V$c h'r՜õA|`l=% 9+폧4:71y履<$7؞ HNar .JʉA 꼯FupG &'109?zz,/F%*FqX\sX3gwzcҾ'O2ل3‡\tݮg +f^)\={lfd3g Id쭽x2.d0 WhwI#-?aljGQ,ҙESҘC`gǴ d&v 㔟h?}]{jK STEiHUj1uf F%%JTjrݓ5EJs6wb>oWg5uۧvK=n:53HzD/t+4fl#mu=z2 vhGEsNE5k bmf]NrƝm7;&s͂Bpo/Ooo'6eR*iox7I޿˻MNT|YB g2c-լ d{ym<)ٳ|]i Bԙ tbJ#40ZI}@ء)=Mryz3;;O/=?g#=sfoS3LIɷxmI!_JJŮW֘]SS W7o_,[(]`'dԙcg*:"ؘ0V/ ޓ & L!x&1oGsTRN/g_j?@|I(ք6ů uKZ5Asd%:U'Uη.L +*)aTb~'9=9JBѩH&;oH(L)hL0ZUz2 v0=٬8xmLWZbjkcfOX?Lv"ocOjk+Q֦0֞~sѱٙ8y񻮼vݭjum̵;pm +/$菘"cjd[~[0IaaǪ;;C)m~@OhLhE;UQREF$Zl=济ƨQCm|m9}k<}-[ _QLE]qS&[py;w + z8k%wA}ASR0s4iX?pVLY +]NUdUmz~+=F%*Fu5Y"˹XΆRpx3e?4\LNkqef%7f w3d❪("zj|[-Z7cTR¨DsROOXw6~tIl|v/[7;Zp{jlُ16|(>Qҙ_SҘ]`^HJaM:01Q iRfendstream +endobj + +491 0 obj +<> +endobj + +492 0 obj +<> +endobj + +493 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +494 0 obj +<> +stream +HWˮ6+X,, +0ndN&YKݽյ(:,BIuw?> Ӈ :~=Awޑw >nuɻ^cgT-PwNn>}3aFw@}: Bj xFro8x@f̜!E0.H]o'o{g;gC_N19#L L+ZQ WTN7ud*:͊jő2u ćŐ}P#5_Qe4*X=P:*0C~Ϙq; ++nof_vR>Ndf/1GQ^Rl]5KɧHM0 z@;E}OiRэK1=?'Q[y\Dḿ8J._}<3[R}zN_5(cmVoV\& xm7eK<3Gb'6پ4b?zX)ז$XDT Հ2e@biֺ +-D$" %Z%X +n)^{8X4a0G~)4@EsO㨌qK>m + +oX[p/pa_CsϩVYZ;*[U!3KYT\2E6ꢑo^ $E%@kJ2Zn{tX(Ѕ Rdƥ{#cJWk}q ּ?HyMrtz[Wř}§f9n!6btZ#kyf$flUlZ!XZ"VN +Mzo2RZs٠EJra1\֕C=8_R?= ؝w $i2(Re"BmHo^m^hMIFkT ߫##v17f_fll3~ʷCex^pƤ9}Uu2P,]g&5F>9'=(y|\|Ӝy6V'2&\Q +߅W}1}[.:'muVq1{q(ӇDyj#ٰY]$3[."&A B~UK:2X"஁hc5ƓrF+;JN">/f\ w㚆Uk+my2kB)d`"&Y n_W?0Oұx`sgTJef.@Knܮ:]rmz8 +< +efKzE2ڐL#ߴ`+#v-8k ie'BE$ 0Pendstream +endobj + +495 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +496 0 obj +<> +stream +HWM#GWԱ砜. `6=xf2>odFTRE$嫌{/?`} v0\~Oz. H@>'~w2||7Su~yjF7lѐ/Lj{J^nLP@uֿ)1ƣa{ Z|hRRT߻ߖX51 +b +&ToT*mR\0&o‚ 2u +hYgoFF{2gbYnяoʀ L__p-_Eh-r=͘ari:#3x< SR<ϭ @3zAqoLEpfX,awhYԼ+S{/W؋0u#sF[c_c!5Ԭr]QЙ=,)wvkt[LSY؀:}yA)q VxF!fLϿd황j/RLUWf`qX_F{M2ڧM]?>!.4HϿHd0Ql`jHHTkՈXOĶH=/O(?B(WLͿ¬7LeU_ Z: +k>*.\֨@ݏvo=62nh'O%]⩨T 52Eb*l1SH.{P HXO¶ +[H3Ly#}*Dw7/n`z8e&LUwڄg*R/7uc)&|uT P ="gl3S_.6u^^Z5"1Mu0>RJFڰ$;>+ٯ}YoLM{7&V/7n󭳯& <\q}\q +_&z@b6 0S\,7gu%W#a}> Vg:j/3S^6񙪊@=7h^ieT;J}pAls*{Nu(ZQTPLSZJSUʬ |ݼWVDl36hҌˀRk9hGd+?fо#9#Rq= " Pc^Ɩw0NX88;=h~N5F̩|[z8T15 +z15/TSjvfK-Ãd$}Z tgc }j]V_slB.k]ɫ<o1>iLxJLd͙j.1T%Fl-ƾl$V*7àڌm0#sF mՍ;Rc.tK`re|? ˯]kQ8q] 3 },ijևe鶃w}%1`@L5[֖̭`GobE>24LNcjK,>wBW5y 7"aT JEFڒga׶ٺj`':^qwFHKjۤLd0Ql`jXnk^$l[yZ'pC椻e`ze&kLU{g*R/7:2k>nG$qD7h?T׼&>T2kH^Z%"fmcpxzFcFzYD{YuoLMw7&V/7AɽdO+ 0G?< L/MLn0l?[t-SH&)*HLd$1FT5Fu^Tz5瓰퀒B!/dӏt17ڇNt{Ι`z8e&LUwڄg*R/7uC)&ٜL>~uY,?U%fSr +rp[wX;aLkDfr'i5x#_[endstream +endobj + +497 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +498 0 obj +[499 0 R 500 0 R 501 0 R] +endobj + +499 0 obj +<>/A 503 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +500 0 obj +<>/A 504 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +501 0 obj +<>/A 505 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +502 0 obj +<> +stream +HWI#7WԱ'@kDQ+` *?|ƷAC6$@.!A~}H-Z^$ݯ^'=x_N~ Nz;h,p}pmͿo_D4ocPh*zm/ϧ߇gK/t8 `hpgM? ϟ/`0q'^Gpvs+5^gmo6Sy'F81 8 k-OzLoD@t\QMD{TyJ5WTҾC]q68w +6mh[VFYly4-QPaXLD[$sPzpT*S ?ؼIG"B +DbV}fWr%*,e_Z4֓+JqWyqC.=c[zYj_ڋZBoNƧ\wSvЎ +U4ylUGϱڍ`Fs2rDP\JKdZUfV`K"9TkHX[O^ڜzrGCH7`4*̃!5֗%#_ +l*ԮDᦷrI%|#7v>:6Ec +&y境+qJywgH2#h0Z?ɝ2i%;[A=&n%e!a- J V"Pci+~ 262]m&缞&{~Vd> sodVb|0wcw1g3q&B Mδi >f*-}&,s[L2%UWf%&qC(zEZ<(QCQ$!YqeMjBIjBҚMӆff׎}FZ+؉BP$EA@ +J~gVwJɺ_= ]Ϛ: <&O}$f0("P{iTQ5SjMd#bT5Gc#֙2B;@Cknyͺl<[c&n4_6?73`{ŷS$~ Ϲ;e~tcG>p[/X )!;ל1m&}!ג\endstream +endobj + +503 0 obj +<> +endobj + +504 0 obj +<> +endobj + +505 0 obj +<> +endobj + +506 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +507 0 obj +[508 0 R 509 0 R 510 0 R] +endobj + +508 0 obj +<>/A 512 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +509 0 obj +<>/A 513 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +510 0 obj +<>/A 514 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +511 0 obj +<> +stream +HWɎ WQcRA\ʀ0 lcʬ(Kn  5F?~mx>~yS_7~ oC/&Q`i N_o>v1f$>QL?z|ȗfRx'IRb|Wbdq&c(lj bo٨W}m?mx vwqdӏ0_vP. ڑBGPX%N]G*x'tDңsU.ڛkUvd`@?c(Q#iδjQDPN|Df4xͶi,UF@k>zej]Baҕr?w+]ыs,tՔ,˒&paUD1P +}LݖJ,%YUy%-Nk7X (PT_@{=C +!OD58J( 3J# N( +n1ydKy0OI^?-.M]{}i+Qb+OQv9b2Fp Mioj1nt;*TTS- +dd6mlɧ0F?V#Y-w: 8~xʭCI:R4ad5y +ڂTӷbVj,c]RP'p}JMZK2q0r_م%qaAtS\AF줠& Yz2Ig /(dAA!cFMthQ\dJ|ktK1B&-|F6~6^_Zw~{EZb6w~w}7{$H=0")b2xX{F;m;hv~(JL4l*;نzvw-wcS{o_ l Rg;+mTT}AŰՀ˵q[%xr7K- Ow2~^WǫW$0Wnۺ"[$S(|1(J {/>|&R|F-eZ +}Mor8Fg:7QW߱+c倊;YBe`@{(<`42o:h1WiL)s 1<|RArϳ&ni1 O8vz1aB scRH!bVp#I&F)\.<y6o~l;\g\9a3DECdPqmmvĪbk ִ`.}6% љ!ev ~&RHDqD/F"-{lKIP9Uc6b9R&-[*eT#ZTTd_p{O%5*ɅGWd.klEK`^z@>z6f%SUYF65 r m[=Q5$7Gkc6ߡզlF_*>>cŸ$]-UKH+ىځ("~;S+jQhբ,ٍtc+&NmX)W5Zq<"xݏ C`cP8aM" m[imŶcpvƚ7DZ=4ud6 r1qL- &c#xכZ&.1t",PU, pKeoƷimvDo=݂5ےZX@pcD#Zɨ9g"K ߭'7n̽z.{p^`M5 w Π> +endobj + +513 0 obj +<> +endobj + +514 0 obj +<> +endobj + +515 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +516 0 obj +[517 0 R] +endobj + +517 0 obj +<>/A 519 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +518 0 obj +<> +stream +HWˮ# +jy;Ezz9Hd1$@63 !(׃rwO벋:)Q??Eu?zϧ{tQN鞿u랿vPFwv]>:>=y<鿽y>z{xrSA hFW+jtH,׆^@E)'< 77q26s\=6 ϗy .Zs#t:o9Y>;Ct5+na5Hۛ<՝edo\qjU#5M'駙;qS5k;ät\#r%ʵgޭ8rIpu1J0!:]L( |Nca,j)c +F [izY}hs5yEV~Ek3b BF.jYUeQ8Tm{zCG.3P[>GuwD&4ऱ!fu2K}TQuTVҳjyHOMcO1H'1:=#(L4p0U u~.w L!yqnf%GFA-c@8) Vl‚ M#CoW@ч$yIG-3Rgtg7*rcڞ4)5 +a] +ZΟE~)Y"o9"c)x~OCkT5蹽RQib#)yovC1t<:X]9~tm̓{ˇfu" 宜XhrS4CehpTУ `LbyŌƇpZ݊q1kk,m7jՇPQvI8T;"mVFZ\9ȐD 5Q.Do@6w&zlQhkuoB:kvQsOc^@쩹7ڗmդL]C; ZC=8q1rӢZTE8Y Ѿ[XZ:/EmTՅm#P]ԏ=Xq[̝Jٯ?-4yi.ZZzU0;vk fL:SW 3j@imVE$b22XA6TLF+І5Y +cP.( +59mj%[k4 kqXVd[toKlQ-*T#"2U_CA2Kn{-߯X(sDzkvuˠuJA:6&$`\8'+2E9YMƉah}L:E[ CeGE[DX%9`XȕG\ [Je%ݵ7 (OQEu- +I$m_:L~sGzvES첩>u +X;mjꨨPdk*.edw6݀f~hߍP.Po Thl.-U>lue;)6IPۂ:N{D3Ǩe58+<cϽ˿]*Vu|KQ{_VQ"DjB֒VIR٬1̴`WV"<[jxTΖw{"QhD~*D0ʛh0XpHC|)< Pw+'նрy9lk˵,5Edf)C 93IN9T! uZiY kqa}Xo{ӽݖ`"}S~Eݵzyo4QɓLMY;,)uddfNA#67YVmQV=lob5oK9ʲ1Aor#wBlM,"l[dhK6"v5ZiXò$[[hGD#sU `7 RӴ^Rɪ }hMm6آkDd!MF6I#6B-l5 Vl)JSHɔo՚+Lvf ޵mmy'≈DQdhaJ6"ʻ@W#_M$|8U$R8U`9~Ǯu.cՈ!`gcendstream +endobj + +519 0 obj +<> +endobj + +520 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +521 0 obj +[522 0 R 523 0 R] +endobj + +522 0 obj +<>/A 525 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +523 0 obj +<>/A 526 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +524 0 obj +<> +stream +HWˮ+`5,,65,:Ad3OE_7^V<<, t.ge|\=Eu}>(~_Ez({; }p +ǿ._^=|ѐ^~_wW4|)RjVByC+8E&-,Uw=62fZ1&0Ӽ:$_hTTH#FZ F))37mvY1 j8G2lwF+C_b+BF7#:FsW[!Gt:/âr^'~^Hl֚KDHO*k"͚f S"lo;bfO_6aU 64`lo*2>u=@1 +Ȇ 4`P +׬PMX(vk Qoˠ\ ڰldk I>eft}NeX5W /LmCHQ?SP~NNPo:pVEp6oԍ\3 |:lHt8dr+ XΚ l55:jDd9i2y҈ir,4yۂ*k +-l)D17 +Zs-`~bg(*s t#sU3e^znPwWM뽀8f1v}QqdE Q{\ϽM`WC< ?zB;C0zoIWɛF̯X;̘rQ]n55ˮmWDaYss ;Y{GZ^MyS;Lw1 @L +tHU2h0'dxf~[FP]Z5-cOM֩ ΃әKOuM&פ,L@%hJxb L%eeI$ U;WT+'jF'j$%{L3Հ;|(qoe fl :#" ;2ŎQ6!:P)&AT +&h%3{4%՚ibƋ+RJ#5$¦HB lE~ ~H.+=LӀ1kAmlYJڹ8m@vZ[@,X=[)nGebJ.F@F"?~ ﮚMPBpEwz!+c\ ʾ ;7 t(Ixӓ.ݕɿ1} W] 'N.xe1Sp?# c@~v}TqղF˔6VGXrzя$6zKuJ~7{:@t#Bu\H!XN`*l-/a  ̇_+E0<0PO~:ז6EZ/Zu_Vyr>^淣9d} =@BI7`uf4.nl: .*lkw:!ڞT+Y\KD\֥ i'èz=-wu^ T$ZP{tڣ\uh ݤ_@P +Of*: +35n,G{sq0rq1$m3,Vx,;l>ed!pF + <nu;3XtY)M +ˉ @ plT+%րel I殦z3ww]>UO2eQ/}bR7 =,FVRZ] lٳYFZlAFdcd:m@v*X\!2bWUCxg廖Kgge1$Q`G #endstream +endobj + +525 0 obj +<> +endobj + +526 0 obj +<> +endobj + +527 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +528 0 obj +[529 0 R 530 0 R 531 0 R] +endobj + +529 0 obj +<>/A 533 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +530 0 obj +<>/A 534 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +531 0 obj +<>/A 535 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +532 0 obj +<> +stream +HI#SԱ۠ ădպ m`/3?#r)Hk ^+rŒf o_W3|}r/of~ |6$2?0Z~4 ~˂Ýh <ft>!8R4V-7][Y~ǕB/u; x^S`!d*DO 1}zgl:?M4M&ly|R6Eci +hђ(XQo97u McOn4NW xwPG tġap_ n_+; hφWeq, oDCpqfF3BL*@3;2D2/l`6k/ɉqN=N989_᝗]9'”'сd:Oh?Og呒sU߻ۗȀPl81 .wgsI񺍮 #gsnYYݥ6M;&^cT1'D'.$xj_公#DN u3OR0֠$ +r{,;#VHjKQ~%9NȠH OvM|"K- Ra00ON<@OY)= +;>hضDMlU-rT5e UVP1NVW]K< +Uw3?Q)Сw +SŐG@U +)ciҦlL.S6f?yj[nS TKm+\!W/҅|+!@ZE#AoCVӜĝw$ID{;VT&RGy}C:~cm=[Le8Ʈsm [R*dG[KҖjY-=xJoC:i÷vշ`biYܢoTr{me[*Еr>K%#ez[6 o91zwzjК0o5Êl1![ Ubb)Ų Mq/Ϸ.wW po;uE%rm:@̴e {SC@hjO"{; O,T=OTGSM{t,Fu-Z[Kv,wԏ o>CrHxN[LeN3Yq:'TDհR {TC:emIrn3;f:j[nSվcV/Y1ϸ4KP܇Yac6|a\`,f/tVhyhr3IbkuTR,UIMŴKCNQŶ&YGlQW$GYD 0x!e:#^\sW|mĶRd=u`.#b/-J>O'@p-vlBrו6D[; 7v +34tY8sxVoG$\^~ + +Ű}5TSvצl.66^eJy}|@Dz ?\JvL3iBU{^+T"z"$3X !lI9f6"#`0 ׯ-Q ÀxbHvygp,&8T= Lء7riZMU$6w m։s𮘐E+݆85!Aa5,et2cצӴN,la8CewIl$<h%*+ki)$7O -ﲤ5ѲL ˏN-"eGbu.VKaa'GT +x+ na hK\U/qqݤO=W|11[%CQDL5'iZsv&:8+2 op')d 04Ʃ.QUlNQ^a`AJ$|%.gV%qdaE(])eo Չzt#Da7ZJ)$dp1+ߝ7Ш(͋J{NW{?o=\ +r5UlS׾v H"yBs!ܥn_軄>ī6jsR:N3w =j"Yn/ͣ\nằ5|݇FqѸn7 0Vhzendstream +endobj + +533 0 obj +<> +endobj + +534 0 obj +<> +endobj + +535 0 obj +<> +endobj + +536 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +537 0 obj +<> +stream +H96{ +r9/X@gq)r! 3HP@}-[/IqEqlߗv|~nw`|[bc0C<.!B46?^CYҗO`+-T@t1M=aq~}oȆ||2;k8n_~1zDә  U$LhͬT +l*flP5AΜqe'N#1 wqO@/:6HTV8; V~&4$jpvG41 zdwS0E lXYb\2h9{ L#뙝< G#KtPԊ^Y bUWKL :B{t?M4BҴsDw)1'XlwPZdXyb:ruX;yruNbl[ +͈jZlo<ɦfn%vDd!H0H^;&5|F*7M4%󘱑V6,By +-G`l+trR +JI4ϱݖņqIZiRmHbM3"MR׽5cφ|iŞV6Z)N`њJ' +𿅎Xt8ɴF +U+XTvPI` Dr6̉(L)Jd\fNjZNͣ&1UT2Ssh,->xG%.5_gMlş$DCkVhzN IZٹY^S;\ s-Ӵ +Q*BM;HK'ġ'`i(؎ Ӓl`|+PuLω Nܑ yhEQ8k#e{;lbcnVz} '@y"D8WmmzpViZţipP6OÑp"֠#majƣ*V>X9!+>Vŧ|5 EL`kUC-)- ޸âoօܸ?mׂ壁WZiCr(Ylsʈܾ^dA]@.XbH:z1[bUj)0ڄd8JF2KY#XX~yelO`c&JX" ON1FQriCb׵?M)LJPkIn􈱸e+"=*^GՈU O铥 7x_Z'{LOVW<].yEoUb6G^"/MM,MskOnp .V777*7!OzLcV>nvۧ5bnt`Iq?~@>f}2n,b=}}W?gM']R1AG!KJ!AI{7,/lwPa4u.i4jq&=&ful)3L:BلVprꭦb]ύGKF=E!L;(V).J;V u6Z8n/8R>҄۽}'DUw ڳgY u9Hҧnendstream +endobj + +538 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +539 0 obj +[540 0 R 541 0 R] +endobj + +540 0 obj +<>/A 543 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +541 0 obj +<>/A 544 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +542 0 obj +<> +stream +HWˎWhiz4.RKvolĀ7€>EJԤf2f:,ԃE~`?.|2a7|nㅹ?:~~Jh.u$Ͽ^ tvoL` tW}#t w?%ay%ݒ_~cBθ h1?Z3bF XfICe "2J,iBQx[zֱjx߽"8yaDsnϮzu8݆{S|xzCO]+JuLB49%(5am+ {E  ^`C$ƫ__7XJzWx6>5hRGϹ@^[үTo-u(Nc3o%J b8Q뮊K(<$5A t.}ץim@!z5[q-1e<@: #r:#2 a!o/l1oeO7[hج6=\ÊkX˻z 鼸bIi.$7pV{}@T"VjvSup_pkp@P+:-F RZk HPG5h;h`[S? +s^9[1EؖkX[ɢ@*A_H}ߍq4. Sj^%Lo\3`ѥ + +# 3'0 {(le6! tkァcq#k(bFbEv.L?(ߋbY=ը-͇@Cmjb+`ѧ + D`1n >(P ľ8D7!fV!Ϊ:Z䩣pt`m +R!Y;Ncj[qwuŴ3 `ˎuOHin:[F ɦ=k:[*5ehP|Y1|q}Xˤ%W-w`= ӎ +x쐄 ۲hm9-f$\<gGI9*|%5 )ܔ3Hф4],^L[.Z6]BI-b*`bBG[_Y&q}8{6'7ڿ#tfdڌlvi> ii4(+9endstream +endobj + +543 0 obj +<> +endobj + +544 0 obj +<> +endobj + +545 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +546 0 obj +[547 0 R 548 0 R 549 0 R 550 0 R 551 0 R] +endobj + +547 0 obj +<>/A 553 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +548 0 obj +<>/A 554 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +549 0 obj +<>/A 555 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +550 0 obj +<>/A 556 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +551 0 obj +<>/A 557 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +552 0 obj +<> +stream +HWM q7jX/``R5}[9رa}P-HXlzbQ2;g|?qx.fx0Я?}||ېoLqt0x;`pxz0||r8Ze뗟op;솘FChɗ7dRD'o>7cF?Ca!NQk_wo6_wey\Rcb#`X_~bi0VT<"(LAIo*8FPeL݂ia 1u p~eh1mlks8`\qR:CZOMPTv]V4|'K G;__/O?鉸ӋbH慟wC{ Q0 eh#-cx\X^ W^h)$;15my@fcoc'ƛxNεq ILz{t9?+CZ zjuPdgTg0ՍĠ,{jmX2YZEMzR2ƎN*+ڄC0[d +7OAnPIؠ@AA'.LRH6Acj&7[9I}Ƥy=jOU8f=f,X7eXdShIgzejМW22d/wQBԮ2%?0USC(m+.GQBH4e)(ek6-*Xy&b\Bf(\g*I!Yt7;&pv^( A/|p2:qysmܽ_{wϾj{c/{(x*s+4\&(^]Щ ĠlFl uV+s9yDP_&bT;9P&𲇃nP +P8mx m;tLIعjen'̃nWhvEbN}nO m a==^pf Zo():SGABo˅3zo`T 2^~k!9~N>tr E:SN +ɺ5ٚωOC93&D촜=m&I6sܔMntSz-%jmxe6,,q,>usRSKweJ`9h@*PrIPtWT,]Qe Ѓe/vr~MɎA@j3QT3奐,|cj‹myU~Z9舜LgRiN}uE_cV#icSËka0Ǘئi MqR?V럙 :UqmШ \0C_FUF}☂/C ?J ݠjo X~Y< d8>'k4ū/}OUPEu;SQW +6&ٖV\q8 ;hjy[S$ uKnJU[Ӫ`z2SԵS]Š,ljmP{jVrT=W +6iVm]6UoZ\W8-|xҦ5e l'v"umLMWq-cFXXI MBV5q~Nl3O(<&EU2%*'uߖKrL!1J%&!Xp3LĐIDD|iz^1恦ж 5w - +o4@["3fXr\I۳٘}ԫ.@M˥t)swkar0rJ6qrpM8Ats+.4~漸6ʇJg +!ukHB,`ffpHƔyb8d74y.eSNvfͣѸ[0H%- =Sddw$(zVxc_R=t#4v97b~ +e.3OMnDD2)emdH6_C[]:+B}޲,ƲͭCj~SBI+`|4DoDVa}ߘ$Ktad' =F(6N߁6w>Skmre]O%CD,`+?ЏB|siʇ@5wwC]t4,i>HIIpt6xIԩT[uJ, yTL{יz$5Đ*z;8 ГFΑ_&ޖRT4zcf=SF +J27N1 2h3SԙI&6w83ɼ>3qHyfꝪy]nAyfOf& '##==jJTdC:ԇEO?*OG$v7<0O8<ōXLozjΠ"'[lFUm!Zk +7V}K +zhh +xO40;Ӹ̘:"Jietx)6%\tPԞ":Q1%pH?bn#Y_451SAw? b7L5cgYKf2?o!L :z -`>Le>ׇsa{($aNeo*yI?O+cUfȇMg4w&_1h2-ð'^p`O^BLI֪i5fQ)b4`˱Cr0iav`\endstream +endobj + +553 0 obj +<> +endobj + +554 0 obj +<> +endobj + +555 0 obj +<> +endobj + +556 0 obj +<> +endobj + +557 0 obj +<> +endobj + +558 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +559 0 obj +<> +stream +HW=7 W+NIQٽiRd;#HF f4%=r __t}=΀y|:9h<gW~'=,|-a)8o ߧw>Oͼxe<8}8;䜣@gO!> +:;E~P~xB=~>ĖM "&G2_<}Z@! z |cd +6"ɗS/Ӻe4MޣfXt "ɆЃ[J=.K٦:-%NlFT[qK:ZT8f^#g!8**S޳wv.Yp]C"1o q{UaPRCgsPTVQ -Q@USuɆ%G ji @q:d4ljlō;ѰcRa"ri3ߐRţ& _9_i/oܠF*!%1RUI]uQ&ChS&:ՒeܼA  X#!M`}ɚl%@݃sPkaP.8IGo%;!O6d6f^F_ԽAs"\J8Xd([sL׵ctwD7@̞Ξ*|+tq^fIc?n\"кz9TCc13@;u(.C.f,gKcm\aމ,rH'z 6X'UIoD{^V[&OLى.0xOkJE;Es=J:Z9)r'N89䌌4Ѡ6.ξ,7Ҫ|0Qritp cZ^PX]/?ƪ,OM1Ӳ܈V^:x@Rq%wq)v$Ň\H8HK%ܥisތZ$\oC+kYkk;nI# KwѐX4B!ظE!oNzKIT<ŅlK?<4者GY WMdWX6ܛOm{ +VB*v.)qjwlJbsǠMG+l),NMt+^޸}dxI R +Ӊ w)o: e?ĶRbKx:Xy11y+Ĥ}E*zl*Ŧh% e à1Lc8>:*nբ&0N*- :$9B +қ˷j[Gـo3XңtELG)nJz!x7F^gR)? ˟KiQ HX{MasX*}/d(+Ne^@& ԭߣԚdMM}3s}~x"|O/%]SeIDh=2TY1 !s] N:::g&}SO(Rj8U Dk`T:EuQ'xHme|#$wSӪA6o:}_]BH熑XA-bҹpu1?(+' cjdm8Y#v2XT|e̋{]?@M/gN>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +561 0 obj +[562 0 R 563 0 R 564 0 R 565 0 R] +endobj + +562 0 obj +<>/A 567 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +563 0 obj +<>/A 568 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +564 0 obj +<>/A 569 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +565 0 obj +<>/A 570 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +566 0 obj +<> +stream +HWˎ+ +zyoE nIvFql$@6"@>d=fiv`Z)6u:mN0}8}?_Na?F-~F1zC㟧/?Ng(N_l7_.?"!8R4(ϸgY&S"E7C憆nfz/~PS1^:pI_'8ۙuƼǟdgppa.ص ^ XnDSi/~^Sd~[JD,܀~C''nlHO~4m$< :FүPwL_ nҍ ;M9{wN3#C>C]Q~WC]6;E6(TVvW$sZo,*YX TkhkڂCf# +>+ {e7Kk3Ul<{^ҌF3Oħ;o$dstn||e'+ٓp~q(R[B/c u W!l|yYv8&gEZ0Z͞U6} `L +O|9X 2-$7I%9q 9G2 lA.IYXmc>6#ŏ1,..Ҷ y"%E14S4}3d 8Gt Tx-CveihHG{r&pk ։Q# +E2 i2"&!7m.*59\dɿY }pCaQ %(OoOg+&:D Q.ET{ +S~GkvŰC~ͰqZV.;YJ059G YPSZ ҖX;'Ye)xBY #Rci{p G>ɧ-_I)hs5 +A1K5l*j[Ų-ݴvTR?tŦP'wŨeP/mͪ&P7c4M5F<-6IiZIʤ(<oڻ[zxܮwP:(]h}u_[P6oZ_ PUB9 +TNa,DƷ>V}ƂR!JmOhM; Sp7HmU*&QGf|а CK}3A&tsqв-n,+ Zvhf`wendstream +endobj + +567 0 obj +<> +endobj + +568 0 obj +<> +endobj + +569 0 obj +<> +endobj + +570 0 obj +<> +endobj + +571 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +572 0 obj +[573 0 R 574 0 R 575 0 R] +endobj + +573 0 obj +<>/A 577 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +574 0 obj +<>/A 578 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +575 0 obj +<>/A 579 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +576 0 obj +<> +stream +HWK4Wdy/Rs=K>)I$t . _όy4v]Ms2Xu]|{e|^>=Euϟ;;Һ{ө{݁.oU=||q4O鮤zD9+=?_~)??ğ/U[nʌ#]KнّO_ru=5 +z}I)a V1Qs_ ,-?:'-> '3MCG =3"Q"=:sξp/JzҚ{\zעjYח%U蔤{BҜdr>*hqh eS 0h3d:5b-yzji\'{:݇uYѺ 4竪M^;ZWd@wC@h +$իal : +;?*UVafokHz5jYyXlոm th~>HsMXۭۗl*}Ga"iTsX(w[R-۬ fu7sC~: kC f?Ȼr#ʮ$3+{qx鉴 `4gnڶDdHkd5Ts֐] 啐,C!7"%T6ow ĝ V-pдueNuUoy<"9Q9:,fʈxKp +MO䰍hY*̳"mrZU@|PٿoH.&;P+s`J!b$GS'Sdœ/1+_ȉ]ي%kCGȖ#,<2-KVhdlWDkqe*5l4]b76@0nu (9崑BĿ\0w,oCc]IoWw'iyy4=ywS17 +MU#R(cw%`<ʹ0raur^jZ@wVA"AyJdKE$F5 ^XUƤdXimYv(z_=:BZ]=Ldߏ50 VzDNHkNӤrga5Lg5.eBvϥ2u 8v6eS9lS#m-F +ӯagGN770i5iqV +1k`fWO Rbuo `+teVv#ژnlp=eLo*|pB' )61.5aPr{JZ(q`ο͏F/(/Gɩئl!tLqM%`Ѣ +Ā^\~ڈ R IAnLۭ $P aID@6xJ#fy`*}`z䮌nEY= f{[B\e(2vWB 8bJ_'7M͘g`aS1cr2A#mBDvbG=0 +FrJ$Sx,⹯—T[S2283 Ҭʻx4رuapQaM<$ C%XF̹US^adxBxUv뼑X_+#Ħ'e(`(#[lӊDⰌ$5,GCiSJDL5, FRDI5a 0HUendstream +endobj + +577 0 obj +<> +endobj + +578 0 obj +<> +endobj + +579 0 obj +<> +endobj + +580 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +581 0 obj +[582 0 R 583 0 R 584 0 R 585 0 R 586 0 R] +endobj + +582 0 obj +<>/A 588 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +583 0 obj +<>/A 589 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +584 0 obj +<>/A 590 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +585 0 obj +<>/A 591 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +586 0 obj +<>/A 592 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +587 0 obj +<> +stream +HWˮ +VY`\@/65, Yׇ%ݙ`hWGG,Sz??I?z`t?t!O +^,4 ]> ?yy#R@>'RʃU_ZZ7A_ "Khnz +-|'Zk Dȥ'ⴿ&ѳe[?QhAt\Q4du\ 7f/9 0@/> }6Gv\N^^bOD+XVp 0B9v ,)z]TV>ᗿ_~Aap\(7dE t I ㈨Ȓ{0l d:*-pzΌ[AK.`YnZWAS1? +,)q鱎M/Ec݀Qq&a?7ʥːVѝ"V*QJ Rid*qCcn[/wJA{1? 簃2%Z[Vlv +5+:5 ]_o}w'~XX1h2Br>͕yŔhߑ|CҗsiKX +LdVƓ$V#v$&F+̮4OP˼xRa7{1^>cE|&r#j^,rY +FE=X-DaBvHqӋ +-{$Sle]k^AӋ|:~w*"v,oi)냿K!K_h۽B ٙtYi2Qcj+LԵ20^Uxpji!r{q#LQmsڦ<+Rț`=m#L;`MuЗ:3g?h6 U7X=xX0._8p~]o,q< NiE(;J6$?1`U_e''ӷ ,*vmD^D^9-=|D;ud ~V;=?5O="'a]/!3| +POcAvx~1MBڕj/z7Iܶ$}&ggj%5U"nmYAƖcP`s14ME+ŞUetGR&δB)D1p15%^WIBz9mg_Z0ker'oڰAA{ dQ)u|Ut^"w-c,CQnZU[ +R~xcllfpdRM#e7.1,_Sq707_40ܗi[Dv ⑑n6x4~ Vckڡ1^{+)纠om>e$|>'Fru׫mW*E/Ҫoe/2kUWfEs'~x0)JPKBJ$4|B{ [9J;*c]C%3P +SQ0-lM*ڕhf3 ԩWv`hg3kHy!2 ~36r6[46M4mAuMOi^0$a, qf{E(k (OW1`ce('ӷhDeQÄl xm%vT޿&5{_TTZn֞&k85O9(V'$kdfLav%m -ynT2-IF_7*>}F 9b\QſJXO۩f,: f3c务ueMYv +3> L{*DQd5dGdRȦjLL3o&$am{k+誓mN#Ǯ e1u*isU'4);i%ٚVeeOC.~U_WcA;6jWariOzF>ZcFe^كuBѲw@Yw gt|-JvF"^>nQ/ )X'$'$)>WP;ŗx{£|Z X^7ձVp1& +sm%Ӌ}=Vv:+UJ[çlpqo (\ωV8>VqG yk yP+endstream +endobj + +588 0 obj +<> +endobj + +589 0 obj +<> +endobj + +590 0 obj +<> +endobj + +591 0 obj +<> +endobj + +592 0 obj +<> +endobj + +593 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +594 0 obj +[595 0 R 596 0 R 597 0 R] +endobj + +595 0 obj +<>/A 599 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +596 0 obj +<>/A 600 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +597 0 obj +<>/A 601 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +598 0 obj +<> +stream +HWˮ# +jV" e;@.dd b|}W=IۓuH$uD Ng3<}{>Ǔqx:ax2ɿ=F1zCߧ/MpoC刺2Cg`V<7<|p(֯qq0QK~Z%Ê`.t51W( ד%*ٻOfOntL֎H6 Y4_i57&4?) \"3R05c8eDe+b/sю1r B@`-sr)QiIQ{Z"9Ú#\j~_K.INҊ3()HMm-mM][sɚX77r:|*6~ u#/D_k.ܶR;C]'^ݟM87rɢs+!ܩ82:/lWhg=<x1)Dޟy!&w[J,Zz epHn"YۺBMt\auy Cjk@F U3r{L'W+<.fm0zbYH2yxߩ@p]q`A*$bXH"(hT[2 +"RP^> %j{zt<z$ d5hrtpЌ.?F$V4`g^i﫜'HɈ649ɒ=ȥ %gѰ͑x= {-6Bi}D6OG,XotuS7[tRİgfhcXTU#2l*3o+3 ˤqn &ҩTU:r +gOd*}C=$}"61z|UoNclAEVD4'HQUNUV$*QT#jS*슪LUQbl)_r+V +j59Iȓ*TTLЅ-4nf`%q}^R8;1+yVj/x)ΒR,$U{ٽcZY#ާQ^Li)pȦ%˳B`?ưjF/aniWgd^6n%zwGvWq9S[E9 k +ڲ|(ۍcnIA_*-HCU5v%6V#j61;}GQ )C$6a4& c{Z-+ 8ɽ/ O1]i + H CX o7{k?yK`/5f,]*`pc*Xv}V&PMMٿR#Zy +&GLk)Rw Uendstream +endobj + +599 0 obj +<> +endobj + +600 0 obj +<> +endobj + +601 0 obj +<> +endobj + +602 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +603 0 obj +[604 0 R 605 0 R 606 0 R 607 0 R] +endobj + +604 0 obj +<>/A 609 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +605 0 obj +<>/A 610 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +606 0 obj +<>/A 611 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +607 0 obj +<>/A 612 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +608 0 obj +<> +stream +HWˎ+60]n@@$5vE OuWEU}:]ud_N0k8}ft;}n4~կ~ +|9n9}>Ջ:}rо<MR ^|61ƽل)@YfF26 g,rvy*Ηٙف#b]2_bM.[riv*vLqHfL)C(ctE!y ff7fZǜT_<0:c[0tc|QVM5YWkAFF1e.$UwZ1bΌrm]][lOI/@!ڴ#NrȍEAq1#&FLMaRL1YC^2ƴ0NcHPG\E^ RHLA19ÎM+1 +#zLE/rԀ&DD"aupfq෉,M~4&PXS ~ {JYC©d&+5Y?TśQYof5r0.)ɶmzmhj۷Cf3lO3M%;l\>4gNV>ѶG{ ;^ˣ_|š0k~;UZ2{TLGS/S⵼MgRr2($Owj9dUye6HZ"CLk1QZx-1$녘^*}]et ˸cT$\) )8ӁÏ#e\p?/!yd&+mXwT7QY D pC^ +^QDsRʹu] +@^."lhs&f/4P^b%珞 uĮTLI>Gәz2)f*wP eQ@+{Q_P-)*m)&0sS|uj̾W;(t_[cz[!_m_}u_mq;7(jZ$3ݙTwbEf?НhŢlm:1Q¸ + \$颴0b܍tep|@S>\QO]%X| nӣ0uPLVT%3YJDʔvg*~[b"&&R=r5KrN2\:>{cOak7\kAR?p{} %%4%IDqLmu3Ę#bj:ˤxKHn\B.x7Zmu9*P2W@nmۥMofrgzcnpӢ,A([211)X# +-c7oc/nڸcl[:. VNïQ Յ~;Sva"NT\3.2P[_w#SC*#B\Zdީ` endstream +endobj + +609 0 obj +<> +endobj + +610 0 obj +<> +endobj + +611 0 obj +<> +endobj + +612 0 obj +<> +endobj + +613 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +614 0 obj +[615 0 R 616 0 R 617 0 R 618 0 R] +endobj + +615 0 obj +<>/A 620 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +616 0 obj +<>/A 621 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +617 0 obj +<>/A 622 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +618 0 obj +<>/A 623 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +619 0 obj +<> +stream +HWˎ$ WqW@&3/1@ף ^K_|TgU1g H3$+HF .75ez^=jE  jhsPcşߞ>F\ F}m=QM)0J)vښBƢ6j a H)m鷙sH/Ͽ^m43# &QYV0/ m0N°ϧSj9%73C0zRaX"XOg0㳕73inM<vc!k9&9,Nq\#Y>/Q QkW' kцգF f j^TO`#6T?K>nL30|tB^e"ljAK6J5h -1uP f{bOn)o=m &ULm $C 7@CXdSTF<0.*s{Rǘ!')a5ԂQ/*j(U54b|oŀ+.4sd| Hg1hHmj0V +^\*1UȬԞ*UW%Z=ɩ2X?J}:Y&*$WGun 3{5Ϭ5H`" {՗KQ IwEp@DCv'Il^Fkm䵐_ _Y{߳]S%iu8E,:x68t&ak)48G|Lt!ƽ0.zMߎwlDyX58;ݴs,c}]̪L%a.gjHL)R03Lڂ'i2X0m8]d*51[FhD8,؄՝M66lg(7Y DjLAm!l&9bZ̞,uNύq"VҨ4D^ Em1ζ39 I/@&ٳ>u2(P; qJP;Q>P;b褚@Wcր+%aí1]ǁuY5a,_lHo[A5.v$ChU/Ӌ=d^O,R2!7E!a5̂CC@$#y@"dOהdhF ȬԞ *UD4!Ze=Yȩ2kR"5D֘d}q{1x7ux0be\Xja:2b?T$bUQfTT2'"̪iHL3W{WvjBF{U;UA>!:\ ժ0;P_DUtQ{n5wO*&kBbGkcgph[)|$nlEȿbLt +sNK)@q5-$ESo@d^gYy @H%!Dq%DI>ի:hK85_ݗ롔*O.7w(n)gi{ElsQ!I=@O&* !f.0ƇZ#Ckv3W%v }X:0 YDOB7Bi{btpfK+%f!a5 {וakLLkw²L`nk+,)llAmT iRJYVsj/*CU*H1t<-V1fjOr +J8>cv,bèJBN 3;X> 3%l(DKyȖmWxK|.?%4]P"}v ^ +\`CH;`Ch\n`}cN9d)|q_֤=MyLB*`*xLP) s1 +I:v;hɸR6:P&ezގq;)Xttcg_ h &*-(ЩV! ZԺi6rő[ZwƓ}t@ق˦'\6{e첱q3ܽ}t65탽u]TҺN+?l?qlOM8O:TV[kKN`-u$I =8nr#XQ9HH_G!OZ%o*Gmm|Gc] + 5I`F;-\RZ:D ,&)ǹlAmX}B14cHll=p'pӄ9Ut}}%fXfJ + be5&Z5]ɩ*Puc2%hͦydn IFWr&jXME*d0AY]ǤU-iX6K.} [m" *U|B呕EX +K$a%b& +FOJĮ,Sȟ֙\OZ7ef)A{5';]|\Zv tk0};_M%_z] ]jy!Y"OFendstream +endobj + +620 0 obj +<> +endobj + +621 0 obj +<> +endobj + +622 0 obj +<> +endobj + +623 0 obj +<> +endobj + +624 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +625 0 obj +[626 0 R 627 0 R 628 0 R] +endobj + +626 0 obj +<>/A 630 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +627 0 obj +<>/A 631 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +628 0 obj +<>/A 632 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +629 0 obj +<> +stream +HW;ϯPy`ibb7H4EeY*R-yPO_o_w=tMO&}M'O۔G7Ơ5NO_{;!*nmu1<\^-_xe\Tu xZg ׬-LI?؎Zk- a};#$2F/:^g-;`Fz \A^%Aa=`QpW#9vw~ͼVzj;C"DCZr0/hDV .u,.ք _N~Nb_ -L7O\9׍yoeA()b7P ]:s8@`h,/*oMd&eDp2r8'6Z7HayR*8kn +b1)2TTʦtysZJ\{'DU lU +\DY, 3|!32S-+[@gϐ..+=[tTe>Q̤U_q/ol8yP>2FfԘSt")\ ʛ (2joTiN'G-;hI _bU 5RlhHFy_yHRڦi:*ŕPwQS1nFCT,Qcc׈e'9ZKiz"[Yн[1fw\D@A$ϹxgZ)-"Vo6Ct*X QDkZZM9dhe ^%F!AO kHرv(}KTB7[N'C_;$@šDfUAa +*AD~]?%\2M6Pr9@$-R09,sK2z } W.Mzg=?He7qd 7yv8l1OWQ#14n9ihUd VCar޹ F䠂8:QÊQ95 ea@Yg'hT; хafmXcgXg_c6͌F%^U(VfP DfS'"uyqnp | +_jԂ扄5;Dkӆ4)_KպlGAGp~U,)(ͤ&pH]YƆ=RfVH)V4d[Cʡ,R,()WF %)NӦ)5lfg_w9)ׅ7Dm/fhw%bp!$\Ɂ%M9fN3\.F kVHwkHؑjmrNu{UTRO+uRlH]dIK}9؜Yuh%,)<^˅G+:kZ"6wFbUm9R[crFr6PorC:QqpKPzt<9cEx_R%BXAJZZ`0]k^?|M]k?19GM9jp],: 23؉ے H,ҮāQRv3)+[4Y]#aa>P4Rk>4R9)ZUjrIqs+'= ]f8fh^%b9SQT9SEMpNEڰ21[iiԿ-=Di1o־MqӢxetm"TsT*0)*7heY2uЙR!4r!Fk%T,>PwL 5" cl~F`69Ȁhe WA|NҮ/ L$m"b)3#_Oû_1smuSk/khT)##ـ]1IH*žqiu]m1A-'~K<%L0] kfӭ].'H^Q3Y=P!y깻d<0=b5zU0 +%*\ "D&amoy="0B|>s.^1${HNE_"HA 431HlQaabiA)Dh?Ф e0JMOo5(uX>͎MOM!J6ms0 谂Ѷm +>`Důendstream +endobj + +630 0 obj +<> +endobj + +631 0 obj +<> +endobj + +632 0 obj +<> +endobj + +633 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +634 0 obj +[635 0 R 636 0 R 637 0 R 638 0 R] +endobj + +635 0 obj +<>/A 640 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +636 0 obj +<>/A 641 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +637 0 obj +<>/A 642 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +638 0 obj +<>/A 643 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +639 0 obj +<> +stream +HWˮ+1p9]/@HJvE 0O"*'xxO /~4O_w3pd3v>a6___R ӧN_fc߇7FGaq4qt .ބjeC"KI3ʏ?0?ϋ#b?N??֙marO.v4 ˊ`v1݋`_]ζe/礽slqNNma 31FOG;8B|nxucE _ZhoΖgcP )V>kƉ+|1ƍidZGgh歉xs;MriU"4z|^v+V>0gl_mٸ pE'1Gq*hHF5RUo/1)5R6]#mMP|]‚u+vsfi{M@+}=A?z%E^{++^1 +Ds%b}ԧt7~C&"H.inMXhr$˟R=(T aG1'kWQ dͺ\U8Cʡy 65v'k+6D EM=>(8nB!9,3&Yä10 Jd^bu˘ry,bhњ32S)dS`?`y^xj6K>18s.׹>ᾆkAF(ȐW!4*W(h-c i.T!Y,f܃~܎-Wɨ&f=ԑo ˧ uvzM )3E)M)v-TkR\/ ~V)iEf?~{V 9wȐ!$bE%jhDQmKEҖ]B43;&Z +SzLY}@6e)PP^ް_Azz +0p1endstream +endobj + +640 0 obj +<> +endobj + +641 0 obj +<> +endobj + +642 0 obj +<> +endobj + +643 0 obj +<> +endobj + +644 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +645 0 obj +[646 0 R 647 0 R 648 0 R 649 0 R] +endobj + +646 0 obj +<>/A 651 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +647 0 obj +<>/A 652 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +648 0 obj +<>/A 653 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +649 0 obj +<>/A 654 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +650 0 obj +<> +stream +HԗM# } "볁Rw+@-0rc#rCV[-:A c1;"YtO>nzr7\70/GGC$?!2?ᓏ/3/cHyyLO9sro'SY|8yZ()0_Go2waTnuN."pޏ?}ߟ@wp.ùo'5+\D\Crp]o./ +\h19M#"şeow2$SiT2B1lDYXpD KFrZū;`8fܔ~L#K]MnmЭX*Z Iѹ-Gredxln3piw _=mWS ;Mh݅*ݥRn `nhi pi 5m ݇@5D^QhcxlR_s=j6,lUe)-nE۝N&5S]H9pJF5=ͪ^CC2/!NHdzu&~҈q.)N$dhSyeA!<񉾝Dr2 d7%iRcy& †S8PI\4.;L]iY7 >G&vqIN"l/ +qʮ [Q˰x[D 9$UYteg)-DBԝN&5)Sk|(IUkc)>$]+!֗@7t+P0/!ewF@}>whOsp]ҰVR+|8HJź$@} }9B +-I8r.R>e#M.g2=^)6ɮsބ]b]k.X/6۴~QI$q4>p=jخ8U}`V0L?6vZ(o@1mbnGWYO/X(]܃y_]&',f_UٹlJKQ`vS!_=p. 傇})A['?>6w@ww H>oB>0k?/DѿarC,T4|Zǧ b{Z.3G:d8uk OLeS n/!̾r^z +)v. Ŧ|}!LKq%~Rwݯp|G-3s @O@Xe|'o%F" +ͯ\CP&QFy ~hOxSxxS0B/(~NеHe>X{77TUbD݉I6Pc#s[V[;!Ax K3KnVS(#b{]}W>:X>!~:vo,'mM>߷g%*Vc͋ +n%v|nQ뺷]; + q\Yz\/wDWhMôV7eBBEʐt Ij .3/p&r{n + :i=&kU4rB2n m #|@4r><j5S۪$nVU'hc}ߺЄs请2OH &fCєF)Q ThR =պ taG6V XRu[-FQIJvCESai00@ ; +MhЅ* ݥAR@hJ5M?uSzbkz$ U7C8xlQ,ѕRCBHN;]j1aZw!Mחx{4}{PmdIͥKفj47@>Oydu3|)iF( wG!o+8S̔B\Y#u0!@q" !31k&MIs+Mߒ?:m"61֋j2M]تBWӦӦԧM]ګBZeAI FGeX{Qѭn}t{6_ޫ2NKP9tgvX3dT%Kq&4I\M0~ >3&wepINl! Z~w /]!1^}gup HH>Se~Vz=oΪte)dSjݙ8{ݩpդ&Wzu(ۻFJbm|ŇJk%$2GWivS8ϥ_`+Z6%_6ѷrP}5_E]A|FQo&2iRZ,uRwi$IMn$nSkH45KTpLV9'ͮG3ԔCT!N TBQ.EzdX{UGdX_xS:y ѝ/8}c'@,. NDfxLO 'ܵv7rJ ߘ6d1Spc +G +~] mf`]lJ MQlvSIM8T.%4Xk%$SLalextC&KX SY?|]0 ecOJ䯰R'&,+)IM+z-%޹1##,I@%pt>-j㨩-IM[=s%Wキrr1ݯNcHVr)눶4ӥT+`eKkAg"NpBƲ(a B_SژkYY]@_fX~^$K\@*~3iF?J]Cqٹ endstream +endobj + +651 0 obj +<> +endobj + +652 0 obj +<> +endobj + +653 0 obj +<> +endobj + +654 0 obj +<> +endobj + +655 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +656 0 obj +[657 0 R 658 0 R 659 0 R 660 0 R] +endobj + +657 0 obj +<>/A 662 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +658 0 obj +<>/A 663 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +659 0 obj +<>/A 664 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +660 0 obj +<>/A 665 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +661 0 obj +<> +stream +HWˎ+ +z9Ej)@""76l {a _n5kf@3)U, ?`y8|o~r311 |O1c/__.cߙ>L_hLq.^$̇1сvտ Ɋx\WrqgM2W3O/.ҕ̟3LD +jOy 1%*kCl} ,Mn81ƞ pG1U/,V!k!- "oipv(ǖ~\Aqp(g_0FcqԨXQ#Z*5 Ak*Z?%\XW+3iYxG]qq ֌X!6t`tr6%ss8AX2UJư 0z-P8cǜ,_:+Lx=0HJ4%a®&a2Arj<k{botu +؉_gq3ۆ'tǬm/!K%]W~JˀM]8WNtz3KD)l̠uD9i'Dǒ^Q*#;pFrxM·w];>ޒ޻Qg\x(-^~sͯo|O6@XP4apO +qFO50"Cqtf%);DScmyy"&)fC[GߨX.5wۥ^utF-mh~7Xro> #M"Y;]2r$l@+38[0qN&nrmo U}탽Yȥis߻Rx{>w|JudƝ%Lf]|7y_bҗyy"[ y.`cJhĚ!dHi('fGavC 2oVM֢Gya d>X Q𛚸=극oܐ^Q+vIO*0WjEx^&B +C5۶_u9>G\ўF$(-uQT.bn~1$;Z_4bB!PɎ4MlE܏6ĨbՆmƃʫػ [Ł"JURnqЙEQ$ьЍVMTjOP.8i@R=Xo fPM`wTI07fImشG"${|0`pL.@G(yG$jL)3p+!XQϣ(i 8Xz(i ЊAN,)_((L꣤N)_׹kP%Ey.u`tyv_"MGQ2_-O/}am)nЪf +M +K1}R5^W-Jp9h[;kT_1iRy {WWQA;cGfpwVs,4+6&uIU{ !D%XәUW?ւ5zm*ԮPe0RqF-8:|V:b  Fl".g.^d5Znd$~zo ?m5`.(4 ם獠)C +*FԤLRRMV%UfOIzy8>;JŚjkhXO>qG~t+)pu0[g)gשG#Y5T= 5*j#"hSQvUw>z#hsz=ҹ%}WPȖ%G"&L\f+܃{pJ}/1ʣ{DUdG&C 3o@f47{eit`]Xܪ΃T={\RT<7}|qx'?@{M_4Q,S`2 +'TuUvtm*ԮPe rHIg3꼲lqM(`ot|790)"%gp˽Zu _.GtlYë^E;ˣc+͔pGmP:3t6 Ёʒ$wsyu":9R1l@q ؏2=g۲*)fCfYg%noV[ݰ|^P3C-*}7,~D& g- + [ai42@ZKZ? w_endstream +endobj + +662 0 obj +<> +endobj + +663 0 obj +<> +endobj + +664 0 obj +<> +endobj + +665 0 obj +<> +endobj + +666 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +667 0 obj +[668 0 R 669 0 R] +endobj + +668 0 obj +<>/A 671 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +669 0 obj +<>/A 672 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +670 0 obj +<> +stream +HW˪#+jm|RIo]c{Y|KC/^::Q'OD N_g3iz<f o1<~I~2  cpǿNϏޘG`'+.GԇC׳1`1fR Ύt%H|d eƢ5|1f_:'@;z7xG91\yQ.("@:)L-,xOn4l(U6}Gٛxe@ 4cz4ulJ_oG TM|ܥ-U}vm;R}F% 7Aks1MQޒ1NJFi['|54 Q 2>C+u_'0RT!Y'Rs*e(@Vq!tkB6=14hxO.|vb©mMEΫ.7ab7u+/eTb갗@Q +) s1d)bџ#b 仙 D4(cZU8&( ߧKX >SP4CARcD.S[6 tӛBEPC݀Bm n8R! +4uf-zFA $7#LƏg09?"QY4{Ҍˆ 'HNF)DM3~e0PLDV$S=ŨImt) %La`;P} 8%GiK~.tk|6,ICgeT(O/wʨԎ2:i +xZ>I6cU-| +gFS}V C.%|Dt=$\O˱`Y`s3 W8,YPy9}wy^na +h5F|g7FJ ͓ w92&Ob鼤$xѭ\bG J-D]zk-̞fs\0PGkNp[S[@:ӭMp{HbUENZ_Tcho*J0u6iVݱP{uTlÊf +nlolE"RL"T@-WI&yERpfk9m zNDkYo˳vt&0}g|U.LVH==Ux=y)9Ƒ]-.:u5J` &0O&#x˥{,Bkѐá]hTקcXf>3*SSTVy;VUjGh4s70` a[4*Rf^cUKP|/lē%knE[Ev}kxkN(L(ErT?,[sjlOB 8RG J2-D]z*k"-̞Hs-:Zm:/jy[?}0#Tga*h2ԙUK4^OMf5#uUk SU%hTPInxjЮq_gYre{\i+NƳI nR˷il(.ؖUAMRDhjRVh3C5؎J Ey sіJ>v_k`Ƶy=!\0}B)n}OQyFfn~>^'?llmsZ~t7GwKd6v]5vЖv2sGUcJ!͵ut2Sjݳ /ԈST4 eWQ]->[X+& VMbr I& NRĢjm 4;Bj!$n^[Z[ +qiyyWpr9iMLӟϿE\N5XNN +웻Y|z +q{:9| sĻ2"y4-q$>7mnY.ʫ=mݛokĥŧ?27'iByZI6y4+SoN׼r0[|7(z4@HߓM"V7Y-3q"@2bi T Yvx$QBt4gMV2PT&H )f v=jr9TG'PN)`::gp%WG0[endstream +endobj + +671 0 obj +<> +endobj + +672 0 obj +<> +endobj + +673 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +674 0 obj +[675 0 R 676 0 R 677 0 R] +endobj + +675 0 obj +<>/A 679 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +676 0 obj +<>/A 680 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +677 0 obj +<>/A 681 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +678 0 obj +<> +stream +HWM W8sX4e9@-rf@.*e"={HnT$h0</fvrۏ311yoouu(eitv0hp//qG_84F;~8p~ )7&|qp_vxׄ5c(̑|; |)\v +3˙S6nBߏr\r{zkl|mq3aL<dų>5i=]JV=FO.CXobhm}?O~5PƐB +BnvE.9ߩ>o߁ya,~E,U`^@;@ɣ M˦:o +e.$uwo@ GFa-YvE +?~G%wO; *7(!}WDdSPg!iMV1Y!\ކ&U%IJ1LqC0Md +~eQ_g Eƶ$~*ULQ5 0UQ5 @N`ZCQQBxh2cѧzvB!DZcTR!EHD15}t(bjduSSf@y9 VV*tTB屿,H~r*k*tT;u+V@7!"+ +GD+Kx3~PPؕ\ ƟYyvnG闳ɜP| uMu5 KӾ%7rk;{t']]l`˺d[rա^/Dl{`S M9ɕ^Tu0fJHy,KΟ͵\jid!~)a8drr>`9K5k47ǒ=AQk"7ĦzE3k8k3:S"sǎKtUɶ9Jg!a=5!xLhec* +kc*9mi>-׶1'"%q}zobY&E4.@ûa,A +ܝiaXEYDD(gJUq1Y݃daYdpVӪ!K\}xL:9xy]w:BȗqkZٙMS~ +aj(طn'L].V&gfdY[cdd;S1q⚼1M1vA:N$U TOU@#֘ZUjuwsn&vƣM_]f+~uuEbY[oKlw>/kX1}{oIѷ}71ټ[HT*{Lٷ[;Q"7T\cou%V9XBz,"DlF|o&1gjXWRrv+nDWū6L2ˮSe0%ڙWTExJTUaT +c2 4+X^FڣNহJgt(x!:Oq3zizң}bDavt ǁHs<+K$8#/E;{2ӊE&Kԙ*UYD/Je.JaSL*4P+DeZ 5 J 2vví.f`Uz_)7X% Xf޵2ǥocs<5F-l=s?8/\G(%F v&aY2N٧TF*C,3XѩSA{ +ڳQ>~'Z #[lGy;9CAY])8LFNTFqɮT(gI@[ų1ɳ<Ežkq_4yc$V$I:wES]dU1h Ur84yU9Q5˩R@t)L*4P+zTbj54P+܃/T@ca2=ե\jTw;f-̐SY? \0Fendstream +endobj + +679 0 obj +<> +endobj + +680 0 obj +<> +endobj + +681 0 obj +<> +endobj + +682 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +683 0 obj +[684 0 R 685 0 R] +endobj + +684 0 obj +<>/A 687 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +685 0 obj +<>/A 688 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +686 0 obj +<> +stream +HWM W85*`4 r\ a'H\vCև,٤{ QH#iO0}8}vzO'3~Ͽpuß[ > Ggc +?O_n8!~rumїO#&xog1vy3}i/wXrS hrr:d'4f.+0#BF +Тs)֧!SVGt͋9>ɖ \R4Z5߾D!P9]BM}ӾCTJNsY)!{op6|%f|(7̷,n% gj.ZM9Zz:O=.]6)1!Z;˟4O{[|'*Hn441}O8  !4u> X[4XYm޸dh?ʸ K0X";R>BXT~-g7u̟pO>B6T}D`cOC +IiE]!<▍; pG& ☷ h6 +nJd{ :v/8aӘFYOOw1n-lK*9DdgG;ѡOHۮ$.YyN +"ZM{_O&-x<8nT#vqI Z@=#G @&ܽ{9z+\֍/MH)ov\WNs 30t{d& ƫ P㹜#,8* ׈z\5?X-gw' .=/]y%O=qX!"^?  qCGƕZPLvZ`t:Ajj.ΫIqqy2y@J::PM&)ifoĘ{g_N&l3/#m{,Lcwm쮃oc}X'ǻzڎSWF)GŦv2UzٺTz +P*5HJWTo+ll}!M'YCR_|kF7|5IA'-siۄYY%9xPDjȺFQqټe{~ǭ.]x?QSgţѮRޏ7k1Í쇨"FܲԎeM KG|Q0¸ۺ"^ ͘ ˄pѠ^ݕ Rȹ0xEO-X_qEy;oWʵ;f; ̬ݪr]O]^?S\ﲗ,Ir@: ^Mѝ*2:N +U *Mn /_TG8ެ F(b}}h3vVRIԦR31E(7FQ]je/:5qEjv^quQ^fd&4O!#e`+z*>ϼ)a=8]<@XUX;|fm^w(^?^;4\9 aܾGRʊ)M"]SԧL!2gV5i8Ec*NSFدK)"Wc56fQw[sR5GDKAQ 5HqhSip06qC1_SecRM-C2QAlP% D޵A(40ZuTQn=* +$[_G!5-ulq2- Gf;Q<+$b*2"s"55H($D;0=,)ʚgG^{$[*u#+Ma Cp5 o"atNr11h,vʵ3/c0(5֭FGTvR4cc"sB5vH +H(YHFR*r5 &r#lwc2$[5F:e1Jnp'_ ^Xuc5lԪ! g04I1 9TRPEj Ha hkv$d""^&,Te8+ +r=8XT` lJ kPab PL 6M)VQlI*l3Ѝ9`ۺ Ie]!\F3c4ֹCEg,n-3% ^ѯekB+6%;*RcUCHTҞSqJ f!ߩG޾OBdhBjYp[eA޵Z> +endobj + +688 0 obj +<> +endobj + +689 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +690 0 obj +[691 0 R 692 0 R 693 0 R 694 0 R 806 0 R] +endobj + +691 0 obj +<>/A 696 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +692 0 obj +<>/A 697 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +693 0 obj +<>/A 698 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +694 0 obj +<>/A 699 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +695 0 obj +<> +stream +HWˊ,7Wyz ά*aVS=6c0 =\*<)E(H ]hp?۟y|5<1A ρ  +m у1ze/{~<k u,ROPRW/Q)g"=y|jWw%oRz_Oo^)! +fjR_r%w4d-%)ڛ oF]ه]ލy$+ q,iǤ`MfN͉)C6rC8MDW&4 ??_~R/CY;,aa'^}kԮc8{9ssvىeGI1GlC ;GzD3:̆T>oE@ =j YvhPF[2$\V-jcZSFDHMǝW7q5*FUxK*=zvmZD1$zx- ؋, uf vp5XЙlR+ԎDfS[a&R +'89ҒĨ+>Pl`[zt~&͒ZYUj2oq*Vyy[-MaEMxglwQ\ $bVav% +'-ٔU=eQ;_6%-m˕Ѷ$}_]ܨU鄍J[ʽ-[mC5L˭R b j2W~MOѓl*̞DjST%GZҨbLmy(h'2%Dܖ2!stU.8Ӥ4+%=&- Ķp>`IU`8%E!8ZҐXq%Gថue뿜fQU1a+_Ui=[.=hv;`[v#os.#ƃ!8R{g"zSnŽBX 40ֶ 8$ZF[eZF[edk=z}Ekɮyc%klrUT>:Є?*(fM]]y#Lv ShH@snĶK2Qޥomeມю~Cm+Su˜J)>|++uShj7hg*Whug'bAo]^ɫ4uP+sTv*_xVgrlۊrH&ͯ"´3dW]x2y4sTn5^}Aj#|rHPnV.hvkKwu6骫?K}b 4#P;MݣOSS4 *BJwxtZ5kOsŸͥ5d&Y&Rٸ-W| {2E72Ր^dcL܀eIR[ 5L`] : I+Σoqc-7xK*=zv˝Y,|nfEӲ > Ϸ{XX=ԪJOdڌQu@d-VFےd}aZkF͘ls%elUAzi~M7_u][nOȕhu6KJR {cTVغ*T/Yޔ5t9ߪvq,!W1Pgr/<tKŖڮEfzv.r 'v^쩽)gr+;][$"*m="5-9㇔_k=%\Qw0HA8N}K3 +tGV +Dl*̮$jUD%1=Mu`T^;P[ +MLni(h/ 27'KЕlћAXNmv:vW4oAfL祭cƙE/r#jn,=׈ގut=h;~gbm)֫~$b`;*0ϫ`UmDiaQÀC AkKd]ꇺV;kn=VR,X~T-+0> 0_Ǵj&)ifu&;Sc >Gng^/PIe‰TiCU譭ڧݸmg!![0BȨ#WP<|$* gJꑒN?'cb +wuOִ͵NHu)kiXEqHe+36q )zl"2}FeFSSi%tL*RTJv?٫W(5v~SnrQXfq/SeD[:O̙-^'jīn*M;ت 0p7endstream +endobj + +696 0 obj +<> +endobj + +697 0 obj +<> +endobj + +698 0 obj +<> +endobj + +699 0 obj +<> +endobj + +700 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +701 0 obj +[702 0 R 703 0 R 704 0 R] +endobj + +702 0 obj +<>/A 706 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +703 0 obj +<>/A 707 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +704 0 obj +<>/A 708 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +705 0 obj +<> +stream +HWˮ+* %65,z2 0E|}%h$zXN7~4?Npxrcs@C70Z38 _D#R?nur)D?8G`e =86nɂ]V;L H{rW6tx6] gXُCCG +K`dGK@sb;[~൜ )¿ىB238݄;5ny7$'6+OOQr%iW3K3[)R*mBmFUwtvjmBmi=ԜP A,C V;Sgh"Oe#;oDJCk]{k BjPثĪh15iTfGͪ(Cdш5 +ع_v- eJ0nՖsI=Js"_)2"K@BBup67iΚ?X1lV"& +tM;b80|t'9d|kO)t)%Xn.E7x{1*6OnwZޓ-xdcrދVmLM]ecVn$~D\ kxs)$5ll4ٖdKį%P9bnYe^|VdCc+di{#x6:_E@>1(r8^SRi8)1K$ckG|ړiC\HuErN擎~ ĭf4+N,rҿbƫܩm~=r vw%>7Yajk*MJl*NҘZVvE4U=Ma gԂ԰j]WsT5W4죐l^vBrBںZ',]A؄KzoZ[i/:Զï\Gðm|xϜ3w wkKKJn֘zQ~uTMȅrJ.ԞUMʅړjNbe"jo(GCn~Vz/n\h9_5|(@.wHø@s]s]6mg6h1𝟉N>OكO,Y}F)pa@*2?Hs[:Ъ+#Ӕ]ye++#k-ݺIKpܬX9alםz +ɭ+y#tǵ8:nәM +ړBj(ԞTMjI ᆪm`|`Ss"l7?xAt{/ g)2em;! s&Tr6 WCfU]JZ'IBD]a=43qWEF|_n+J11i]ЛMӱFl2.L2ӳhlؙd[Mi0{V T/k*VPꨊUWT#\``B[V8^xKA;PqX3.uά*TJ1+mevѪJiBh;袒ؒNA7h^.(N=md>Gq@g`0v^Z.p"?xJf|R5ܤDYtEewιl GJAffrZ^Z?RofrLrrE mv_']19CMd͑#Ľk=Z~pG=,17~Ugl?0 bt "?43<77Pd4؃ .G~G/t-՟{=s1eGC Q#Ӓ?3U~"į+PaD26Mt"`Fj|?w[:_"`F:Ŀ endstream +endobj + +706 0 obj +<> +endobj + +707 0 obj +<> +endobj + +708 0 obj +<> +endobj + +709 0 obj +<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +710 0 obj +[711 0 R 712 0 R] +endobj + +711 0 obj +<>/A 714 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +712 0 obj +<>/A 715 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +713 0 obj +<> +stream +HWɎ#+m@9`prQպ5 =e0\RUA͂A!KRcc ?\`p3?] 0 |?eP\)+\="؈-"0RH3N&xf4D 8$o/?_'_u<[ +N&0kR:cH&g{! $gWirƮfsM +lik$+9GsS=Y6Q5[KڄZ(%+\t#Ё]$D;Ti]rEҎd8fs*`>=H'LҥƂpvV>te|ja3p"jcd}7}TBP.AUdch2C#*mWI굑@{$SepMY`:RXk9Xklc}WotTz +dʂӼDZ](2*\Ep|03yE4[W n}ĝTх +:|+8l!2:L+y;?RG U[ 41Tq-\( ,Nm:*"E_#os+ӥPd{r3Hl]ґIcRd*TO㓞j)>{3Etk Yuұ-&\ _ͺcJ.,ܜCj$h0q Q&`<{ks-$;uBhn*EA\nEf.oCG +?>CW|i*:T瑱scP[yqą&';PX;?c;ygJ閛.ca('s>% 0j&hT {zlrV=9SHb,uc |k:_ +/!Q(-YV,mDwBm]'2-mի)͹osBlƵظ6Kۊ0Em|n̤9T{ +ppj$ uaa'R{·jnҬtk.~Զ玍"Nm睭sU#cPDL]R!cHE)A4㇚f#vxB6Wq-_:b ཟ%I AB ^ꉇ"5 +GUQ=n^9 +G=RJ'ܬxnrCmmyRڕ߼ùB*bꋈlL)S*R%JAl<)O4K ."Zmhf{M#09l$.kf/"*Q@{hP굑@{S-e KODtk Yuѱ-&z O>95Ǔ֞#DrSsqݵwb4'-ޘVp:[9MX'ra.ip}5irӛB"7 N9Gݰes Y#u8)&?%2aRѢb$9Mc*kx%Sk$3`䅬4|e;_6Iښ_dxm|O!8*nY[--Z'Nv''n#n3{aݯ WX/)=fbJOwqr¦\Đ9ϑұ [k(3\|=-iJ x@pږ7=m)̆xu\ +8MZn9+|'"}v<.X(Qd,hM< -|- D)3^Yr(hipK\u}$qT[4uL(%dgJ0J>VM*RysMBe[q?@5.:VL/ms;{4~PRDS 6t(ar@yʛ> +endobj + +715 0 obj +<> +endobj + +716 0 obj +<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +717 0 obj +[718 0 R 719 0 R 720 0 R 721 0 R] +endobj + +718 0 obj +<>/A 723 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +719 0 obj +<>/A 724 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +720 0 obj +<>/A 725 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +721 0 obj +<>/A 726 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +722 0 obj +<> +stream +HWˎ$ Wq9DF*n Çޤ$feVQk0")RP ?]`p?_.v3 /f}߿pe~2) \> o!|BW~ؿMb !?>ސͶm`B0Ə7؅^-nY :zM'x:W.َ1 1Kxѧ:a ލf&7&{ҜǔP`3X~7z(4ZބBDJ\?b/_ynzFJ VIh'Ydı%V%w:J#ڇ\j2Y|\ %uPZ >#YbyJS0y4ɚɚ`oUsd3DG9q{BQӘ7KtnEhBn;?;m-l}AI#xJg_ c 4UGݮჿ?l߁ gXp۴2%J^k,N10s?\mJlh{ !qwֿ6HJӃgW@uyp^Kk4˒H`WuB)u8EX0@X׭_w^SCmmA<ֆx82z1u;-Gx=Yy7yq Y/5%޻vvɇO6 |_aUU,kMaΏܴOYU2 lbP%zґS ;T zFPSjmC$ gDeg`eNz5XR!)puMv])37=7Q@|t"F6dpȘq+s=x:کczCDѵ\-v\[sZLbT=&p2-d'QDmCUUՋ+0N1 ]{g?SϾP_ڑ1'단jUhZUU=nY\#^jm3RDTʄ%9[=^=tF{]бJ=S,/l/2Fw9@Bn_鑞DL]S ' rXS\ao'\SZ:! ;.w،0`g_>Â{NSbsm\9؎TYzzrbb-++--㞲RA٨֠ +R##Cl ![څ/|`'*HTI }J`kY=Rv]i.SvU +LUqTqlR *+Z#ki1fLLRDk*!՗ Tj$E֟CUB6ɉ +Ѫ`JHz4Cb# +*yCO8W+)rB{R +*G+C.5q:PP&<۹ZTdjNA Z"}pfn':oq}Sj~jq/ݪX#!T:ֆV٠Jci0:Q)UJ5zTG_ 6p8y`Ϣv!uw,'C X-=3)a^B]GQj^;^TM),*kiPcRFiATkv`j# YN.HwY``՚0gȿD܂o{ S1ߞ9D%I(IБ¢ +휏;T3 9 B +I/mzDeU4I3| AmtMNzb98W (ܨ7RFEfTdj6Г-&Sm1Ub4LE T(1HBQOɮ5aУ}NV_lb4l[&O: G&6ɤH +y:QE @+g7<QY+OJ,0?WY0 J?8$Hax|,Îm +0'bZum + B]][؝>Rf7D*j[M~ wS\[6=pN}\4Rb-6_:5⬱gBa B7ʭ6W\rkH0UiUqbuixa+'1eid40Aftvv:p˾t9gm y"3k7iZ-VB4Hަx`ZV[7Ɛe@ "0hx1B[A؆t(2<2} + +9V{8& }s5=6cZmk#8,\+b#3<}ҡ7}Q v2<4*M$9'ȣTp} /c>5(ۀ}vpvgn$v:X&Z$x>~X+tۛOV֝5~gr0H}&nDJc%endstream +endobj + +723 0 obj +<> +endobj + +724 0 obj +<> +endobj + +725 0 obj +<> +endobj + +726 0 obj +<> +endobj + +727 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +728 0 obj +[729 0 R 730 0 R 731 0 R 732 0 R] +endobj + +729 0 obj +<>/A 734 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +730 0 obj +<>/A 735 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +731 0 obj +<>/A 736 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +732 0 obj +<>/A 737 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +733 0 obj +<> +stream +HWˮ +p` ȶ x7d1$@63!dnO'H۾::*::4';m8}v3n?pa0coۯ5OP옣ӧ/~Ph O߽Yb;1A0.9Kg[yA%9LL)_Bpζ}iSR,sX/C(c +F +?6L磾ih;7fPcڒGoBw t2@sǜveQNUF9dT:MG,:q=X~Iu߽c}KByOq' rnrh.WgD t s }G^;  CȸoIDV[c +jy%o~|=Hؤ%YkiM̲vj c(aF0;ƁJ<EžkȦ1捆)!D* tP..jpyq9U9LCԃ"*"qUDjSme~y}I(hFx02cѧvۨ#l; `G }z'wu>:*z +rs 瘿.L9SH܆Ng{L&BzWmL6rjfxczzez;rs;%gB:pٱ{LɄ3ךw[<w>JoLM) +15KkSӹf@vQzMRzaw*z("\hElՙ|az.&݂"VD~c4⾉bAiSTEZ+UV*ڒWTE\J Vtl +3*6Q1sotvÔ;auD"15u(D&kLMcbU&bj$&8 Se1\ |n+1#-za:ofW?nOl:IdlU SE4qUNj‘Smef hӳPUVFUj 5VyDRL?*f.mR4|F+E7N|` mbяF*tnPk\h|p: j-YƛFK:[͍ΕfWB&:@[)o2PO=sV^ՎaZ%{-8Xi-λIqu`{?; yT* 2k->9z(i\ݷ#X{/k6 iyPM=sYe9h> $\6͑s)B%9L֮/WqOQCŲdfo= =uMS= =@ЩJ[0?v^GcǜveQNUF9dԭو_){x>x;v|VHum"Uטr^7 8NZ5ט,kW3`DdD^EĞj ?@4д'8fZ*`D-Ss wPڋrnT[[lWxULuw2˫ScR%wשW +TEaJ 8uTPQqT>[۪*{<.6Xu3X`7%' $4 6( +jLMA) +15Ik~SӏfNQPơvLPC`ҶC^ A ٕ/xՁy'6zCSz=LiY‹wuG޼D&KQ51U^jWe;Źፋ2Ѵa/\ +jE26VqMA'2+)wШi4-wI)C1]<~$*~_q|oe'[_˳mmB}h[k6umٷXhк%Mm,h3Iuzs.essbaiPI.-eKuKkxP;PŲfdfo3* "'P;} }F>өJ[0?v^W1 r621SCqZ.XhMX +kcJr8Ky- +4PlIl)4ٵ-&D:&DǁHsM 1&vH o,V5A%xFUL5w2ҨYTȫdUj-é+aJו + TJfSfA#s0&c%ܹhG;;>M_ W 7Zі?ɯŪgk~c}X팛7e[kddXr[<}͓mBOjb~ ~8U ePEk +~KfoTo:S[2~j{_nAoٔTg=&}zڈhWXmmĩڤ--!_׫[ФMiI#Bw])7&J&.ؙ,[rv9J1F+ƁJ<Ež gĸ=L +|y*ߘ*z2 +hTŎTɓuGUY@N +Шx, +Ԋ m1XZ 5J 2ޓݕ`fNvDofuJ^,^l_ endstream +endobj + +734 0 obj +<> +endobj + +735 0 obj +<> +endobj + +736 0 obj +<> +endobj + +737 0 obj +<> +endobj + +738 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +739 0 obj +[740 0 R 741 0 R 742 0 R] +endobj + +740 0 obj +<>/A 744 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +741 0 obj +<>/A 745 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +742 0 obj +<>/A 746 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +743 0 obj +<> +stream +HWˎ+ +jy'@H$ + eƻ Yׇԣ.ݹAp]$RGԡ~9od_~;͏ӏd_O3<~GK1c?N_?\~IfftyZ;GeXOh \ \{1nכ3?=bz<dg" ^oxCL wK7{r˰W 4 /lBwgK^~IҶ)9[廟> cJTd[Ll!Œ9&y6(:\V@wsuv:#9N]J7;`;)F!ï=by#aZYǰaNXh`СQGPY@cw m|J,kZC5ZAr^f<g}R9Y,by^4(z =t!{Ֆ1OK xGѤ_7p#I̲\$"+SQd 1K_oa&z/AUѣeI@1-7 kaTXPזauEƍLpxԭ*9ѕ{IEŮTfS@"(hԃ2+%}&B@''S5R^`FfzV^{xeZs>a+r jEI!1sp_iyjGb4rq9U0? lz ^6uFԫߔ\\3a7gN{i}Sn{;s KKv}FtboK&7cCb$:伂) vXmNgun;E!^Xqg"E_o;HF'tAW +I3dVGM ؑX}w-ݳ eR|΅31~v歮Z.<íbܭ8 Qv /g|e+9,yQߝF1;5VAGBUnĦa=opp&Z 2ޤ9,G[XQU@ٻUUau$~0J.oaZt?.8Vמ)~$MktUڈ!>6*m?IĀFЋ[і9Dϯ/- +3֮}޸lH0gF]1M7 ɪ+\5:LZhäaqc̩,(𼰝NVЕ$'d7n+AW&[{[_oDrg'wG_N1Kz)/RM-Y!BWNYEb4k;בֿH"Y]2ޱ7˃|)Qex1ѷtk/6l.7=>篷Ql`eoEX4.2&ϺWjqH۶TPB=kp\ؘ6l[ޭCg^Z:t|Ho^çkW۞;#`WfәDJӸ\-*آT +` +6Ҁ 7I Tj9M4;o+ +Fi-DW NjX{d߮Fe69&t3{Q'm)ԞrHK >CG[4 -> D5K'l$R7/DUǁn> +endobj + +745 0 obj +<> +endobj + +746 0 obj +<> +endobj + +747 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +748 0 obj +[749 0 R] +endobj + +749 0 obj +<>/A 751 0 R/H/I/Border[0 0 0]/Type/Annot>> +endobj + +750 0 obj +<> +stream +HV=8+Xg8 k}@D!6  MRpfHQ^!ϧ|n?>{8O4qf:6`'2?~zWV/SM~Ƈ4_͜pTs,zb2 H-yg܉oV63`2N,W(G&!z8>OJ~znYCR͵W)n%۔LH"?O |uϔ8cGB hJL _+#L9_ʌ"4dU0!g+ +$u%r' +wBMd㊉}"EBcV7*ڄ;TdiEeL 2DaƐ4MhKlh갼t OjQUD,<ʂ> +endobj + +752 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +753 0 obj +<> +stream +HWK ׯP^R^QrM& \v Q\v; @WŇȏQ?O U_tO;U\ݿ\¿_ubu*A/1TI[Uf ^tv/$D^bĆ`V~v}͆oҚ`d T'|nH]%ņI/"#U~ޛĮ2OuU0\bMC;hSeLO.}KTT[&^ш8VRo v44-އN8Bd,W5\]m^cyq""ulf]M<$ G0=Sx/69zA)sbSNʓ(DwFpX#C7!sKbV'}\V,kynUE輡B4KHaT2(6Zrg˓s䑝)9Efep:nT7D81I]1 N @Lj-C%k&_.[ fVx%E(h?߷`}lΟ_6o;5"`{!.Il1:Z1qLԳzV~6fk{/9^ڦYz^N:u5j).Ȍ3f&Än=qAı$"nd,fw{.ia#J#1-L2;m%`$e?yGbL4ikenW;=X|/=UHIdBӴx]Ru 8@oy0Mt '4t HiWq'g(Py^PF$!endstream +endobj + +754 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +755 0 obj +<> +stream +HWK>n 5r܌ $6l #>EJ!xo&ɍ=t':Ja01&]3&J +GC%|gp x,OfoX˛fI\ظ9GqN'5Lӂ'dDRi-vPUYs;fQ 9Bny +"qJ Lyg3bϋq O!bX}iYboG_/6 ̞K4FˁƧRX8FϦ|X&cB +HqZ+1#9DM k=Bci{ȁ0N'c[Y7E!;dgg7lo3K i, ,X +Lk0VH@ߘ(ϕ`=,9BX!ʖmRq8%J^my_,L{O45>5-k? +P]f_bc^~q}#̝_ɊY2N 5lVRCnj-[s)UK'& 6BȽ„ urKgEcKʬiMv.Ftp㦃gt{Y9䙙l-GZB1?Y5Ӱȡ,ݟ [YS;rAg=e"ګ/h妣DAN+<0DQ:0ClÞx +V~*x7u-?8Z亦(eZ`?EtѵnZeQ½RBZ KPnҾ$$E},({hc1UA\-\cR=k&\gu$_GLzdב\C8DӬll]Dlo߀,b8E. &lp8* td%ʑAcK~Jų.7_v^H<!3,7^LHhLN/2lc5Rװ\N[yNlrvDSGEN!.)Wv+h=b@hFGOa~*$7 #'" HF+"!%عPR8`UHB/T\xSqM*LF؋QqKip}hb8*ib<;aGIFL`m*+qhFG4:z*M=,&4&yHJHQ"*9ZGD*XR@hփ[,[&$vЧdsq.lF3Wp)͊ͽc}3̣)\w{ǘv/'G HwD~GwD^SK8v}y1hy4m6f)z|_ >c! q7xC3#cQendstream +endobj + +756 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +757 0 obj +<> +stream +HWI4Wd H{}=IՓ2-=!L ,@z;MS yptN؝>|~4Nn7Qw7~~Ow#Ot_U~>}}ztI\ ㇉ΓvG"IDuBYE)gfEm +àep4;%fYxR$kbo_ݾGSolzE:I.vN!aΆ0_~#&=@t؞2ƺ#zE|,KVI,8%KtR"=ܴ4In{!8[926Zg㑷G:Zx:)eE*&}O@?C}w- +VcFU^UWYϽ[͞)fe̓4 Vk;oT`-9ΠLzM@H#6?eFIL:ClR]xeҺ%9Y +6!w∺qD6umf?R]Mrj'ɷtP,qt2'uR|\}z $Pk0J͆{;s/cqM V)31j&V(Au[g[)C\*FS\ }䵔\jQG}Qnc&#,0K X) ,jPuim?$5Umʶeq[~Och_V3<7f})ѐiZ鉍00i0g4U0hDIs8瑛%Fl&z]q.󥭭Ayǖޢ*f@2bSSvPU ?|{- 3:e{sы.^\d^O{a< PƼ_Wx;CU`TW;nGgPvՅI8τ|qphrc $^dٻS869=uWI!4#=5fTf ̪:ׯb5w+۬aM܄{/!gЀOpf b4SN9Dԑ,Wrno ;H&cؼdլRgVb*YP1|{ Y"x+floYHR,+H߰?_UWTY5-93 QEpٶafѓ,mn<1RmuYnWqpPvnDQbfc=/֑EUt3yZ)bܵa\s쪃9`l|U !{R9Tfsa]J2P $w>JV'IdݪN5ģ(DgJ" 7v Z flqOX-̕y]Pu1rĵMs*v6VYup(uq{^Öycm Ӓ1M X yV6v\ǘ2 $T3$nkUz`k)3/'b;hȊ.qg#seA7*?lmVONCendstream +endobj + +758 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +759 0 obj +<> +stream +HW= WL^r,H # . ׇHGwIc{GPC!t?a۟ +OϷo't=|C} ktA=zk:}@oo_.bww69 C1ZC#C.{4Xrp7c#Dd,ķK8V_ޖ[>.;ïI1o?bDFQ`1{=>6@H|A"VgUPœVG9+VK"@`ƒc2 gXb29awEA7l6vc9?i ´ivr>ilޙs ǯzƩ.k_`ɗr0>uؗC3; *#ɔ4-3\Vi8>ahuJG+tzם7u~NMecUHjx4Gjh4sCyBRlmm<\֘--Wnܥm 3xhªm(&z kSaަ2Xy`kM&ULnZ knxw +0)endstream +endobj + +760 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +761 0 obj +<> +stream +HWˎ+ Wr29l "  smEqhިwof:nGwޑ?]—[n}?o$(6ߋr.ޑ%Wc= 9c;Lw>X,Bх2[Ki12 +)ZIyhƣۏY:@& xyf:>=UTpWC.ʗ[ >;K>~ۯ(\OD{*h.dlL .)yx*ꩧ}["9H㶰.3h ++wapc[E51Zc"F4¯ÇDqQCL8E#fɡjpB!ay6@ר~cXCYjR4;.+B~39C{.Θ+c UȧՄ9]٨*"ף"En̻ڣjp4l))Ԅ..<>EeH΄٫MXV3ux: V\9X:Q4#SQ2PkqF9rFOO%>1+4 භl<--m)(gvU3[X;;cR@=W[[a_1W;C95rD'wǐͳd6>-ksmVߵї< @f2w9S;xޝ |*eE61y,5jQMU%$9TȫJR8`QhHqbHܙ!R9 &v'p)r%-b !%~'I 5LmK4Uٝ>?DVy%ma(̣p ж8scˍm fbA+Xwقeˁgb +^+ EQ@ ~Ƨ3ϧ 1an&}0inclSY—|#9-,[GԒ Iw::miq(E%%"V(kIViᴤ$m~RW~6:8P}QY06$@v#3ySk9y=J;3ʣ [Z${A 6k0Iiec4 X]bֵ`ۆN4pv4˩E: ݇5zwe6 HOg`1 0g4@_q 7;[@QkkY|fV;!$ Gu 1誰g=5Kvpm1qzٲ] A[%2j}K͡m!Z*ǵ7=n c*{gFkmddpNaA\K 6nc;vz["-/6 <'9ǖ +=P c*VLмi$PJkkt͖F3O˾兲jjcӍ9wq >b`{'u{ku;^u+T}Fr&T*7V +rm7̆&ӇR{AҜ>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +763 0 obj +<> +stream +HWɪ,W6\=fAQ[av76xӽhnݬPHqb7ݾ}y>eG?tRxu]#.!/,ݾ~>a xzWqQ[mzOR*|HKi$|(4T}LlzR?`y\]Vj&^fr+BCjpYFR N +.-4VcB+ՅGa& 4C(*Q`zXF|\{ϐsثd\Ф>Sti&hLM6؍ prӎLJom1_iZN˥mȦ*V؝;Yq`ޘcl"!|EYKa[-I'(594amS$Ȭ[SoVt$ TݳBnZTe.pk*/6\qC^#HaӬgAϡFpC*dU@]GF3w :MuK=o^YK+a&lW[{L=d-N҈Dzþp'1czKň*%26W^'=[gg'jT_* 1G,2k\}Zei- CnLOR>5z3cCdRֳs%XNjَE~Kv 5#KK!?oͧ'`Az_H>mX)܏.O7#gOwkV+LZ嵦wܸ,kf0@E-)82h1zbl2Hz `L=ިEۈ^jT8&lG̉~6Zx/OKtnLDyI l +QBH3^*U^t-LJ2DYZVzB_P!/)+Z^L +H{m!y"2ݶ_]:y:e׺z:X2J:ԔV!.y<^&&iGw0Fupoi>S3,w9ϱY1VW 옍u܈Q3LUS.4fP:Ƭ6%(3woj h{c) |Wy8dyV& =lF$AS0X5ܿqb0zVz\M,M8 faTd[̪{ܷĮ?hYosb S+n":BSp bg$s" g:QRVf]#XR"՗:a[魃gO<}sgR@tZГ:TyNq.RC̙Y,ByvE(8J\xx%.L.^l 6U!#S 05} ʞ"a]a٦DXAYّ6j%Ԛ{緕dB4MhhM!WDeܖUsIL`_Bd:ePUOiIٴ3^`P +qY\n7r dz'&M ۨPMbUM3)+ƴd՘R%fdȠCl`ߒAy%0ݡ#1j6*ϟ(jI3ͲzvEyXXko4 !.\#.ڪhU!ԶBՑX"%jU[S|Vf[FĶUҗj;R0B`J*5"XmLI32N.U:Nd8צn7V9I 0Vݰ,ױLZ=(ttsoLi*GJ+^FS{3OR!ВjHK p-! &oI.=1e~7S ;zF:[zjNl +Ma)H6oD/iB he0"2҅a#V>;չ6JL2:Vo|Zy/M=! 'K 'endstream +endobj + +764 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +765 0 obj +<> +stream +HWˮ6+Lff`\@/Em@7ɢ@3"%6&t8yuݧvwݧ/vzA /Ku/W$794w?On9_O]^29C#>\`p!o^{;l1qCdo`d g = ɡei]jzzգvςQJեV}uuQݖb4wq+u.Jl R?nZBK2B1k#A<!f'.w_J֒|Q}0晦!mE/IdCil)0N59;Q"~9, wx^v]I ;KuC$Lv~"Eܶ7wiGY'9~Y$-}M5sV(*Bg/.o_arBt +ֲ-XR)c1$^^'[nP`K C̤c|vɧ ėZ'=5U|j`eU^[\`.uh+G/F %kHlgWm:gҫ0*Bo\+Upe +RRcDbL3FlɸEOUvYRQ56X0獋ݨaQeK~*6S~ozj_M}R +ꆯKz:dPa<4NDtU $fE|uD0Gd+ɳuzTU'1lC*56`R-тI-Ʊ_ժG'Yؐؗ[ d ڬ I^!R9"A䜜d`WfJ#=&;|vx`RTdLJ~ox{H&RQe^CQUG s<`Dᮡ.?UJN$lXI2NGhP?eJZ>!9Mme\%iG%0gL$Ju (}:JAxj$$Oendstream +endobj + +766 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +767 0 obj +<> +stream +HnF~ +-5, Uzw1"\dlfSnu+,}b:* ~f|}z5  fdo߆,Fs1o<͌?$_fE]?15(oq7ƭq?Eh`Jk +=,AuCױGc%TM]/963OY䵦M0cJ"..9t/ܖ]<ڕgV]{m> vDF7[ڂ7l<;Q6T>pq^YYr&['VOhyR_ZD;bC  Zº׏Íì4HC`/{ \oe&^j>;n99rMBv/UC9 A\lOdGh_˜+nȸXVڝU# b(UlGjwS!,1~4žS׸WNE^krdk%zyQ^/Y~PXbxdz-(_!̃ʐ_+?iBzЅ}ã/6aZ3hI MVk0i!f7_s}mFJT666^f4gjTOy$@Vu$-QȪ(UM0+@U$1"T-6NEG5N XN'^6XՍz2aÚK6G l`X- 1PkrvM:[ ߯MͧSzP Q ̊?5*id5QJ5ik@VAMAƠ']'tLA~mls?.Q`1(Z°ʣt1`XR`1îB&ASȸߛ͎T/ 3Ys>'P( +Ǭ7B +yul^ +m)fђ2#LH +&aU<7G禐))=oCtJ@'qɫ"!R,BΌA+B5} )bVDX* b]e蹁-mϞ;ki3w8;= [d~#=vVP qQOZ` E+6Y0* a& {P=2mGdoe<.WfNQ)XQFE*CɎQmP +hd-eVoZh1G]uBݾA]z\(v +6<1%L3K1JKI^@=S*˥ͭӘbY +(f%QĚP5 2!UUbh^;wLÿ́UW#T)~R%φ/5~RȽPog!?b%R`9#HtX҅a j](<tJgrsgQbZg &7 NSz9JmGUOW&Z9;tŊV +,ZXzôКFKʘ60mr)څiO.L'cZ^x>2};,g=~b*)LSA.Tv8YѧF4&}*qV(^KXowFI[>R锠o+X=ŷ9\Hއ\7M#=YW<`@endstream +endobj + +768 0 obj +<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +769 0 obj +<> +stream +HM6@<&/`94MР$,3$XGc iԧ?jxQ ix5MF>FM)zNojʥ*ӇwLQ;< B>0? //4ITx^? h!3F`/#V샽1vW7ؔ~wӛ< !i *UFco_>n:vM1gmACci i4f@[q$%CGa"l_-ZI=e錦vş4@.r=zZ4o`vD'0˂aGә̀ Dr%->-^;t >ќg0!amyK* :u@e!dW,k5=a^6^-k5z[/'ZAo,JeQr*&?BjRFf"JR).S]XnUB:gm#-Y{jMla=-Oül5eZ5~^a+LAMveMD/d4G5J=T2NPc?zΨJe4/dendstream +endobj + +770 0 obj +<> +endobj + +771 0 obj +<> +endobj + +772 0 obj +<> +endobj + +773 0 obj +<> +stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream +endobj + +774 0 obj +[/ICCBased 773 0 R] +endobj + +775 0 obj +<> +endobj + +776 0 obj +<> +endobj + +777 0 obj +<> +endobj + +778 0 obj +<> +endobj + +779 0 obj +<> +endobj + +780 0 obj +<> +endobj + +781 0 obj +<> +endobj + +782 0 obj +<> +endobj + +783 0 obj +<> +endobj + +784 0 obj +<> +stream + + + + + Acrobat Distiller 7.0 (Windows) + + + Acrobat PDFMaker 7.0 for Word + 2013-01-24T14:18:08+08:00 + 2013-01-24T14:17:56+08:00 + 2013-01-24T14:18:08+08:00 + + + application/pdf + + + + + + + + leo + + + + + uuid:a87e4878-f107-45cf-8bed-ca4ccfdd24af + uuid:0507b3d1-0e4a-44d8-b09f-b0fae12c51f3 + + + + + + + + + + + + + + + + + + + + + + + + +endstream +endobj + +785 0 obj +<> +endobj + +787 0 obj +<> +endobj + +788 0 obj +<>/ProcSet[/PDF/Text]/ExtGState<>>>/Type/Page>> +endobj + +789 0 obj +<> +endobj + +790 0 obj +<> +endobj + +791 0 obj +<> +endobj + +792 0 obj +<> +stream +H|KF!-xZMg10S7x?>>}<{t]ίv\u=HryŸ~x;}|>_޿˟>1<__Ov|;.å继߶oIϗa{?~lxݞ>~~ ̇;#7Q*[m36'rNW{c"{B," V: B7( BNh&E=&*($-*:+:3֯Xh劖BD*hCʅo+:XZ raeoUW?Cҹ.*)ѣ%%*k^!e-Ks3Ax,h:$I1DC ɩMXC{ϔ}Or䲽mP{PzP%2r!C`!$Ed" ʉuڣuSvU9rP:qtBڿbX A bg-^$ +wdd#7i^ZUD>doo9:VFVzI*;ٱʎyvFe!G%׬ +MBnFٌgn 428:G[c2Vw\rG?}6 Vla%]Lu ^@El@3!acO{9,g7Ml --볬oeXձbcQR { {mS RE54bZt@uYF֛faN:'%sRƒvHu3S*TYm)ڎ:.ChWV;Nd8,tQ : 9F;V=# ٨*:+sS۽Z|WWk"E:TEҤZzIY$  -Zn2ZXco^W&fc B +Rg:+{=5fy)9oQF4H"B˂ْY${!Aʬ=Zأ@E.HtNjxb_=eNb#'| $ zEI"|U'1ZךE-WTŰB :*w]&IiדaYE:7IҔLFS&E !E*Z+f㞱䬁6H;uGNNwd[;/">4 ;1enx$foo{{:oqJkTٰ>c}CV ROLm㞇CrjU=ywywנɳ]uK =(cTA/Ĝ{87;E< Z&/o v|YׇbOFu&m^+҃3ѿZ8 |ӌ^g'&h3ӣ %?|eQ=g ?a%=[tr:uU9YBR%e^lOYgXXtdNG'י\wN@tuAXNAg(tZ*ҡ7ՠR-j$wTRftOLw{U^U֝T"qҤ7I'`?c7K8kb*9y98hHw4\FU:?|SnGνA9em9&Q[u_6Ioȭ5VNWVYTtJZTI.Ҳ,J^[.F94L#m6DF ՕUWrY"[ +Wܽ H#39"3+\)&igQ٫G987c6u5n-5GRUH93YlLԮȮ*"hI/?+V6L+:r+rA馑AnN9N0CL:Z +Z +rѭhr< ++5ܩ;t"gQ^ꤼ:ѣ} E[5ݩy>H;v늅좫7?f' 9{䧫<-"W9hdRD(Bշe[U o$I{o`29T尳S9іo}9lo@}$8v*t +h׸YM<%_+iE3`]9AV<ģ#r.oޢֆ:Ҟ;Fߙ4uL}+(r7"7vo5VP*;J XP T^4Nu;WV6dĕ#f\A"dBdMdm2,igxxvxs V9A7in[M3ҥfFmst +w{I/:FtIo}G76( R` u&!Yc۳Vg>G&.2N|H|=gy'{Fq iMPz =A{ϓns6sw!#8BNE&Ks[xsҮ:Y>'ҸM+`% +r7V8smp'GY,Y*zee㎶wT`!Brz:Z6 6H,иExqlEm5dA|wIg,2ש +'Ը +7nU_KnGQ.Yٿ+r-^ә"wiW{] +?6D~o Up(Bs\Xրp_M2p gbZ%^Ϊo]h'I۫<6!|j|% +VEjxnnu92!vvW}SPvm+c/]e7,_z v!}z:ZA6 KZ +*0:m;t>ܟ~ v1)J.2(ZRQ*eB +j1i΢oMsuơD\ ⌒"Q..0ab3 %bx%$)"ePBVBpx %˫q %v9a!(yb,[Ʋe;P>F qy59f -G|#v\(ʒ *Qvi+E& :GqPeb* -uU̖s%~˒;w ˽yJn(OlPA(Z46bx<(1q.C rQQn%b_YÄNg_i8bpa( +bRV)ybz0gBZ b(BI}FbL]);ADEFɫ4hVCyR]P#@gbWjP#ՅN uo2Pt(m,+=h}8uQ@vPAvF%w3*ȪȜN ybˉ_D%e} Ym 3gc25NI(b"6ukT^ %tFx4I7;ڋQzEKO( =bw.wuѣ@%_v~>~ڷ~}z~qo|}KVE +endstream +endobj + +793 0 obj +<> +endobj + +794 0 obj +<> +stream +HTۊ0}ẈSvF7KP +,,/뷰4qv$qH.w$9[蜹9#XAvw|&kf!4s9aX!,!*0 +4> +endobj + +796 0 obj +<> +stream +HdIoFߎӧǿ??}b=۷/?tOOݶ__痽{D|;ۯm^|w1M.O~w#X5~{g +Zٵ76;)fez.4 +@>Q VVY tҹД͊&/:֦0zx/8^ +4+שQMW((hݡ=ϼoe?MϛE9yVț dsj=֫ZКI$--G(Y!"+5d(THo*j*_eAYnJ$dDz;f%X̆Gg7sclҒ2+cA[,Ā/N]Ln] 4.ªfvS$"-:z\ܾ ZDvYm"#9ݪb^=kyk&`Wb&hĚD[$_8/G׼HeؐX&{k2 փ4%60#J"v/&gQz"/\x6],aCJu6dDK +fSPzޛY,9+aϳ2T?Td[t2[:7""eY,k?Sv~DfkNʼn($wAn {sp%y\,-ITErEr8'q|TyR ɒӤ{jWjF Q%RJEhv +25n `aYƦXz; +IE@J$ʕHTHKg=~ɋ(BEC΢heHyq>BCaj'ޅgcmD!G.3ۄRZƲ[\Bf!GTEJs"n]4;:+'m"|8pnz™wyϕ+*kPYaʗo1fQ2K]@5ŭItݙ1*~ao**МCɭ$GW]ŇMGe".>1I$ҢTآ '8N/[^z] 4s}P "r[ +=i#ZnKneF>B?ֳ֧eKQjEk ~Zx?:hڨU'ft9)QKz83hȬyU*?0s3* rĐs֊:.W8DJh*!2D⪵Ik4jh'IH0Z\n0}rޝ21i85p¼9hEzJrQeFBXiM5њEIDkb ѭYiѵ܇sy N4B Шڑ;H:lWc4gӋaxy h7QxDk$fv~>dr|.9}i7Q:t|3L~CoH3%Pi>j]K` ~>B:2tS +zYGPQ2u__痽[}{^߻km_׽{{}Np +endstream +endobj + +797 0 obj +<> +endobj + +798 0 obj +<> +endobj + +799 0 obj +<> +stream +HWo\W?c'񼏙73χ''I;4q>|5!)18UMȰK*PA` (, {3o޽{IJDY^<]gꯀ67H(Wo:߉K_uGIj}m՗:O-ѓ:qk7ȺKK_$ur˗{A|>/˯X~wWE~6U%%+ozЮ]P#AzSJg|2'ʣGuG~ = X`A#Ȱ,ɠl]2!O}|qZ香1?ZX{Z.&eZބKr[h5HSR|VxS/ ]]/)zz>h#Vڰ ld}29_D\PbU'ͯɱw<{:FO6Lc]Y~Uq=v>CП)ʋHy*':TgCk HCz6еG<_Iׂ==Gfs=O> ~g9V_8V9c<8 +8 xppp͑<8yIY')gNОqҫ9G{g'~7H:acNq QYHsyFi,e.0NSѵ"pC`P&smUCx>¯$㱅q&q##,0>%~cF?HŘm'? Ww]ӓp1p̈́k{~r>I̯m"h^jN d ;&璮֍]}/^Sn'_ekZot꾏ְ)7&Eo'4A->'toTiw&HBkPO\!nQlL|lϭ4i 1 t_'ݔs,]SD{iD\QL2 &uZjޖMAh5A]H%O體 Sv+XQvoja@vmCK2.7e3nMunAEOOr혜vn(Fp=| +mF/9){A2^,` 5ދ('?yh9*gp? ;^E'*,6'}gr: +oK># AMÛпvA5Z?m4|\>)kJ_"ʃڜFr$܄xOrx K92. `q*yZ5ݑEx^Ú,#!gaC4pӯoe }{N9XNbf`i-ފK*Wg4ZZh+/cX\ +΅)obêd9|iUpN>⛔оy{;ʌ᨝^*'iKM8BR:+|qzɐ.Q6l8lS8u0Ί,g>a}g i(cUh?J a׬GL#`Dp1he֐;-cp友Z<g@1j34m!HǓty :$][IŸxm]D:QL~'ӓ1=Jڕ ,*iJvDzF^btG26>ynmMfeh鮸tK8 xuG9-nQ#Z\].W;/>SϥvTBd!!g1oRb,#JɘТZ6?tFE9%e`n..s\l\~YFrw0/54heUM)1 qYVm]/wZ,ܪ=EL#YpՌWpڭMd|ѻsNyv~ȝEs.d'\|CFoυ*t95k9rOD-ernU39|5kzkUh؝}rl7ӍVQXW7lm +ͶS3Uޭ6l]⫖5˫Ahb9UZ<`,٭|WYܸ;=53/_DfHy"n P(Ԓ<?k%~o6ԁ=Ε/sk`O: q`lAWoBپk8`-}Jj;N3{!&Uֳ`h>,DrSzE;Q 3-T +-_@:`yj,Z ηKNWY+,݄% F!VĮ*ʛq{jXhvYn-q+v~a&]6!qG_y 9ԡN xW]K=᩸z\;e}Юv<ңhbm͆ g,ЌZPVD|Y+r[s*8Iӌ"o7٫ +1By ZĪyDI'8 }ֿ]巷Ϻ8WE4\_g/@瞩gU%;חlOn~9;߾1y}==Wހ4ҫ43X~덁`1 +Y!;w`;A}cO 81rO3'ڰKRuNQ{7Oҏ{ZyI/ (6qEr {YΟI!kxi@t}m74:%1̨XWE{0.>ؑ?c:1, \]gmܚXLQ}f@ 7|[?c>sԝ5I'CO}&u.**^MvL_&eʏ deQ/ԘUC~ Mf\Bf7r*4ZvX#w nu7E,+> @;d7`ڈmT̯i@R0(Y2ixh]RN}Ze`m?~Jg{WX%}g5tNNmz@V,⺃ɮ>/DmPv%!n2Ѓ.?l"&r<8bJp :u~sgD4>/U'8~z96^C/v=g 0`o<%ewˈߦ0V!kFemx83DŪb׻Xzտ{{ߐowAw3 +U;2>rM6.c]qVL#bV%Hxxj~tsփ:Ŭ^l]xi^CP 1`fG=%s~!R4}|aXfH)- Ֆqj'fsF~K^*gLݐf9 COwؐ "~Ev/+VFO '4cDϲ`|gmXudUجx\gbC^OQYӷk70<6H]M{c $O#MNAMϲvip ylίARfY! +S6A(0JW5No6eE܆"a{y z̊eͣ&8{g[yZ*T#Rk /Yze[)Zv4%XUڧ]gu: V<\ЪzdZcIWFgś?l6#>ON -~_[J_/|^oHwkټQ>;;K m̂/]Cko$~928oQ-vyoLfTE6Fh|='+ +z_,"w;_,5$_uL[ Qĩӊ ։"}0y׋ꯑ5~V:컺>X + +[K]XLC6(1VG`Άݬݨ]\H_-WӇ|^,&i["e݁^#+cdMG: dlSNFd\ (nTFH=@ ]Ef!sO9V_eKԵ Ĺ/q9qXõ*JVcP 1ixAhh{Ce \U]dOL2Uą :僚{p̾N~ōP}3L#L#ryh㬩F骝-ZOwNHdH^Lv3!6x%᪴W&Σ]25D|'$"5Kn߇3v%L7 լQh![E`܆ebzd$\͌$-V:heY +0븑ĜR"p69+}$*|vM~1i%ʑPwsޒNAsbTϋ%lbLdԪEv${4ێ֌DY9Ӗe3lN&Lod;ͤrp2Ru[-xbX@FHj[6o|wZF OIDPMI%ܴ;}Ch^@qOD"G kz#_4ƣnu9'sqs?~ΖjD^C@ G:Z-0Q۸>b0n4& [ESbWDk0)Y{R$iH D󨼪cl-j@ܥXz`Z[2]s\Ƀ1?ѡw\$r{+eZz,<#X"Eq.uFDR't#e%BK7zy^b"\(Ng&x5|) :e‰ZNnf)Ɓ؋~GR;\SH7yxbջ+r7I7#v :$+tRJ5gV vWBud0t)LU92LQM;eS?iN4mt8큾ubءBjUS@mcPE[Ŵe"Lz0$)z(UeNfwTv$gh)N&p0l67Z2Z? q*j+O04{E rQ{3iZTi;ER[%K_K%y1KiNC/ٍ1i_a|ߛc`@ߑzPu':mEƼ5!7: +>׳_|?ڽ?P;oᵽ}ԾU7{{.8:uShpgv?cZyr֬ȯzɦ#k +n=xtN ~Rkq3xy򌒹OoO+=GpO<֕I^8/n *D @ŎgϟK U'W WDrٴ,wd~;RufwΩUS] n8uk':%Z9&c! M+:v-InA>h}=ǎ$R(?Dfp0P3+ HԱ>pGg bَSFN}(ۼuN*8ի7лȭXU싈bed[&_^!1^7W`27y7I6J;֩ F|9uA6wݯ7=͊6K{Ӓ\X&1i0U3j!ώ~Z)¬[ey]XxL|9 Ytiu}TO;Sɍ3|YNmuNZz$͇os6׽j)/o!^7YU;V_'?W#zU׮o 3XԗE]@M@'+VV]|" gNHuI|瀞'sn b']Qgx=5>,+]o|ؽ#!dCAa`{@Gv:'|ØK NW ;ŀYM;Sٜ X9Y,IDģrϩ&cSXW`',bLfy2m2ko mnq|M'Ta2[q233APjCՕE̼aE/+)!EDM ;5eYT>Ó~2gҟ+}Sd$'L&E2טdJ nQPϼ+m߯(/Av0}xq Y4/<6=VBe~:$nVSYߛe{R/obGNnŪ 7*݋(9Ql' GrfDin*&墝`ưĸ];cMN1 eM$'ˉ Umh/¶8 Pp`GI(Y:+ƴ~Cs=.̂&|v YS*3'bxرdwiE%v ӗop|F}8WU3y~}`W\ljH)|}dI OTVA]Qy>>ԭ*Q]1#urvj!C +&<>Q9aq`8vUeo٢/6yd3A uk؆#6^_:S-P8'v/H,ޡWtź.Vq'ϧkT>cTv}6}հD;Ihrͫ;XkЭ#ANM\ܔ/Ndka; (&EKVSw}u dCwC2 5u*U霕Yhg=3ך*^BXd<wGt=9ΪЙ}@jӏ~ӴBB}CLC1WUU;<'TL +CSNąTSOjYn)N +Xj=S4=#;vyY;|"ʸ ?p5rye +Ŋ̗,_Cc)Q,vw_da]?ӊM8q~oË{Q,f3r4|kccN IwwIt*mrkvJT_OJ[-zT\<-Z>wxM@GWKw1 ^#aH?p"DJC#obJ{0E,4l39r~f:48fG;'OoپodqJ#<2u1$OSt"NS,NvvUcvCV"+ 6Rwޕ9VwVxM7u(I\K"_|%|o Os< ҇"6rbu}֐ٍWi_9EG_bJVmK]3=e\zST<>$:iW6YSL:16vPWMeCD䲁x%^9?> JFCMc&[g+Hҍ d +BJS 8)tBhKz7Jo=ȳú 3˂h{g#=hbP2{]{O\RZ?Aő=a3`yzJ]}G!z&{${jߕ"j KO8$nf'Wt7GG2kKTy)˕tZM cy|X];<y)~YVbrOvAJN?I+5j7?ͪ#zC.I=#^<#xJ3;Jȩ3e<ϺpbB풧TvPqng^iE|oEu_PIWQgG8i*d\-I Z8bl]5߁$u|\P1G{Fq䪻m xbV'kơEh?|vʪS7]WJo}L+ƛ\t:EͬÞ2+h$:e?ͧ'{{ެݩO'ͤhBf'XzRzϖ=kx'fK6\i._yZdjܣuZZOi+Z^諬Pv5FVyYRBo7K26/jDdD.ElBl \mqSlocg +_!K6iGAyYSf|& c$jL0lg@%zF +0L2T]IQ\$?5 7=YD +*3*O*z.=+5¦+XF +7y9eS3mr3>3|Z]$TX_+LG>Q8US&rUU"[z1tSGn:j7C>lo* +&q-7;]%_Us+Y2J-:/8q_e*+ + UVTδ7HUKj+^֣2 :cpgeE1YN S]/< a<!\p꫸K]0_[x CSq`&zz~zzև|·h.Ċqm> 4Q!agw0546<4QLS#o~7G?y؃;ы_N@8e]5ݰp~_o?Rfhǫ^ӳ'}h>DE_U(֛-ih`hG؛pP;d,|]n["! +1rp4Un'&ZOXct$j=f%#ӥj\VKeGzN|֗G۾KFz=l,Y-CkhjrjrUb\iLv]_t'tYii#قp1$YLoқů g9Pk065T3X,k<,b)<蚄.o9Ojl}O,,јh4%.)L4G)J@S\L,ag`쓄?H4x925 as88 \-v9w|W2wRnWt^k܍ BY20;d75>ݒAu0* eajVRB<2.V on\'k _/$ܥ%1f 6ZgdΟ R7D_Nunr(bw9d<+B぀gTjIkM@^J&k#.y.a+{B(#K"sKJ rx(I8$QYw90n87qٸ_qm|P;H߬ 6 8"3InǭJ]I`,X7s3wc{f v!֕ , o@ V%JRMJ* )Z6K +~Z~[THU%Q3cǡ{|glw~[>AI82Ҥ[K3&_~}"|&!a S|񢱂W t _2kº$2dCdWQ0x IƆ,+MI)55.PQETj_@1[޺ +GܯZare>e|Jn|pAvҗtSAnXe'rBK>mL۪jׂ@V]"*`*Uf0Dב`m xcp9t%h 4qI 6CBQ`e#/YȲ7` y1wp1i,eq5PW/ EDҸq8 74N.'O^Hz:$~I`@S2)xRϟ137gdߘʶ@,q{[6,!P~\UV öjG!('mi@(P]d}J>$Rzf:^`!f'ȁ|oEH j[{{gxBHS]ޱz?$E7=LG }/7ЬĺnmԖ Gl{+6B N)9j:Aoɲ}Fd̾BlT&5W}|~Lسm-z(1o"E;F! yl_QU؊i2ba@+j O\oķ7 U:)/ɷuy]UTӒ6@Gehz_W +rRF?1S1:Z#϶qzUtsXKx,OM5'Z}uIgj( /]BWH:D1,cf7ۖՔ"4xgm|Ds*{&#D<4<$nϋq|ه; B +t^ b&D0ⲻdIJSTQSv2d!evnFS>xn+܍.y'I*0>N-diكJ$EԬ(]81 E#d}0lN!Q7$?>m /ew.=ЧM{iucUᯚ2X4;&`*dy Iq\YbZunj}I$CSʓ *siqA))w:7ys9m`5A6cٖk=ʰa$mbI^qNM7O|`Lb’cRC13q +;C ^z^:Mwp$3y/)%뚵h@NdNJ$ k(+$dn ͨ&Ba  J51Tʪ=B8"X#H2.[x2+ǚ)):ȓ@D0vG.<EWze{;g g03BPxhfjp6#I{"H&U㦡ֲYGMRO^٫{eO&>ka}o j`M-o+^Fu{+GA^\*A{MlIlbP Yr%m`;dB],krPUeTJXKށw4y{'9Q)̻\7>p>10w +GbVJytXs^gUj::go;c1^X46%NZ@*&E JTA--!RPe!*A+d}@v[)HUS*ЧJqURgfm\Ծdֻ]Μ?wS [WR,8z@M!\:o?'[Pf8As%ה7tMH`ė6=Q?|0G7,%(Q=P,F%rn3,ˀcLup57))A]lnzaL6Vlʍ\w8 pYO'7YDAj9MQiE>XSmí[ +𻠍*yqu=W?UDϝO%4gNAlHQ}QzM4SU&2t]t天ALq%7YӔ3N*XǕb`eK٠< +J芿OV+Nd4qGc{!n=zsVѴ{1XMYFXj+nQ -\ +j@DamF(TNPEK||z-15RxxȨľ +p$^gVv,C+eu)u-KyzzlE`̭%&nY쀦`:R꺴-ŶWSl+buב`@^jzB0Ki$~E&Q+^xU^vC"zp%|`i\݂WYvqY}1찈 +}Q^CPrw>lw\^0f$Ŝi T@:O(,g烢燁K J} +W\ 0_uVO+=V6S^1eN<F챚$($9"J" /5>)wR%ԓgQTg30pfo`C 4 +*^[n!+@h5z"_v^qTgi0(}љ3aAlQY8 aQ4 j5>N@Q=.QJ(j&B(&x($=qGL>vmXV/-Ec^tXɚQk݌tnvXvi=x}'Ie5mdh^5-6m^nY"dNY,>gNX?=oẔZg~P|:ąK͏T0 xS ՂD?EE@WG ii>9N0*0$XPܥox߮ڻkH*O};=P_zz s6qbH zhOdߠ7Ĭd3**f$蔸O+mh(#=$ȓI:)J(5IIc&\sP +P9 +Ȕ f m2ºm0<}‚rA_ڠ Oqj3^jJ<1jIoXv ޾sSΌ3A0V;h xTU\R;^qusQ`Jo.\ٿO]Dm}qV,.өgn88Dp9kM qTj۴9p٘Vd*Ǡ&BYKin[$kh}#_Lb+\ ^cM+mZqski67rK?T 1+k[E_A͉BGnz=Guž㿢C5u=ejQR%qR[F(罌j3sܙ]ۻwכ vbn4k%m4 DM -@A*T@*H( ABO@*_+*|B !"R9<;wF9;s&^,:_8/i^K2:_`K!][1MblE'Hjb +=4Q*>k.zYk&~SDZ\@iyTѪ5[o[BcˇВ <ӱmd x$ڙꞵpɺ>v]Ap$\2WĦ3iZîdis B&qp9 0x$]"n/+`EˀUe/;>XQޘ\e0L"M2Om6 /#}=FѬ5~.uHNS݇&z[g\(ie݁ ,⼶Qn-ׇ`v-쭾HC.#aH7Yxcĝwdry%aٗe곘4)MFs6oM?c+(PY ;Qb|tgpNN8v'`|lF'd-0SԿczW +Ȗ6+՝蘵sΡZBF=CE˲i>rYvQ48^`v>)xArM_k}ՒmKqb(h-]:[vdfaK&TsVl>bI:q.b0:O.譿Vvtl?qi۔a~My -u*!P.BF%%yfp5;0?Clm53>mᘡF:c3B/󂫍0p{ kP!tm Ҕ4Ohatk% Fey q"?=14hmt5 #4_sssrߋk6/YX:/+N.'R&'N4oއolj(l#HJwPЕoPz!M2&r4(6>R5AUӡ)>`#ԙE ;"{vN^pܿ+ZO&6pkt]]܇w@?~=d9*+!ZBrU9U]}.0AN=xǣ5%Ԉ0y`/_".mq +^ÈiL +I Ĥ,MtC]U +%:Eٶ1 Ll;ԨB%/7]XK^={ zžسJ3O)4 n +RZe}:RFȰ6ۙd.-^=TEظ`heǡ6zq7%=MM2A"7*RslARQd %XhBrf ]m46wCQVZE@ +p, @H,xE{zT2L!<MSC7O ۣ?U:ZT8:Yc w/30v;Lu:*5cMtRiˡ 酠vlcI㒭Gf"x~d7㳝%|F v-n~.А|jFÍSjuX1ծ8 +LgP+ 樐e]=&z +:+! ]Js9QqA$zGA0Vy&'E^N'O8'ccn'$R;?Lno3?O +:R$Ul. evx׵jAzޅ} &5bzQ>7Ch9 +Vpt<-5@A:[ eg/V*fx¦IDw/SlWKGUuuUWuuWvgvv;jfG-ke=81d9J$`C@ &9c@(cN!8 &zR<03ӳ_߃[Euzc@cƦF1xcSNgGfwxf< Vy3"s¯ zz/ك=Q;_8ue<;_@'*ȹ<\ nfjjZY6װ9:x<XBf&b8=|id))8*Z!BIJ '[Na/:89)>o=4 5 + 6DHi<} sm ϿcA 7q2|MDh5P\qA:i𽆆 3ݎ a޹Wȗ!4i6])Z Sj24< +l˩莓XM4e2H1bg9g_ZA`n#wN.tc>qا̇O{^o$"T@hn'c,U\a<Yx1$aX,FI egMsrd;0Nye;x%EtaN[m'_#-ӀbL`Hz=׵"Gd f8x.Sy0\oa˺˜45-d w}|&3J\%XKbA¡AH_H(0eBw6K'jff{RX,fgϮo70x] o#-|W20Y ؏$p Ɯ@Ǎ\P`: eð]5F7,Anbպ{Z Z眛?p4Ċz. sD;opHSq> Z +sth,zFdպfيH, %HJ?ft S -hX +=X($vGs.F4M:NڅzqIKӞgCf~ǒ771 $ +:m_*ZWBHSłUB4[G.ֶRu-߂y${v VY9:U 3V=h&Xm5Jmk52ҭGO2`ϲ2synÇaobrtI#á*ì"Nm}Zz:R_wGS$ӿt*;cL$2orPTK- -t;ӻOv/s|y':z`p%9X klX LJ[$L!#Ο(3XaLLYhUfWpe#K:㭢=QY̏m[ޅz76LzFE|v(qX29A.{uMCE=x:[s泂mMͥ`xt}P'E^k)rԯ._VyI_2+ v}oc.B_.ؤv:d:GlqgI u?DGa@8K}1[Th&xׯBa݉dv% Iޚ]6=;k$wL2L 7>8aM?Ȗ+-[v&^N[Ws [HW&1O-,T(gCbj?E|ri)Bqx(@?smZDfdXD:0Re\.}#\BSR/RGi6]N^"r0u!$!%=ЭZgv&Ӧy Ub+DXuV@wKf;ɘ!ӏܦv ˽'رx!&t@'׾ەㅚK=vI P;7譖Fʇ!v% !zϦP#Z`Myjmza4T!茴8S(: +Wḱ3ln\dlִ]ސ*fX3 .y1u>D8ѻsPkWgZodt $4oAXo{փqs^xlR.aG-;L} + f$"X`lMؘ8I7ϻ" )$my? Ys,=sdCA{7F T?V wfm,,8f+]YVl=vEZPoUY>'QDO $;s0hjwd O])ew(5JٰYP>yu^OtN+6kժ[0ԧ=s9֑6V9CV^AF*ݜWT0>YWWr`}Qމǽ-; fog-ϲyl>O⎓'IHr6BhuqW^MY P%]-p2++~ _sfy$զ^ZR:q%]ndgG=O¾RK`*rQ2&LbukwN@v.J0@+i2loo?. fy1H5[;l|võ,F,OXS1xAmJLDQ->o$ԍ T\(+ҏe58.'b on:a0"·|8rh +^sΆJSV]j +SQYgx`~ǹir+%o~2WwcSb8:D\gai)sy{20Oa[LtG\hA_&#,X>;mH[+,OM1+NHNaV  Eo'IBGJ}B{I 4uQ&5#`xf0[SHKv%nonn_iSSNQ<򌰇+F31^VPr#+ubƝ)sHc,T(2=`8ex{- 2 í݇|{!eX,ƁwI7;V9[z!zG +˰Ѓ¼+"҅]8d8ϮcI4k+Ti dҨl%IiMDc G;TiiLlāT*Zd˄Bwgb|`\8Gk|#@ҌOC~3+"\/n_'Ez&iIɼy3o*@4mk%*ٽsR@B% +j/ARm;87'u'޶Uj]jԃ +)7axkR+wn}63rYd\Zɉaͩ,jOA:ޏѽOau=c93n+/"buj<, +$}2H>oA\nxD8F(&,MeQ&F\h6@->:g wB@ׯ8jmNQW 4 +jn֋O0XU1i:^:>Qձ}/.+;8+J.ČGiVMnaέK=ݸ&/96\Pm`0kCa^:w%f#1^9 [X~iK{AՋ1lu K ߴmY6B/!NKS+>Į\P-q!X"7[0 ߎ RXP +9fˆk*b}Ł.޲3#>F~\2-y."jK^YXq ˘҈ʐ0Ry F(8PeԆwiiߺON'lA +|:W2$#>]bdG}i=?^VǼ=@7>q_͵fF7ߒԿ!$xDαصtl~"w܊B/3,KYN8d%.-HQ,gciuZGo^nR^T\bK!:M^5iNF \3R}zƨ~hԵ&GLn?Z7PqA*g+p"+l!MNpxi8 %#*Qz9:{WJ >Ó=sC&'(-T/z

M%?vK 9s@*x)1 :_!,0,yһE!.@=T@۬XRōdeI3 \/,-g2 +ѕ"E>bG((Ǹ9ڒL|AYcN`$Rl<*h(HQXSe7vwKqbDp{e̬f=sOh0 ĨF5Oiz'i)zbЮ.-VՓރ*xz4hV,@=c$Sg8vt mj@e˥(Mj|\ |-`9u"b]Z~fRpd9ˆh ۸TKE$ĔB‡PiZQUQ(UO%3Q_̯mwCrbq' "$ Tpcr20Y"%֫$һֽ^7,ѥx>R9rls.x՞eٕiŁ)zə-殑(I]o;k.* no2uŊDjP@ oC U/Ǒ@]RtB\+!2p!0ֿ>%Wk;cxrSWa(AVEYBVS_"." nV#6bG%oéY:9;c@6]W0rOloiG疛7!pqzw +W5@jnQVvwVyk x}T*Bjߧg4|)`Ci|@{݀/ +]Щgvt7Їwrݻ>*O)|ܙF=mq$yq VM[Brp[Cd>\JLoŵ_qq6bY2 )-%i!V ~r@*<ܣ ]oƠOxΤig6g`wKv +k"@viUnaPG#3z3vɘcJJ-$߄2]tO ,/Àl{5o [hIlb7z05`reO*-]"OzOO~?r-XӨYï)IX4r.JqgX&;f?Ƈ<goVg~2<.M\_vbK[‡[+66ֽ[h=Huثnz;ŗYOSf󾿕:GmT# +PK_U,#2ӂ7az7 "Nyґ_k)ʢ[^HPDc>a, *)B/\r|=/{'`1Iq^}M\ݾ}mR}1ά,y-EDc!aZLO0s}0b@,$3mwJB)8s}7]?[(ηae.JԜɩ;E G_2[)D*P ɤ . I +7:F#TfՐb_ntbX6G8!r 9pukMO@3d(s\`Xo )7NW@c my/Ӑ3\ބ|o5֙Z2ў$!0Z):W4nN|BߘVceLHu; g>N yDPx0 +D\DCnpQV91CrȷXnÖ +M(WvKTr\ +*1 tU8Pvfy^E!y3 _@}*XMCAEqUdprQ1]m؇,iS'E$nQ6 P\j*v\a.%a$ppY/yx|znL4P֎UBr'pƱmra`A]lwᕛD̿-i%UJ sT)z%S&U&BDq(!*Z=5'y4LE="lVNb À +k1'E 6Fׁ 6hԊ9L3'FvN4;0^!2YRe1RYGʠ]2V\ ~"x`$i 5„)MW1ݬxnF6f 6o;9duΘ[_{&B7|p~2LkV$.˯vG5s8!K*ss23gj?4b,ނhMT2"Z2n}++Ttz-JdUR*uY:Œ[]i +36ghG8,D^f7j xx2,mqF.duE}TB'>}??S'LrمKr4a^:ZUU7=l+*"ϐPᶻ\6_i?1T㍊v:~ٰQԼ̹j?ÑáYz358E1DkS UBfZ1kf͒ QV,eLZm&sq2|Z,f3ٖ >juylR@!*Lw×my1Ӳ,+hcmP4]gwRIYn#hR1>VE[J6U\.:؋E˨4'iW#ֽu Gn#I;KyxnnnG!П$]g$z ,G&B$JUxLxuklve-l\Q9APY}2ko>~v$$P>, +˯6 +ɶB v_}}B " / +Aq6@yDR24;x) hH#q=Ӱ!B>$ioNww +W& !wMSUJQ.|^iʜQ&2E$uOìZ:׽ei9}5^otCcaU^%bKHEI]T~hׄfx3CZ}ZkJyS')71gNQҥ~ k~a׺F> &Œ =#>]Cn~ykwI`[qv֣ rKa$U6QKktI?EƗF|Rl]70`ioF[{!% w{{_s'1+7NoGjAC8wi$>h;LRqG?c+0l xI ^|$Њ8~L jm‡->mćdt-#yarFib{;8~YR;;" a8͌* BL&TG9 ėڃ*U[p:Z朓vjNZf\܃ (GB)Qnf'v9}p xgQE cI$FygwWaڀ߽&Eo[4d׋7r8 5|6H{{hݥ ݻOBA+f]76Y]gY?3EUżޜ Ӄx}OղG޿]9l N>;3;իZ솀S>|=]ʲKJ+k[1[O xhyKn-B +Q&4{tXB*L)dL[)g^oWSp9+uyйι3>pvXnu9FǭN'gAE4hX7ܼ,͹QGVPf$@TIn CXL[ńGB+%4Hv /mgz}ض#a< \9QrM DŽ1N|dxsUR f|硎8<ʰ߿~]\6!me B6|SPBE.DC {Go87|[l1NhFvc@!(JbFh`!DcQ-DY@+Q/E +EH0IlaȖv Y+kćsGi@(ֿ<<,Ƨr)ފw}a&L6<{8뺣׶LZLZjG +.'"(,kif"8Ƀݾɞ˗,vHoBEO ƢB^U1Dȓnך2KgI8#o}PﶛqL9{%o7->pL9։[{Db/*b -oN7F3^.?ruzWuUuwuLkwvw;6~1l6DH,čCD "8EHP@H!¯zY 4~ȳ f9Jdﭢ8E iɢ4YIXفSՙÐ|KEcw4+FXSn=IuA=8=Zo?@ 8g&í= +yTZ E Ŭ$r\d#%=!CkSq*D#N;fGRr;JH$D0"b4$YpΠ/Xm@;'$q2e@c(1osQ ضbcz#0ZnT@w9;fkL'sxM(yՉ0wtxo}G߹R,lI%v ozß>nji).20㲼ŲӼLAg[* {P3ߘ)>]>̤Ej?pzͱv)^WӚѦW>B +m:4}{uY]9)B`v-ogAvn;e;0QXoGσo?ޒZwS`=bIa4$FT*ɘ` :K\rYk.nY#b*{Rsvw"Զ`mRSmInVׂet86!DnI0՘ CZ|5ЬS@Z/X)gch)Ȣ3,xR֔I*( -eQ8S(se\ƾmy瀓| MDjUGR }&ZO`7pg1vP4 px:B.pe*"C"6΅RkEհ_[Lr<ӴLtSXUp$Ee2e9!HR煳K%-K=44qck2tØ/#/yKj|b Rn_Q_LK Z0 veSx{ 6}GO[W"a}M=:=W7"K$.4u4_xl5z0 >ӕi^3 ؚEIJ?ŻXgY=+"YJ[[p>1qy2R*4J І P!પ & +F rN| +N 4d)M 1\0u;z+o;Pզ[PAP3OmoHo4#8glfYboA4N#F#9]$iQND FGӔeJ##ݔe#h'c$ i(sXP-5gnYWHEUyxq1K8#㮫/ı(#q$z>C麇0iH`lTi±c{3׀^ E=Yx gߔ{GLih*F9OLJ|!D +C(N,7B:R~Y;5O#Cc*dyQW+<2h%NM>t޻U%iCh*m4r:ڝם4.3U ZƑ~h=[9(Yv5{3ߢmni<a=`ObD"` 2!,)TKV)#IBk+ ^݄1RjJHRJq3 $@:N$S Iyݫ~zuhOƴ*+iznL~fj˦k3O z!m ևիLaÕ,tyw-t^?ʽm _'茐Mq`K{ L_k7 +4Rkүzbwlmi=QSg³_"o*xu7ՙ. tҬi>1&.0{{߾dN HJ2!%צ"G8K4f:9iYG)=<ăWFy C v{ŰDoC݉< LBQ1:!~ܸ\{lȮ&k{#d$m&HZ6$ BK8< D8TU@Oml]_ھZϯ+O[1ۀWl |Yw. _jIG~˪cZ +\+4>XSv`-|nY@Y1k':3/]z!-`KdMc +'Hm&&9 f|@|4`^VeFk#Txe5_ +lM5b^lkayDV*,,ѼT<\/e*FUUj? 0 ` u^pA5@b6OosYv~<a;1`#v8W0?Gf h6xz̙d?'YXz1Wy=a( RU^@DK>JMQ_P#jR]7!h{{{zDY'_s-FTWUb|[~wss)*4ibǣPrZz0p8D(FU-?9 +'pd3n+E00,T̟NoF& }˳vūa+ |.(sAQA].ٕ +zOEi4T] hB>tuNz[zr5+%Qo| P<.5+."\HĥCa#\%U@,pxqƢڡMӬ&oxqU[~TuOwcO۱'vlŘH c'!X EA`ņ` +ޚSQ$F[ݭ:|{ٹpUXB]&Hœx^&Du: ^V :\^(щvvLgz>.|Mt]>?ݢ:؃)"2Ofj]hb +)508`v5a\,_q~) ,[3>Mx'DovX܉g{ˇjQuɃԓg!(µǏ^ӰŴWBܬisWf K2PZBI M EoUk楫ƪp^]Ċ'=j6fnᤱ@[FViG}ϟݭP:L+_;U2+{d[<.3Kن.:ۺ@Sp:6ƻ.% 1md(-iJs^Itٮy'Bl8ڬ{՗t6#q=Y +P_uzbl6CHO1QXVGJn(Erp{CXHmSko$bQ\F7`Pd~F FV\pҎҭ:*>XAΕ9߶ʶ"scAkfrJt2x`O5a򮓵+syQfst4[+N- 䝁b[Pz{l0S)SKw)XUy:#D𥳐3[9a&kvjۭ_'| z':53[ŚO֥9 («&ͫU6F繾T +sBfYӰLw䊛koog)7SM:vPG:[sIw̢Yf&8 cz. 'V_jIHr]'Bbz&d3PV =Y^k=!A| ( 2IB?JjHqVjErī$kr{;%ٲŤpwK؆cp *mؕ%hEj5}o<*(0Q{&磾X~iu#"1*4LQٗ2)MyיO)t{tټ)AA!zQ6n_B}IY}-+huVt)?~iǟUSI=:kh҉}رG~L ;~5.8,`!%a 3{DeC]% + ?ǒb\*agΗ2F 8-ws0D?@'RB +, %*]Z뢔zFlp g~:鎼J& @g؀6l4Nks:BS<5v7Tot|PX~LԷ,)Kx3 V7qhP$ +UV¦B1A۹XrB+ L­r!&ʺ*ݮm-+6~5QVZh&ŜB`p ?_MHLDQ+RAR̚@)O8D3J%Hw 49/iApH՚'M<ݜspc5IOIl*ͬvsJsv gvTUX=--'Wgd`*ych* iޔ]H-Nf>ȧxAKQz-eȔ03Z} 3zJgpgܕUG նGjº*c$UoGLcslFK D\(Uf_ ke2fYR-DejbzUxd)Ę)&z:j~f5ΘsiHk%_}|̌\,p].t  y+uO5%g1o0ʹe$f>4aH|TljϮg'5 ]@?awZP|g!@Ik$v +9&y"<g")p_M?_HՐ`OloW4?:~3KK,I>rlTT$,u6YyMV9!x}i`:"ُSiSL%\c&j:#•Lv̎Lys;Ӧvghz8H\E5ռ} 蛧3w1).aWݬ׏NY,ʶ:r 6I u=N93NM0PLjXΦ$m $oӴi/+y0$EF,x\ +o0ư~ޢu9H8f[_M~pIp!ʭlv4-[:GokoSg:_]ojuv{Y(16nSClrǘ"Э8֜:ZS*clj)|py_2y*evq,Go,?2&~O;vU+,Dſ=B4>-B=? ;A7hRkݺ_OZ٬OJVPT<{?MGi%J'%I+BR x\/aܙݜlqWLKb2S }md*?ɒ0pA$ t;=Re~*9m|cvރ;>jZW Y/~7un 7R^m/\uN:.==έg&&+îIHn]%nEpAE1⃒ }>O1k̛~ӑx:S]]ռ!7 dĶ%\p\m hš+~l UJ_YQ1gj)fut3MǺ VIƔ\?ٚ={0KŞc6L]PI +%%>@'B@(JRyV?&@?P0Ts%"1$IVQI +'$_`hkN6L_,tcV8^ntVNjĂMdjF= '0jrW1?Ur)(!A|^Bީznٽn-//.zA9Mc] + pRQ 5iSB* \d%MGgmD)ˣ>ukɵ !Bs987O4ArkJaM'o43j"uF] oCŘkVF +Y  Jtǝ[FtgO#,dٹ/P|ݣ5ӷv͞ɡ|i O}uJ93]mf*CjP砍xbb'qƛ#s''  X-)߃Z] +*R&3tu홝X;Z&Pe:'eۛZI{6Je$rt8ԋ$ևBq%Ki͆3z%߲ۭj),-2kIAtLA +$rw&x>թ c'!!4)kn}4q +td5ֹfҬ :A%aUxBv]"B"&LY0jL3sAc-j<`PN.&ik{Twj3X]w㜚4-ecTBeN܊nfV(9.6ISs+KΠ )$1Y/gdO%ڬG# n7y/o4ƮC|w~n&ҾioVxݦ/岝GMf5jcĔrsj;ٽLnz{*b`W`eITR)HrtY1bߢ(VEB+KPM |+{LZa!Fi}0ꁵ17ڤUyte߻#>{cB~IDjߦχӚr5gN;C;A#4oZ&Sv[&hk 2.΢8;IsԴå)|Nꭌ'ĕVq[.MJ|QMY<'CNF;>I})#?O!ZDpH(C X}*Ddf Vs1SE9͙Fz[;40s0FI<'u;j@w׃V4;ƲQpɒ.9ne0_9"lvD,Ke{g`w%0PsdMxqUan-wUgzz5,&6v1vL`A0< E!) $G E<" £{cL23S5S|5_: HE gxLN&.VՉkۊE/(kEW(E5/ &i3B#oRF%=2Wqb?3ě^6O$:Mc2IկG[|>H( +`nYAK.T1Vڴo.4BE X.M\B}Rµ[1%) MgH8Ԭ d"9g[?=0NezZਢy +tSh~ džgT2Ȥ+^ ¸%"]7H2g[q1yh=G,;_'Q͒֟OId&o(9msPTZه_وYVv0 /ZQh0云̱xuFu+De_1GhfgWՋYEYW/r}',['h%εNN[Ajiq̒t5/XSTEme&fq=pުWm?V*?ÿ';|eAcY09!",`eʼn4z()I'jl-hd@l-aIkq\4wK=;hE3TpydRv/O,G mK@Hp^wNYA,rHo+6J] T/cl1-eR:R +rRRq +]NT]wD/hTd[շ^ϸba}Kadd>YmxLc&:Ib +[Ǜ ګ]3 +4ސEtK&ؙ6E<*DH|o}Ez>+eB?nJB# ab+L()rF E7#"BL2\HuULx `ee 3[ *8=Zk_46,Z%6z^As 8:g΍Gz״nؔRWѐ=#H?i0T2jza㾛E:Tb6=7a}:`֘a3FVNx]^BYvkӉt$Ғ0;o]p.# ^^Vs}>26êsem{X1QW&c)JtE2GH,zRfaj'gTr/Bֵ&oKk hS +̛fm޶يWVz`5eܧ;/83 F +zW68:T7E` 1&0YDz56[,$vzØU-̗ uPWDB|\18Tr|?'=n"xCcN_KT>9 lɘ &0f0Ln[jal24A YB:I7>Jnב#6<#= !X4o y-w<+sBI9fAlIuMqh&`A%|Ӯ +R*w1LUՌQDAրƊ)8눇ԩ!R): TRSޫZhR ?ZKL[ortuE-|-m$Phq-I՟^S';Zz-cM=婢{$m%i,UDdIө6_ٱ *u G;|9#Eचe +Cmƴ,c].}\HHzTAZ :5 ssi/ZLpInN+a\"P'%]Hml,gZٙ5 RؘFEJnc(;,q'i.:Pya`4V˔l?fFm9E"Vh0ju ncByɘkz.r4s3җ0p -<-*2Cu|cy7pMrŕtaD9Shꛥ]ɲGÿG~1/a8k8Jp4o'ڣg%Z~8pWu=y3Ywfl/v( +(&%AH<\x(p.H! q#h~z%NnW{WFSΏ cSbDmFF~Ѯ0ݞFsFsȳRӎ {)TܪǞC +ڛu1FԔD)Ί51V@ϞHԢ U' H.@Gs8˨h:$?!=myn #zȤVܦy;lj׭*c{B9d>(WK(dw N~p XD0i?|eqw`͡ Sʽͤp}ApeH"?X^_{ķ.g}h@ԈcMլ9]\\mX%>,.:.6R߬fD`!~1w8Ɂ呗Q7qGyXkŬ$[h* c\v_ ׎ C*sƺ^ +uP:&vDlqf4 |ߊ4zM(CCf4Ibp{/! + `2 \BSL%kηrGHCY-0_/|q;Zs2XA7xEJV.z.نߗqDFీ(+y >zW +#(kmkh݁@C`1:At +W0ιRg^B!P}N†S.=߯.Ћ,po pIaL5u M] Y WIzrupSg7Yk*5%6xo-6_U؆:ٕddn~ :Av’", 4kLA| o ps,6S hQ + +Vȸ!n 4c c2MJDlq{J>@CAC F^4|5&* +&A3>ŮE>esK D~6/$ݵV@ = YnY&yz\u?>}S=AG?*B:2 +hi @Cnf`YtO-bPa'F>bHt$рH+|xV^7<}:y0o{Z ̃RY44eOu4u~Z{D(\s7 +JĴ]7$&\Lqjk!_(_|5֍**n+fE7]DQ ѐ^ L6챔d;N 6:Gb(gD/A|QqkwQ.GxNܡt"_1!F(x*3UwQWgˠ̬cm7ɬwvVާt_pQ~)/XM-`;79kp(B=6g(w~_9#12(# /q>VzI Ωj9r>l~V759SXpO_z +#>Ճ6ȈxA5y&72{@| )y %#b"&(64I{,4sIZRЕNP˦C8eV!ȣGUw1(Taӭ!IgYVhi>e^Q]fʕ](i^[xLU]I#-8ZA=tDy(RK6s!DxT&q^tU~pN:u T5Z&NT~Jc"C3z}{ɘvGDژ7;dm\&ti1FvOB +Cvoʢw +NY?7-zKmN׶Ǟv۞L2;f!a8D !#Ab!"".KnpH('z<^u=)nWl|SL:rbU`h*o5t=Z< :<@-=nN}̞S8ļ +9Ƃ1,VyC-^fS6qoi`QxJeKR&J a^2#pKͬ|gly9n=.Tʼn5UP~kdmh|6&"0OESYݳųpuQɸCuڧn.a^2p뉐8V"H$ˠ%\F{QG)V&j*8M%L>gx0쀍'K*% +x@#ˁy>g66;O3f&'SAWY,O&Fks ݾcOU䎏߂;EWy^~~^Nv+rP; R.LaX^oze{0`}Ux|V5קj6~ak0|H+NGiOU`< oI+`Q9ڮ_J%RkO Mf eo@S0z=m:gzhb68LNkוU* !mMhLXHE}ˢqKphi (49ʋerYaBw2 .4Ld23i[ttIy0ߔȭ {MfVM:jkZb8TQbYI`Qڟpnd u_DW E/SARH{`p^A_&0\O>% k{Wgmh|s;OHŒW-Nb\v!<ݾ&Ǥ ` A}K q19n;ڶ>qj{|F9ӶOI`4ؾH]s{I]T4s LKm+c(-tm@ $ĨhwaFmȊN:1 +oTFИpmc[kSrmk|&'r^/iܽ!~LH,p.k]IM|Cw&ϤI<"fG19UXcz5ffaGfw;o1NVd>A.%ל_sk!>~uFE< xl*tKRµɥhJzyh @Xec+m]n?Ϸ%c>ݫU:-;ںG΂]-;辈g1Nj!v'YgMug߉yjD v׫R5m1s?] /^GxjF#@yRHG/64-s۔:j@Hu`7G2WVJ: ;{;6s~\=4MWV͎O@*9,# !2S7RZ3bFdl3ߙ]2\q&{_d(tvOGv?ɾqΟ8@L| 0M +endstream +endobj + +800 0 obj +<> +endobj + +801 0 obj +<>/DW 1000/Type/Font>> +endobj + +802 0 obj +<> +stream +HWKlWNy 34XK.\ +c-(SXz&%hlfA` F]д; 4Ki'w蝇9@ ʐ$`cHWyʜAġ*8#8+|ZV @!20}5W9ģ8 `^pHY˂İ0Ֆi<+݂ v`1s˂gy?}=׵X?" ς>#W{|NC7 Z tCMSq l?E0Ӡ{3cgv@ ?MFcM}`WPB}!K>N\i.־8||-kM|7hj.k_~uuo=l7jc/&Awϣ8?7{Oh9OV{i|?=jgG~7;w3ѵg07aG : Mqܫg!{gi42F8? +}(n+~Oo sg~Ra)r2w !gd/nt>d8? ;x<ꐩԼ=/'^CDjhqv==ޭ6c}BlXOyq];}ڇ5:8| ~~G5n}F>ʱiն9t25X֬>f|T㻁~FN Bgq?~EkTsQ +i? Otd/oqy sCs߸ނ.o:a? k=|Gs 6+ۂoG]sOݣ07r4w;qט4&z'Z;OiĤCP^sܵ޿> |+qs'koXU >9 j~j\Yu>[y %Z3S}u|i^jj=͑8c o>Kcw/|{v&9[ΘG9s+<2̟ePo!>&5MM,n߃IoFmLhyHόo0վ-x%iv/[:6>Āril'IѱId<8&PϦOHw. C6%}s88/Y?t#) 93tk쏰rsl&'ԫ q7?p^ōy&qͽ5;ЅɉW\]=\V ^qz? +\a g֑{riJq ;akXO6̏V>kUa {7/}]o~--AL@oweǫj;S¼3hwϸRvᙿJX+.ܾGl-O|Tgy⩲:|_ٰGPdz7P#-/;۷}O|w3fs);V`-o[㛈}4G`yQnI~Gqw?'ˡ2b;:bG]uǾ%|-hx`ri^$_{7w@VαOR@cDw,u {u +~5C1s?o²r{p`Ox}wGwC=g%ٿ(PTi^͹ڞQ.u1k.Z(g/| kyJ^'^qsm|sOoZ~g +':1Z/%0M7Pi1v#Q[ױ2z˾4?|;|_}seM݁}[߱_,ܠ걌}]M,9j>#KY~h9ayfww(/O>Z)/н6Ilo{r)Ϭ»ɵ7ۭ&1A~_ +#V3磻 šgm实 },(]̈́\}5|{zG}BY+1wV@[?s0B<,fU%rY9҃qGQ]ݏ X릹`vNZ'(aGhVMx-qcQtI6M"HqROwz TPl8}.@sie̳GMfol.pS[0olX#RiWt/ bTZM`ȧ7|S#99yw,ޖ֋DSi}n:Gu.`'zϥ=aIEAğ7/}l3Q{^g–YkCiuTZWSjڦŽAԌGɤWSZo=ΒI} :ON tͽk=9F"0Ct~+`*g>%^},mNAe9{hO#Cg\p #G&uƾ{!<3yQw9$&G589x}ǑwQҷSlg 59dR/yX=kbF|СǓ9#,]i(@&zkf_+mnR\o,g_{\Ͽuֽ/k=[&_B&<_DYU\c"?:c賉O.|7M_YXlyvu{'L3Ği3'xq;hWdQm>wYыcoq{MO2'z|aqQ}'鯌 5:ۗuc֋;P_8W\n(3D/^J_t9ZܪJa#涱Zx?/X3{>fvr]]n=oEO\1zo9:9ԘsΘDwf!gN=2~߲Gj;S@5a_~)d[^_lf;s6Q?R[w\zxe1˺u篬qYSϦ[ޚqgo}u>G<⵬,qlrAsyome.f~l,y̽cy1Yw]bŹ`[/y"cAyo_g]ak{7龜j׮Gs=Dw_cݹ={쁓KYϿ9ccgy/Tޏe=bU:1;2Sls?*`-gy?+hgf֭YOƽ>]+k; ٓrnwmkACo5e˩x. J oCފ4<~/#@$א{ԛ|?XK˗9xy+,?Y>Ksv٧K\ףxBβ~^lgSixxAæf:z q3V"o X:9:;|t "K֓kun`<2un/9g1/Wu.*6ϥa,7i/|*: ׹h`E>^yn$f0t54?ɶUoz\XG,*g]r0ΆwC tV/OwUS콊?5Zoz:1g\3>xntrMNM6xSo\GOܴ%ss_ӇϢ;,r|Y ~[KاiJl30y"u&A֮yZ3Dc>䷃seY[b׹7w.dv?8u2={^]\;gZg?/b3ca+j;?55|p/?ci N>C3;6K륋,2eH/ 5Ži(Y;},aF~B83K2U8v?փh\]p3IgMyy|<_G*kZ3InףI =ePufEKܱ~]ό'έ#IGK=PZd?4n_J|18j5JKˋ]<6B >c;ʺޕSOS`<:^qD6~S.mW`q!ocΰxa9/'߉ǽ\I1Zn\ܗ _<5Z;LO-8Jj5V;YyWe*:1ެe8f9q-3W?/kgk}ӵg}9~o&gOpm4C|u臲u/qMv_G,6܃^/y~o]c8%8;mܒZo6!'=uOd]@awĵ{~#|Şw=A>7ǜ{Aud><{~g ۫=^Y_{W[{$z=?/y[:y^fzx'Q\z=38^NW杹OvN/ug[=ϼnaz{V=|z+}|{?ߐyKn^{ȶzNvz{RǿWG&8vB7IܑTZO;_fM東c<ӫc}5?e+qDa` !lw +leW.:3h]ދ? %ϟc}>^Ҏ<p)=a%-a.X!=:|gb'K=ΒSqd>NzgӓyI^N~ڝ>9/hHMs5gGe-o,|ΎSy-}O5tƃ=g 7Z7U83.N㤧~ƙ =p8uΪOtռș{(h&f8?]7/賟Gz'U6}+1Zۏ{+}6 gj>!G1QV0|]+Y1xdn[.ZzT1Nx`?3؛_ٞuoWKXHؾ{u16Yp/:U ^~Tuhܫͤu2 G>d"0쿧=#|8y/*{{R1py] fg4X??ЪT}ZgmA5v6XVp~k9 +kjEWF]y1X^}<ډ}Zc2P|QY?@KM<ڔ2c+_kEk.\WxgJσF ;/mxl>yz חZF8 ||(dpk=|EϸfOZO^ fRyiNijhy0:_>]vo cۧxkjAW'\Ew'Xp=b2~:I1q?ţGuOh-|{}eoƒfC)Yx_?7U.1.Ǩi m1m:m5Slҧ&['S4\?G8'L1; # UwΌI|d裶M?Ǔ_Y~  Pg[Q;ڀ(xu8clttQ _1} Zԕ6v]OŒXO'=]glp;bi<.˿ju= ڳc U^hw&WѿM1mǚK;ͱ=f|&XTuƶ3s7<3Nuڞcg^|\j-*g^\nAK{dbg3xVcg}OFW泃ϑQ I5go+>28SG@MP&oj⃶ <OT`9MvNX398 !I']]}}9 gZXk+!{X{zg[|eo_sl=S +s%_3/iOS}t#_oS#dbk є=ՃKLf=ƘhS6zks۹@xC]4{1YqfjAW7YG4_5e9`93T8^+C,-p$v>G5F_Wz6dACUO _)+Uvëa>KvkA[*gOt `k<8k-r{wf[_״9׀|řSZk0_}0G=ӨgGV6GcnWlߥ]ڙ7p9?]dt[@GXggyh0HS1٬+V=(o?_=wKk6Gƣ,/6er=5*&RMߥQ-zxzU9J#zMƃclcG97*6tI!|$6w#߳#b1}Gѯb+oH>K?I)>݋[B +z{7c-V1^I('%5z5hS")jUj6ψ7EU{U7xfS57`UvS]rsg;cϱƥbR:L8뢶%׳5悻-|}}_:s/po෬K_Sٱߛczx _tXk5֚\D8՜'ѬJp. +3`O 3TGoiY?_%uOc~gXpW3'-D ^C+^Ak|H~ [w-{C#Y 6 ES_~Sҕs ƱQxߖXf9|ѝI6֟nKM݀~_pFE_wq9nt{l"1YH9Z |9kVO8eqȃw7ə:,+t>KD@ +)kT>=DZ靽`}&UvN-_ꝬM<{ޣ^֣jWk|Fur8 {6.>̓_;;Z`!7X9!>wϏ؇ǟ܁>mf>_ qK5K*,i1}wLx_|jj]Cqԛ~ w>>+,EܢSM]Sډk5}ܡ§ܾSNKhՐӁg1s\ 6%v~{;3pսf1UG<2fvv:ųb<+2d9赜ϣt!!流3߱7O˜Ǐ)q;qd>kbZDS;-.~cy_AC4VߒYjpsZ ~+%܄w9~18#_l#{KxV < {)e;=닔U`S<چ6ax,wԏq|X^8yC;FNwc63G{e 9&0`t7q{P_ N{-yW4zcqnt;ӭ1:/iteLh\ /jN$QLo>S'^Ѧ[Oա./xe?$8KW?.y5Qg6зOn6]kl,g:(q^A'Ϥ3gJL{ony:q{/fvhⱗl)sKr;fem:gk3H'>oer)(S}ڷƣZ\gB/-`<#u⨻p/5Zkmh+ֿgwIdMߕg65܌xlpq\a;[{Wwυ:uCy 4j}WПAW}o'ZݓȘŔ?x_pwB߬S}'qn9}>ylO0S3.ޯqga»9t-od _uW14q5c+i띾\8;`fܯnW{=sdS{(T[3 07Sm}OX8d36M2+-b\jfNY/( +y#ivb9E~_uHG''v50Ux7~wc[W3,mݿ͜X?sxk|<YcfOңY }z]s乂{ cwfS}=_)yt\_+;K;{Zk˭osj˞Lo9}J?USFu8Δ:k<:}u̿dfl|kz,f}Cz?{;,%g[822^qԍ;k s7Xq=.<}V!n;wgϪu1;h~H|q\ɬ;bzq4(x0kލ kfgO?x=9_h]͎Գ_xLP~-g+Jhn0x]0){ mI0i{yW1tX3{mx1~F9JG;cx\P)sg:3`p#G=_L'B2GYrN,y0^{CWﲓtl IN-'^uB2Wt:]ox>Lϕsl{ߣ[ѿcO(ccNNCٝg9}7 ^;Y=#:9kj9I׾sxfztfl;ٙV}6sgz3ƣ!n_hn,ܦ>qt"w{Z9Y<Ŗzl̙Lw<܁2hOlV5j<טNKz;Ao@{)ߊ_z?+<~{o]o|zv2zw}Rpvf߲XPЮ;T=߽-٘t4R6G5:5ttF/S8_B_5f`\ՠORl@ n3&^^c?rǾnK8_K$IȌG3H\ G\kXp6*+[5ZZ_K5 ﵑ>o0.XKVeYLo[[Y-@~[Xmԕ[Ξc> +|$xb g3dJ,w-^2f29zh}հY-he\8&oͧxƮd| Y-MEOǪYeb%1gKCAG}2ܯ#&kqm>Y?o=)NjxoOy-gɚm{ of_X8lBvY¦Gl.CmR"#p[6qMg޻{v1;dQ31s.}1?Oxugc{Y^dg{TnS xzוx)u[T|Y"eVp^FɾXShyd9M;gZmր,}yMGb'jN;-=ȧTb5U~O!˟Nw͇Y u%}3ZƃzZdgx5g=OoM}~u^YbYk˹kjxvLf}x<7ˀx?ˮw5[{}_% o){lr}sן߻9 /2_1`¡c8} y KX >Γ_c΁{oS=t<'~c^!=AWw-cthdz~g +U|)_Zg2ٞߣ쭫 {CZ~] o2M5:'p.Y-9gP6Y؂f^y)_:WgtԺ4+yj$Œt/\OrxQlm[iۻ)q.צWg M6c3tR-V. r;beV_ ,C T^,A$uT3୽}rObf?aWn}@:fk6FWq?ߩҟ}7{͌ߗoEs۰^ 6UCg^Y|XGW>﹇}.jy0sz{3o >TktM :73ك:o?24ϛ ytsP_<o>AG]%Mog 6 _ه|:#;oL7~ +\9Ss^B2ʳS#ڿd8Ow eiY+]D~d3yEvvzz#j߄m> MZ;a ztXOrtNex%|#هc97K{S;q\wϯ` 1zΰQ ]8of6?kC-7KNew t5fg1_y |6yd1wcݔ⇶xr]roL{85Jn%)y:ͷ5SV3ee\-?>Ǩk.WmyO/QnBn'uQߕ0g`֜EZ|E஭ө>!eKd ^K >y?KO'O280N }8kQ\o?'.-K dSɛs%xH8I^se39D6ь']a6/s`;`kΜ/hfܼ6zGҟ|+p}g]ؐX3pײ}/ θQLa]ǘ*x݀Fۖq ]we'G5wTK3oS+ܺ؃S K2eqc<aoٗ]x(Օq>2YO:r{[WLotGiʯﻝ+9gl>T},˸Gm_z-qE~ԧ5]26Qn?%=k sCw9kxWnc]+<7ޖc^Z?Kkkh;mͻw[+>7+c;졗Lj3ά.Qփm\9]{=r8+2kB>z*Oqμ⤗ zߗB͆ϱ5Opv>\/va\βϨw8e[q2K ~{q ǐs +x yZc㸪3s;3;;}d'z7w'zi,$C$!@J v"Uj6)*BB$h݀D'ɏBEPATrCE_Ɯ;v{ܙ|qlB|*|x[[Dp1q huF=cv-r0?wXnw @ +BRD^*PeJBfPPP\h:~lBmR2RLyHei1Ecc>Ʉbݵ4 uB##olftKt{eDaW`)45^@{J kEqS;8ez6mK$(i y_,:z=v5Ob#QQ97mskcK>oOzaxîp/] FGQUJO56Wq0|j[ᕺ唓@Fg4}ghIáL$~T*T)0La^4Z*0=C'<\>` + J%)xNeB i*¸,K',G[8=i!2kaiHW^> Jp XXDc`׆CI/ռVupPh_mF%BC2UK:ʭ4!!3UP"Qb.%Tgr=AW!Ipヒ25KݪXTPfߦwD`dm*r/ +#JkE2.rge r痰n@A$#R*)g$`A +}9*9f,i7&U'D M#̇0a#q9mTzͺh%~fƺknw)W:57<#[VcهeeξA|ZV[lW ۝􊨅c3IlF^Փ=Hm+hj,- +>&x̥ Wס,FeyME\AQ5Ҁl< +!'7.be[y`€Lѷgʝ8wڟm (+#Sy6na]rO2EӋ$C.]W!6A$6=W!YVB n/  +P/ +9XZÞ%W ǙJ3\dI؆L@ +X 0s%t(;0-qV,8WQn阑$ R\>ۼnGe6T{3u{'"٬X +@{Ys&wG60-B3M8BPS=]](/pɥba 6'T8[ +FKPV 0m.tX,_1\~.AqMg]BiFd*yXީD97[LT2e +7:~Q#9.K|[/7{i<-s{Ȥ>i_I]K >ZjZ͗ '+FS5)jY-;D-䮤 e:\"> ? N녤a n2gC,b-&w78|<ل D]u]t$pP0!o`Cz,61M{݁D5!%*Hn֬N%b=Qb6W1"2r,`q`WKsr;鯒rO[ҧrr7rsIlMgwFq9mg]j{٭V< REIU4i J!a)JPBƐDBR"RSP/yX]V=gќ>I~!G52~Lۯ_+˥Ԅ<-X\>O/)s*7]N]vzPdbA2w>[_ꬮ|,+8bxa0Qϩ"bjZt|6厁YR"*nuRy9ަMcc=tԍ>0M37=GUmZ""'x__,P$GTG$:hqqՋbu].ϣڗ?kށ[ڛ_yoUՎW;n;C4mTߕ<,EDQ-p(G{>-TB +1a`Qe.qlr8$p5 nbUNWo/„{,aikZ13i'~*ׯA)F>z)5џjy`TPpJ! 5=O +ӡL 'W-;܌A X6͋= [c\i5Bg('CwOo;l\+l ZDxE3"i k Fϲv 3 L/D" +s"Z@rq_yDɤU".]:' 015m]o_njz'ϋ;v ?9LI|(P È$3t)qGK޻wJQ609MOU&r7Qƛ`gZ8 *#|4?5WӟiKƗ<Ԏ.iѥ^5SSQ?TqQ􌠧`vjs%NlGD ӤAnx$n4t젧#[q#7 +A4xAE谾`n;|E=.HWիJ m|@D"%BET1ʐ ,AwJx $bЉ+B1_Onwϔ?(I_J$u7޾)XlFj۵( %=o9͚!p3;7hXD I Ͳ6k$xH5o"Z8W~:{SNJW* +mpց{[T1ڴM quHq} S6:)eP&8:~P:vo_daken$d=OD榟b3baPbBXOՁ PK.FGI|0 Wxh6ΊQ^F@?GE( #PCV9I|9Jkj?{M(fm֮v fawFk:}bScXz_j +-;=F? +(h^3g8"P8#9hTY}@L PN}IHh844Y"0sGLdjX> 6p MY6PX, rSt$pt\SiKhF:!ĤU|pxZktZ%?HmjJ2\"6!Jm5DDvLLP{pe]ܞ}Bt;V?RÊqSd`0#҈HH;q>{{]Q"Nq97 i~]hI8|(@:/5& +L;'k +g=exvη#o}C{t5n~*zt $2VH3{ ƵW{@9c2:cՂVٺ.A]./>>{}g߇|>;9 DƴFTUHZAӪn%[0ڮ˦Z%&M0(}UZ6(0JX-Ԫh{k|;;>gbɆAQLOqeeUkWaW7|#uz1‚1͝_yy< N}`Ee;XH a=mOʴsԙqrλ; cژ1xݚgμ:h~V:\1k6Qyԡ|R5z`VDis/ +M1D8N}33*ha{kqkiT&(BiDΊ_H pS LeO8 UReGG'sKwjΘusɤfG6{'Xu֨%Q5 n'dӲOOnD1pAӼSa  F!QP>8^MߴF/?!0'n9]SY?Rfy&YX,QpK%r[,IVRC*A"\]pL .<&f8j˦kylPi*jTSbоX ?XVժ6+V_տ^i ѷK q#U/y@hT_ARJ +"Vk)UaT* 8̓F=<t~f_cA3Θәei`t{4 )y-4[ڠI6)[ (6jڭZ:`POk_kH=Ҷh+U,H{H Y="\GKm߾NU U);~-W=]vI>Cd:7_9.Af{G} <6KHf&uI(/%^w A^{amR"!4zn?9Nhջ8pq*D)u+K +Qs+j+GESq,/ &&b\!X3 aޗ>y%}$s-GiqojoY +Es@b@)x^( LkTr_0QxE{䔢M VfOShkA4pd->2ՎYQ?N1aHZ^ueuBg.. Jt?=}Wx\<.\K]/_U| oԶd6E2@ҍ`eXfHt+wziJ@HzA1quo#LK&iwܦ;ZgL;uy~trp$긽ExYZI GCה/'GCzO_J"#C'*sQe+iag3ށw==$$P.dw :?Ĩ̞ z䊅@ꐝ4QD; &Ǔd,M.'I+t r8Z[dnv@35 9/M6;~Q{ej:oafxK6̄2(ǃn15t9V +1zlbԔbDB H^E13I]hUpXk|iZ#q"8po +X.7.tLjo+`aƷ K<. )%TV/5P_v+~Қ笋5r(:t\Aa'QUy +39|v[#5 .(+ϝ;yzfb{c K8 R@[ +&U-Q7&" +C"ADJ)@"H蹳kjc{wgF׾9)X>mm1O.\۽pt Eö! +DL݆L|`j>N𒻖@BN8 k 8BGz)ɻ;+0oS#m<Bq 802]!`ӲƋRСݻZcz ^ڿ 7x;doy]}F~] Y-_*״EZfec[eԊzq۴{ciYV.YTnc~(?zBlֺE/\{xi^~KeyBbA[D2|2 +p A4Vr; @Jh'l|Dɨ:`C(;n;Lf٬T[tQXҫưqSڀ6)fńeؑLYLWtNg-\7g{qh~Le۰h6X +ޚB_}}3U>hDF#s/ͫcE&(Im9F=@y`.xSPXods 1R^R; ?e\ +YCOtlXcfn9)SHUʨ-m*ǝq3u#Zer2U[!!ZytdrZV2)iyؼi${=p/TjJB鲉Z(=U+zb.Wj)D_ԽEaVUIb*9EZ^,>g&UMOmQh4B[5E/ML (h9Er6yQʘʲaz(s+U\䕯 +D :?mu10@>&W3%&9Mn|[:_|XY0%Qa!D¿i"PhT4};s̈́G2V}ŒohNa8Hhم1m s ?+Zbyb Hia܊K8CQʼLB"FmXTMD\넺5n-le 9b'Z5InZ CmvMIcL(1 + ?>r9BMpX4B4*"c!I`Bo VRchSܲIwT:ƹ?'Z +et  o$!;C+>"gp7^7x'fw]DDgFvMAVޱti5/"Z~ޒKY@:C_vF集[{!s+ൾ6,Kˤeۦ ySwFzϡR aS +*=՞z@[=Gru\_$>d %DΔh0|"K`K(>"u <ȸ{dfr֞tW nx 6zۤKUbYh)ܻҞp4ӥNHD$ +3 D֝aja=S `TB4P 3hn%]7V|kߌ6oO/?== ǔqe {rNY +êEDH: _k@0r!" Zзh'kH/"EdOP@}VZX7]33٤Y(ݖg9kSmťX2;TFy[!3LՖJ1j(1lPàz;~_LgOA#/>6Rs0C[ k*nU .]$@vF8bZ +,H`H<x!<"j7Ҟ!saStυ5J ^Ȭ)uIA~o)}})BIq.K\ }C"hY${D3S$( }kerhghzavenpn> {/퓏帷8ln6Vcs+p"Q8j@ƁnbP8TY*Cx(3|̙}v粳ދ/^YgvH A#.mVAQKm$JUKm>ڪ7\C񃱪RQeAPe rŢY[JۇJvGgsKTȏ!lBRhM(0MmqV,.ziP&}Q: ҼCnbJ3y0 XK atYÚ|cQh $ySf+]| bgTaߍ-H8f;8A  Q~y@^WV|6ɤQG]3S6YБ,jUtDzCXeUY꩎5B\e ^Hsg@v#Em$0B?+| LˢyE5:;9o~r9*F_L8NƲ,O5N!: QГh'l~cM+n^G)nݎKwUxV8Lm/p )zmCKgmxFRi]*)>ṁ􇷳ϤU f{~8̓Ru t!`7_Л@ы:M??G1z +P> +&d/FNl0n9F:]4CQJ; /$D cpx=!, m%!*#ea6D_KMna7 :~]guVET{=(ѠN' q4sYz3.ؚ0% +v&dw(@$3P9&^~ *ot-otK4`eQ\,2r,$4\^`Nrh'QXI1ttlPTPe3d\$7 Xoqr2 ( C7fѐͱH)<ظx +1=zl$!?_= > : +ߌ07כ9jl3wcƷ?5& l5O=gnWv\ +=;=000E~ ߗw ̋zj<1=a6R]HҾұһ%DX%Pݝl'yB0Q` Cah~lЧ3C!lC +jjTjK T[`(Q4 :j~zWi/>"p2p ɘ\0 c5W2% +( +5FS K[kI,˯N`z);w |#SZ2Z=33(p-[-I; ɲm1؇TMU[ȷxHj"#U,hXI*="#2jp!2"!KA!G lEd$0w< v9p ݭ[| Ri?H7Q+a)]A^\յcXY>g ΩѸ<ʠ"2pbC'u"E<.NH{83`Ƽ^{}4xFm+ 1Kc-,9 @1q' C4;{.3MY#TJ+AEm7.fp{+͐R&vZ 4-5A`$şJT& `,4O;1Z=/少Fr8ĥ*K +K K^#Í-MjYK1x|^RLʑ+b)ymy_9@{Byɼe(%p`/Z#XP"T9;eTV|uqΎGoQ{dO0`z8KnI~'D!;L /%I{c<ۨ3aa2{йpoiFB U ;Ov쪍83;{3{{{'lr"IUQ8EWBڐblE@D4B?*?6i @-RB%#PSE}gFγ7{s3>S#k^+UNjrsڝ Jt㲨2 #Rס.ҵxotwe,LpnЕ7 :#-5*5'[Ӓvp><OρxlgfAFPK>J(k4nق,a豄o+DžN͔aOk%J4tօ* ;i2P "D}eW;oֻrs/ƾf컖Ră#QKF8IkaZr;30l.E}lR)R7M"*q薀S,myAM8z!.]Q lG$vv\}f/,ݡ޵` aqx˼gQU3@2y hh 1 ŬbTG=]8qx͛ɠNÑɭ3]w) X ~rem4[55,!deOC+J"ztK\" ~56WO1:>&%tϡq?~>(6:;6Ulsu ̅dsG:, +)[vB0, ?PIŠFJpCBƒI<<]Y<zWc܁10)bcx|9Q" 괜yt>6E|։"vCIJ1Ey:3@PIxV7R!ޒy2sݞ\/Y;Y z}bSvSe{v{Hapqūko[e []kI{]tY+jKa)ih$L֣i$RJeA`MU-Y bII@;WHjZao} =8fXGAr'3Ku*3FrA~$hast 3wK\ߒہG`Ne\ aϱL]M(.h;'swzp瞳ˠF5|*WB8 {Qyury.*BP=*R],1/kJƚpo)tZZz="T!%ES>IRֹUI*,&  މAVASs%UP)UQTHҊ(}@wүw>s?C*%mʨ $T}=gS%NڛPl>]m)-l"<*;`ML6O4@B  +y=˰@ ʳW uFm|>/ۗIsn!u"+RW@e4N4,A$`TY0Tkl>S: ^ WHҨUa%I]G asnX#N55Yβ!_ewTE'@(08A zC;hatYz΃Ӂ+ץ^ֶ޷ }1xLvz KZk8'<"i_\k|eǎI02"j&gffP59Ӛt _ö q==k0 m).gqnyAՅE✨EnXPb2FoB_j,`A-jVՇРFx' vA2B҇wf$jK&,f\M \N[%^<&,ꝰ 䢰jtA=py1,5m=Q [I2h͡qB\hԢ@3rm%%DzGhXdR SWc*۷}ݳ]x^NL&(i!*U@)kE/< QP  M9wFwYA$ +R@oKzj{ہO[Jw}4I̋Pgog~|ew33tj*Nٟ~T|Y :1\^u"~rxNONdr鲜I7 +?aBS** UMht[`%hC8F\,V 3%<։ ¦zf)%* l]R=ԄXj, վ A\WbgxcKˁGGno߄<m"6 .kL"C {w:OpЋ)U JA%/_ ;Dfp%jD}n+!*z.oM[L^:-+#p0V4cXn-+]9L5^C@y 3eˬ÷[2 QZD.t5n$FsӫG0KЌ9L͊? +o{,= bn74|G`;E+"btGVWdk<%I$TWlKNؐtp5a^Yyﺆm) +-PڐX(1 Z0GG9#<; A-`")t7{Püx[U scUͥ!*7!ԡ1).w ÕU.|KXyEx a +:5eA +6Yyřwm kGIB罈٩XfsRHf;QfS)FFfY16FQT85[%„;r$H+#r=(@c:RSc*#sҘ %4*4z33 !'HXTJo;V|Dc'!S{J;S{8?^ħz@ṕ-v䆃8(`T,2ϹC^]/Hk֑,w:<5 -S/XVfnZ/8aۀNXdhcc xH5NToSuml3/7[`U`ՙW>i-OvAyBN/>xOL"l&^R|ۨ0?~lxIS1꺢3bԩ +cV5R WBWX9ҜoOK;~q/ d72d#J$쫢8hyl@kBfs +f]%=淜(Ҍ茸VZ^P JmG "yzss3ՇabzaK[-fzfGںAaFUtJ]҇8-MG?[c lW a2Wr;KY٫?[ޒcE)҂ı f?◾}k^=iiHgmzgfV^Ib/DX9eʧEd8ctȎGBy +mMvdHZ,iZ,Ǖg:9?j:GeNaz0mr 4q=^|wU5|6 +C)+(4T?c˃gϞ>꿡6n7Dc]&,|'o; -Ie$#R'tۍ5N|zoe/ +.d{+sி&z&W6W}z}j ˟2Ig _oDΗwUqFmw!mΔ?|?_qO;تRvdsr鲇0>|w"?~nP/[ETv3 a:>0Ocκ iZqYN) B\oJH(-n&5)/R PZ3~ SӚF9t= 9|pj("O|,!Z9Hwk{ irː; j?>uullej@Ӡ4,0Py^7a<(n.ēsnn?Zp?jJDliW$[n#n?9As6堵S$NK)H0p7fw?оʩ_xLpzH2M'A dMsAJ1fWi)>/n3YDN.upxˇsb*Lz +-6RA?7gCRt8 4wP(8\d&ET+9]*й#$.)e%u"D0ދ>q+%K'CqSPUw>`ۥV!V'~bY*ǘK~_#[fS*:U#UիzK^-tO/lnX;;M8#DZb1q,q`%D NHQrAn\\@8"q2H=ݳ+?Sl;`?0A}/8XݮTyqKp?HY)笿;yPwj~c3W Ba7y-nF4LГz{r^G`3U?p KybG«VC+ox5xVv8THFKe[/wIWY~s@2]^@f*(-ژ݃^KF3z;HJ@0Q}cY3@}1obFJDz&CR \Qns]'qk-*]*h7,M^oxiNd9+]z8@}a0yP`0A_#Hd-0`Vp&K>d"\~Q]Pց$)7fAHx;5E4t=DK{HU',Y]I+AHsuK+#YV+8hY3}ư͝;nͬ`5C& j+ 9R!abōOҨ5+A>Uf\N Pe|>^gucP3\lں,x49qqpw覥o\ȴt)A@55ɷ;x-~e +=̉uV;;=Oβթjvm$-N{ЫqhZĮan<=ѳEp:&_mÄ|H%y %">[j׀V:1s!ùXbsȗ;ΔdzwWcX҂K6{B G܃V%V ^|87^ɁPڬڲ +( 1Mso!f9_/B/SНF{k?&m +EwBs2ݘx/ADc&׹~d%uR"ry3K8݉Z%V!B`lF5~H}~_U8wcKݲ8-Ԉ3Ø-/'.ܼJ,(=Q=y{^tf7=a}/1>&|h֥9htcgg,`13\#E4jP8|'ozMXfH"d@Rͬ# LKm65?3-.u&/.^Nj? +/\»ہ ߾VzA#@ٮ߸*~~cy}mgb;~M8U:̓&j)@UT@!UH+vtÊ%+(kĂM!v|3cNzGW39@c |rp~}-aHzMb$R az:t돽}l'HIs;q~ HyD!w;HJbne: mS ~AS)W fptBp $0'7/S"m?mdXyI'B_2퐗# FaX&O K.]ϻ=}&Zy\S| ˽ ӓCtfSz/|Q&̜U 96>V/{BfBT+lߧ <򛶋DQbRZJ4" Ś%U=\'7 QRrG" MXeH]q>C#ox/N|Ccܝa +xL>)'}G 7,wL`uz{`u+ +,,wzuIh;𮤃E*kl?oZq #3a[0+GP\>'Ϋ Y1dk=@FiPQZfD oKΒf3zDt=9asK6[v 4j(N ̯r2RŠTo(1CJZv{>`;[%le'1ީKxȱgsP+v~7ىXAH9%]|b1,0.buv/tA{ܧ ˆRa +5wgԲœ`3ker^ +k?K4繼ztl3ZHǷ(o=o9 `LO橥̓)~T</7$TbE!pXg&* O`aCֈPPDR>a|3&F8Tzswy ZX΢DL^$.3)b؜Mv$bё)C,?w\ jkGȋ>psYGhYiHH׀HGu* +j|\5>1D!7}U؏k푽L`^=Y<⯆\4a@⼎8hF;DJoOQS\^u}p ؇`860Wp NGr13< ;V`pvГljD_(y85n+nvbd>,8Dž"Q$[ 6jd篆 X^31乲V ݖLg]xj!^0,yŹإuLA;1 6dd<^sr3|n' Ǒ|&<ǝ(7;+tVHolju5 9Ť0ضvetxʰ* )'YT:Dl􋳂P1bBD&4G98pHP5(vta&1V`mX[q= /@&L%]@p8:60to]f\ V2JoĜs`jax}3 ݧ7j"#'UEY.bWJ>]?fof\mCVpXm)|;5ׅ̑m6\tPk=a3 rY)B_ M OJXEnm/B )4nzz?MJ~ʩ䤜pV'11I01{–?qS|u{̜cɦ b^#߫4Rs]bx^0@4k88]ܣ<7R Nb?qoo#[ !Bbf3.x6ř*ps۽ +ƖFiBj.M6UZ~o`? rc}vdɞ;lx=(Y&i~4<\^n/rduSΩ۩~鞞KOO&f&dDb$IH5HXYPX}|_DaYae/1NUD隡w~v=GFX2Lb͈$n؍%EiN] d 4CyZ1Hw7~$מ9i +0m $ɌYrf@8J޷_c]̦gU=+ʲԦ ^.wt +.tf'g] |j:lJu.ܓ</no>,fcHKzm:߼p ]`u})BIR cՃ:%&@v,OozllF/zNY\CuD-]9$ԟ]m('kd;%f/P2d-oMF͜3sG,ξ ³ UxW<40-z7E 5ݧ8rGu/n-9XSDkv ';3B潒,@(}UG픐~ +-FkURfQaL -}SX/2zCq5yXre^oy 5G}H,m&r z,VVU).P\xK+u.P0YsǴ>ou>Q[ ++g؉,,&;KbQn!B_͓t6I_wEY t'F +AіS%gόaݜ[TuH,)8L Dy2.9!1f]%@C}gbB}xg}޾vr<> pkMNM4Mn3oM-Q,Qq7~({^(J'O$ {3 _HĢ_=+cS /' yDWŞa$p⚚]nS$Whj'3U.`,@P-VDe,ð!BD:Dӊ\TUˮFzL +GnaVߦV`k_UQRҮk*+;=GzxGҁP#-^=K_]qYyYITQk2s)4ƎK!UcQ+W܄dtt6AM.Xݒl T.\Yki/0FKdl}2 cQ/3ՠ1 d|ԯUҙbN}'HYl=p1׊7<+ΠeeFT$#l qp2ml킔LWwX%\. !V|t3I? =|n3qQ5?Hi{BaG&Aԉc{@/K}:WKRaU{|8M#dr>?:_@]Spbf->$m >):I JN]n?n]Uosn='=$I4!IQҊ)! !! +BH-KTs?@PSHb-3]ɿKW66"ܭϼlw-i5b7t 8צ cNlfz#& }Hƍcj*|'3'IM*ΆV"4\23]A{@}o#aFXڠ/A1Uk礟&8P$ZOzҵj<4zޯ%5$Dʴ'Ý5'vۃu;g97,0A͋͜}lp54 :ǫQ )gxH W\+UHLn6lw'ƍú45:ʾD՗#x|^Y[QC'ZYiTz&\BZZT뺢o)w*eygqyY({B+2>*mh^䜣1Pl[Ct +ٵ:IďL4SO\`׻zK SDDvDs禟2yJCPԀeO:mVޯyg++7 T@q֒S5,Ħ%ƺbWPȃZ}ÜKqz)A~OҼ2]u$wԞ#]ɾP 5?;j4CDmóc M;}l8 Ɛ4x"S)Tx}`v[3@va*ʬT0rq.!,N`` F^.kA,['đBAϖ|WOG>Oͷnn:wu~3l1EG2> fZ$s'y-I? +?3:GP0!HG}L&J^X/ E +fl:x|ĝÝFդ"o`0TF[h2hCKv*u.YQ(nU,[ɻ5V-'6jNq:N3* ș̭ZunN 5J;^xUIhf ꮰqw[ͅ {ܹ3s̽s̝_;ֲ֮O˲lǖl&?줎];MBBCj(&R(?(Zз&RC-ྦgfvW2s|84aFdӮ r +QSKC/S7 !ȼCJ LCB"2[F1vhc\M;'*'Q?#Ñl>V 6q]*yЖ L;{ZQlX$Ec`t ݁0JqVyA_jY#5tԣ=]qh,w_K91ءVX-vS J#}8ODY {ӋRbȷv ) pnh|K\`1|nY1d5N +$XdG#f"~uV$)@8_%=;FMqJ~F b<"ÐZ cx۱ZVAsj۲ 5u B \6 (W %,M]8b}˼btb¶-d"]=o D=kKT8 #eܪ9Se8hK !K,r@<*c^9^s7)6i%yT@*&sEU ?DBn [x`ub_)QBZ *S){S(]yz"LVJߚSuʪq>>׾7@θ-yd/`s<h=^-j¡b~-8~܁S|ӖU޵W!v YJZ˺ߵOP+kyCPt)ϰ]OjkXL" .zP(wJ[_'.0GSOME+hg4 Y0~&|ktB-#629|fmL~H5\{4Ēzߤ5ֻVlo{u&|a )U½ mP\i2Sߠ'y{0N^Lv[ae Xj):_W⢞']OȌXP-y~L2j\x ;&בI<;}pܘ8AHqӎnU"ҡx\RncB`Yp[WÈR 8Hh=)IDzW-J[5b oCӰՊ4SF6Dɭq4yC+ ;o'կ+q{:%:ףw,7@TlGy[_ +/8'Z5]h(NԧgkЫ6es^#-ŏ(壯INdY+ډG0nQ墖*fEn6Z3:pKk觡ܖQqX*(2['/&"Cnuu[=V!f²[ +ʼnt؍%Jz(_:/Y_7<>>;h1:P; R/z1wET|{(%vo-M7,1'ށ\ٹfQA sy>躇省a*\~3ʝ ^ &>(w*M*ߠF&]"ɹS3K!,_Zχ#}qMv2?P~! +r{]5#@ >JP2%%rKً"p(2jbcyB#QE=gg6v;vlc͋@ 㟄| >@!@r?@B"H̭]81u:sϩ4{jءAf8Pհ_dR^鵘5$ʈkvŵJ2+ +`]),vf9;Qe *S+cϤSOf@[į+ $%O]}`59%N(( +sۙ'fXK;o HA^ J#71^;fGĤTΌGf[LSl&6p_|cOMk*1}V_ NYi+F x9Ps8S +cL&Ӭ)S:͕ T>i|\PQlp-Z"#֊~+sMxv} vRV\B.c3Αiע,P6ė 0]zFG=$ tZt%'m"N}V5ʎ('-5a1mؼ/VrA܄;aC7 ++ׇe/œԺbd;qb4Օ xP0z^ z(& J)VVI=֦|FЫQWg +X~Eӭ Mԗc=2:)f?rF מ=l-xH $#ʱ֚vkZi᜴}Wj|1(uICҌ-k'tf\]0SJ%\dH Tk&;"~owa<>/H|+vmUæf&_TXZ%Ig7 |l%uc}%TAR}5O|wziK/ɫ |gtj:> [iޚW3n4Ft !*,ʸ7<Ȥc7Mv|3~B>I-|pk#&;O ](Ew* R$ilxsV qOs +4kX&m@EyNNQBR71muzsCߣGo5@^}1 ܹoqjN8"3bi$Ltdžj,%dj⊸8}`CΕ7c\S_ ^.YύcĴ+W%yY|+?sK=1Ax ͯ0ddh8jZRxRQ01 's}Ǭghlg|pԛ/+0_wXGg!h:tL opU,Ng%%úz !zY-˧g0bVz[mfLQx4R ݳ,tEly^hf$4Oq(%%\<џ!e'ޖڰlaO2mT.)_؋c?*л. u+O_~S|,tb倌f]vAY4TL, d;|E;qfQ=⩅TX [ݕ$>x͈> ]cVn{UKz_n*oh[bVQ޹\v5+xGwq=s9sf\uwl뵽^'$4IiMHEAyT +! R$-J<*H!$3NbgkiG?h̹$/aNEK%4j٨T y˻!=$\y ۦ+)pFʼ)4VR -]R=Uބw2,粬0x#,K\4E3ρyfkK[ޡ:86Fb,4,˵# cpQMEm 7H(0hAE(OYupA%5GhPe-c(Dx[>+t˷]4NHup[yb)0ˀ~PvKQ)`{"(9/aή{#vCg] )fo(onr$@s}b[zxM+1,W2552צ@ f\X9}]2zD +9`ՙ.C3-@|6m%(!~HXNVb*'B=RmYg% U v- :[n~n@]q=el|6c&CpO<7,fOmMHS)AfaA:#!VTnmў-@!?,m$?T1a C !7[<+- +7&1u:V99i$1v=qq&KD乡e[ SMft^Z_ViUB8m{k,v̰cNL:96PxMhܳxH'^e Ttu6$} +l 6AʦƋg /`svz{;ɏV4&EU1mj8"q)zj$Z1ӯ/uscceIKG)2Mjc?4l?cC4#cX;{?<1/nRJHyo{Sq~ѤC7AlJl;tBsg wiZ"Tp|G^\._݃UU[/u%K$OV$vplTg~Fn"Ɩ6`y+ جM5.ΣPѶh쯢8 ,`d,~EyTkɮT*OGm;6cmzb +IK3HY(hO.D 7Iƿ"&?l^7]9՘Pd{B2X"OCӆA^]خUc3 2C#NLWv&N:\f1.Ӧ}ՔĺO/@l.@+b`PtXMe4ޜ!cGD$z-iPF>S*mɓ+pv \ܿj\>='vwo^?[G{0jEEԎA**d n?/~OUrG߹7ϙ33̜3mgv^l/{c;q8GNJ.ͅ4mZ +"PDu҇ "/jryCjiP1|gvv.՞;.?Pqc4+0y^^R+zklR(hɡiXxwu,[Nu Tlr-u(.S)D 5ZtK)={+d܁py04X]}Druč4}',fitx%ABzoC0ƂVf僳@`S8ӏbcS]xkg>+qkBeĵk(RrpXLH/zE4IU q-!%yէbҿ +S_ \Swg%Dнob/_(h[ԫo+ەQ/fb=L\>O mz$`-9<|֐a O]Ua'ԎlK00.]RKN*U2Qߊ|Cbsز 'lMSQM#Iq5eʐ6;x<$اC&n{nM%H}Z$j tqUSYǡ[G"ц+גHtsEy#NbAV念oV=7Ï@9G#(Oe[둵۾ T^i9v>!m  QfiX?hy5k8qd;^SZ!O(,!$7J1K/ +a`(~Cݓwn2n^m~~jׯGYGc ;E6;GPlج`P|2"b >_$q2w*i.`d€NDרf^C# N~'[ȬNP$TyaL?Ѿ՟X¦-MdWxt}q&p{`\R|r$MOAѾV/"S@x;T4/;SVW9jEZ ʓ5qV@2Y̬OIϕN^\Qi{H? P`Q'ZGLG؁J0Ե$dr9Ȗ*b-?Mv/K% (y %1\E95ݗ?bd 0ԍnx2M 3 G$'H^N~gU +ܺ}q]wlJ:Ȫ/!p-SϓÓ=2a]ṯ@{=$}6, bƮy<$ !jܛ"!k6*] 5mf +JJd*Q|.a.4 :%G)>mN ( o* w ;7g`vL.Tn2-OϏ,z 9Ù8T@S,Y1=88ֿt)[[NMA|ivTOBq:qd7i78 pJk{~HMC&XގF;A{ 2=I"It-S-Hem\sTJWe6<Œy}%( +Ĝ"pdJxn|"Yum1Z8SڧеUi?+Pn_g#q  R0wއ-,,j5]0sp< NF읞^_7H~(e,u99 3'q"C7멹^4K23}X"(kkka<mB"C^49[ʙ3I2|8sɐ(,8H!ᨎ? +O}/T`Iy<'ϖ￝%C\mM/%dcؘJfgڟƵ%1 떽&55uVFOs(ɡi[ u(13^%?r\eޫz[{jz{z3ff Ӂ :%EOLW2(^=0ǩdJGS‹qA!Yl5oR[g{#K89LWVzXC~K8fb]eqPjmXZ3dV<@e4~ie8w+f'۔9\PawZGՀR5/=̵ZDƀ밍=IIɱ}Nx^;X2.h_\ fK3l-Yb~w{cβ";~1CYc_xHAZ!ŸjiQR1*,(z⏙Rv`~Ck45OQgC)wr + +i巕 K=qHiyY3ZW"oC>E逢T`l/nD^?X:QR,n=>;28Q 1SP#zxX4~RK)]^\[w|BC(Yb(>TD OyC؞6kZuOsaP 1g vnί`Po# +`Zb34,֝V + 7J$Ix LNi]r\!Cι 7XMΥCټp6ƊQ5,Lc  ը)dum#MM;,\ͬ**"0Uة5.{:7rV+c?BG.O1lAZʗM &MfJ$Z* v߶%CT +wx3+}R(tr\ _X=v|LN¡ƭ=[O5mmrSS7yj{(Q2hǥnu-*VY; + /fʔE=WPE%nwُR4ˉP#0%D/y zvB͓C $%ɷ`bWOG;(k1}%Rci +6j_K=:#_SXhRN3q +˳>ĕr~kpv>X!m8<:1u~j*㲅ӃJtƽ@_lw-j.W(ڢ#vY(~Q)d}ZC;r!@(S:9Y>^o-dԤ7t\nm 2ͤ6|w8/Py!Yfսfw +(BuY|=hx*募X(x-ElWYW[u޻ggz2xC[ +! YX$R$b"P+'_)HApg ~Ѩ4uw=i4֝<Ձ5f2&?(Q!pxgs{be뎋|߲@Z*ZpUm"\7 lϪF\u/tAta,T_X'ByЏA_xTV0m&٪jvރvDY]*‰2=ێA_""oI# 9ZX{?5H{W,2 @~끪ؗ/MMS47c˽gB`{-Q]o[@)87̄Ij,Nhxͫ~'d|"C._LӁSa-2א~L)+=tdeg^GwvbNVMDP]&w;3v2;a^88_@" qЎ¾;S5Y8 D%qJ^@3Lb:pa@ i~)[Ð|˚͐:3ֲvokͥN_vi1߭akF1eȆ4iV4{u漢JB!$0+ }ῡZ_rb'F) (Md\hp$zj/~ +|vGjEUӟGsK1 +SdB!} \T_E}y 2jP +%݀z(N"Դ!`[L5W0=0V&"E8o9A{.e[#2ig*%sI _֏`oШA2@\p)C]A~'qdO9mPq7m 1(.0MV4z0rGZ!bJlvD7CU+CxvnicŠ|j[J,Q IK[XಢI'RSzyx$v$AW3#PWW)k?dDyaIm뀟#ʺyˣ 8 0bLxEwW^0 bcNK + +F*%SPu5_#LW˔z5yhc + +\c6nbJk/&Ԋ%%\ wfPo0^vɛ>Otj\ d2bp2-.~4̱:Z4kEIҖk M2}4l>S+V1ۨ?Z !Cs|?LpԬ_SvYpB/*mfHbfp +s0i.)hTeJ&yrLNi!ds$}7GO] WMr +śM-ǖq#Iu+do"b0R^ɴ(ƓA8)ҫ6T3nu;;fmC2۾ema]Ԣ-Tኖ@ ޢv,v4N#@PW +Щ\T6>6 +ڙfbaQwO|Vg~G/.-v~@#8yO_UͭN-!=iϏ[{j_[gJYTP֑Xl> +&)9j@]69A.l4(P2[SM%o»U[;[\^s.*Qj)Q!,.8@K3?ɓmWCڌAݣuluhݐD/(n +D?OD9 +v+Xs28wJ :z Lnwc<4~D/)PǜFF3kٚȶׂW +&|JW\Ő`vcC[crLz7K z2rwܣ|wyW"0Կx"LmKU .vHYun@ϻ˜۾[naD#ZڋT-Mu'|˯CqB8u2挭d(SaDH_BS}d&埠6XoZݍ-l'h)eȴ HQ^K/kQ(|޲OAY+Re +B Q\mBL`;Y3z٨3E2C8l4^ I`d<-W=j:|e_0EmAfos:{vATK =@\%y%S|3(FC8=4LG+g-*l:lw.rLjjj{u`Gk2n_]fJv}l2}ØIVx}Kz=,6U >Z:Hh+_@mIl4< j-3xfsJl{LB2Owr'>2ʻ%"w)LjBHԈ(DV8Y iq%\?'Rl^ 5 uvl"/wFp<[ǒWA M̀u6WU|b8CxcbЖiߍ|;\zWV:Vd2V2p]#(xRf,vAAt^Q%~ԲeGKάA}4C5Q0ߗzJ@%b~N'"v-KUWFVT#"ߦH*:Vq +%U`@U *#DϘj"A俵fzĵ/׺x EFwl(r ]l..' 9Y rd1gZ8,Q(-<-쌕w,J#_iG7kqpqFIEHV_#y,fd} j1t$Aq]dneJS?%֕_hyk%|n+Z=EҰ/Y& cʘA 07p+=pr(!@16~g=I; .$=矁_ +ʂBsF*h**!^*؉m$ .x ϶?}EcKPHC*Dg!ZP3H0D =nX&_ FpFojE!橢;=uvzuX*c?[u0И{fg،Ys4 i;ICrD9p_x@j>dJ*Z%[u_fX-o1X4@.QzzռVv|Hv*L),ؕ|%1`螪ej$ .T4 +"]*\RtJ:c%?Gd2kݭHNEއPlk o={6~qىPq gn1 I)h_ }sֻeL}<$ +{4fWJ#Q`ouj(/8F#t߀Cb_a|C4.3; %u"#O8-{L` ]X.eB4d_r[Ƽ`ĵrCMnW8zNMUo (E^Fة˔nc5\DVa+:*4W[]t,<['=ȍ'3et(2[Qտ]cZgur e4b͠_*^&O]՚#y%ljԈ9dd;Un9).Mn:}W˴>0>kwoΟڍsvEG&Z$TOa7cfMiD<y6g<"w#}ɜcwkYCC^SNܦJ<$'jֱ6mkwm@< ?"VɱЛau7 HW B +:0"8}>0"\lv)CqmfŭB$q9E GBm\ Ȯ4/оnt9e0iXq#ò/L3Gb#=2>\8d~_o;': +HPOwXĈql |rFo19lH\61la.F=ߕE"PbmTס%ʁTK%7iQ)f% 7?pnأ^*c@?\+f{WR`Gwru<ɺ]h13U+pl?㆏~Tq +y WߧKYBKtK0a1t99O$/C3[Pûi0{K8cթaUs\#s*-c/dn, VĐnox 0:K1ˊR{xeḙֶ+h7H\Kb͎f 'P%AFzMp„kVqi=] +9_ߌy%q{ @ZV?Ǟ491N}7 35ԟ3Q~yZ|ngODc<{;O/{sI9=8V;ѝ@=3|uݲ qLdqkϺmN:)-]Qwٞ9͍0g[2ȏ./Èizt^/@tv7HNɷ>#]Jg/^|};y.oP~4-ů殞 _G(GqqN5}̧\svzǗqqDrQARUR>h Z xA x ԗ /'>ut~`|l1pb5$5 pO@- suʍ;_;2T;=Yv3E7`0kZnw۾kKqj;iu 띱w8$2)I: EӏB:`~4_ך;oM^oz>ww_/v Gx:=WĤX#5֥߯D' +"/B; 4l4pv :ͿF/`ۿEWrydYUD0(z. oF9,WMԜOe:u)y+:Xgff#X(PƏ?69nX7 AW;5\qՈN+HW+ e_wD -k7E`,w~~G܂9$3ʛ݂R`08Z`tcn\`!&I2'R"H%b2m!e<*Gq3)jp/Az>j鿟D`a)S%X*aiFw|[os~1-UD0?:sN +˼fmڊMb} X kb+2}*hΈv4;Zr{vQF6m./bXG3-Vd̈k1wnS@'S(8i݊]iqDฉUW.I&ڕ0vNe>XeqlGyX!:Lj8 ǶUeG,ۊ_rI:>Bb'|g#-,qB$Q1"RR`^~I^ɓ/{6"hn2Jf:~K™Ҡ-Y + t~F9*%<%dO$#K=ք D|̝ ihP!pnlO3#  +B'v܈SNZLId⇺GRy*ݬ3]NèD`Ę,`^H5΁nZYvaohhT'a5S"]@p *AwX\xg/ W1*RQ4 ʻA="!iTp'=ppXF?N^j#DW? 9PB&fݶ^^^7?U#U-UޫUu-]MwLw>35NŖx;2GAAF +!rA"#@\9`8!H(#,zJR4 ye jOq ńgK2I'B'(8qcD>3FO<"4 n#/[J]o"7B65qĻ~5=SrqybvWߞzåI;1SBW+W MPӒz`G߃?pf+.{ViFK&9acfq_ )11Yp 5aJ,]7hv)(=Q-oD8֗CY&.2K{*&+YO:FFSQA?WޯJ(zrz4lZ-;v$WaPHsܘ#)o5L@u^L:+.`W\-XzJm"kXw$[tm6͋p,o\vZ4ib8 rQ$T[$+Ȗ;yLVWn8~ @zܚG0(Q)]Ot[/˥قѢȊDh>L M1h$GgW )8 ?]s2'RFfFސ GM `W>(k /':Nˀ 9S.ExUcnخFf"U>͂+Fun_D0 n[Ud'WOzקA7}(c +_p̓|oAט;? #?t7dzۡye{ڌkK|"ImGp*P7WVUbZdїC}2<@y# Ծdcx,&p1T; +#բgݢ@ Kcnp5yyE{&=l־Pji2ƌUEj>wekFA-Wt敌?ء&;as ;ʥNݱJd-]OHfP`-~bVjp. J4y'" u?l:W +`HW8"i)Ir^м6Z$jA]ƒz~Tk-`L#h0PU Nc颖O3EUm8e[FĐS$!PvPQa@s$+IT~ƺe?]1h۠c"K}?wg/r66ōBʳA +JNm ~IEW6"aơCT=AC݅ 5tRy-}bg.[=ԾB!nwAl]U\?v X){n#n?83ͿԖ@v>J{ +6*ޤH6Txp#L*Z޴տ3LZem9)*]?0 ͸C7`KG抏s(eGJRpM(qc]ob[q +P(~O0|8&"Qɝ}S>`"e[Pn3dj?U&UXaAg8#x}ĝML1',J De S؛!E(;z~}eˍU逄(3sY@aF+{Nk\NU>S{4/-ΪʡvZ;!jIUg - &M=MFl{k4u|*Id[Bq[~df_" =',.$!ɥ3FfNG5/ctw9x,Y ag5Q[G:pANxY^$獈A~D1UkOn ~$ħE jwf7KZʟ/"9ZlPY^at5FNCA*Ȍ;pDDZBaODrO\$bN?1On_] ٖUzlxv7w̠XD/LgT|I#^"A}\~hِ@皂FWy*aD.rCHx C.PmR >f(9⟪QKg # vjHGFOS 1l=\>~m}|u^ȱQvxJ| +؏0?c嘗=BC_%ܮ5), +vjz?JhN@x| b7zqB^ wr׬1o+ꁓӚeW qsHS\vnW2x+l2%{qC&${~LL^8xB%\{*<9jFfۻ-II=k:?vR09|;$R^\%#:p٢(a6a׃5M#wkWk6u9Np';͑ +rA#+LV +@!@}߆#>)>zՈE5 gF}uC ~FQ@q'qI[^ 77{ +[*ᆰ8alY~i YSP + 9\=l ۻhvLȆ}>vt2SAE,&hpA3Ci0_ hԙ_4Ѥox\g nst* +S{h3c^8p~33d=m=xj~IE깤v5횱/At+밀r . GK4w nww2&n]pqh 35'Lbʪ0|oWkpygW;Mbg [iP+A(HHeXEj@a,@H; -m}U&++Ks9̖f?xڮW-, SOs;/sjNKc﮲kWh !FrZu-txY\S"}s^qA,b+8 P1ɲe;d_UaWlNxnPk E1 |^QtOl"T^'?WVWP -BYUd:z<|{u޴f!0y7`C^{s2j<$3-inM?*ɜe:6dv}W֖bdmZC}d j*RmwVO1 E/"!wuE3ᜢ=@ڏ@o8I>0\ +u0 riCzrh8X4բʲ(z3'FpXXű'UB#S'opMdnV2_jHKb +EZXk R[ -)`)iC/(M3i)ԬqY{慺Qc.b|x7yJCxh"ѱ.J?YRj9Tqvzp7kۇ~7=-'ך!96tAǾ;JXpPʻ3qeb}F=6>VeD2lDƧgC#fQh=˴rk>ڮX J7qۀv&V0FAhE~ ,dyy\gOՔ%$~Jg ߠG| + ξsWfSy Nr6+/?Nӵ99OCyHuQu$\Cu+RC r$ѺfЋl;`_8dawh&Iywqq1xrWk0a +K<Rt +tN@e{ ` +sR*<>h!Ub2+D;!~PݾGg=XSvLbW;cYϋw/[ +=G{Q(98/:q9 +fkUY8Mdp򦠞W\NjUU}L7^Ӭ ?[3.w  fiZ`r{5jPrpȶͱ}nV 8fvb^78V(2kh'Z` l'g!ǦhuO=zN Txj]Z 5ޙ!Ӎ2ʻŊ?*eம.r^7_$T0Ƿ .gb뙟b;1vAF$ѰSB5SeN1$'8ƭ-C5,)_TuJ>& Q<+\dHTw||>Km0lkjw2j'0S u1;L;l96N3T3z`).tcG5tcaZV8s5]~=;^e`a5y!* _Z"lR65v~P3.ۙ'mUaVvZUe=L WF$eKVcKֆG'1i ^8nV-|9UU]Ͼ̼`>-WN+Es@+m0`)+hI L/S&8_B[maQI ++IDBXIalw,9En9ණ٦qkݡ'V#l7gF`Po8<%!V e'p/sषt¹b`3i*ACCH(PVY+,y NFh#I5_\ly[_Ňxez)]E}f5a[MxQEYXi{V,˪ +اa i{oG,io:[/ 0ͅ'|ʧShX؁&\:7ٰ*GÚ釷_H`Hu,ZtĞgA=bCz GA)m:FiS3xr[V/=E+cTrʣ167 %m/Om\lWIoꮥhf8NgfR"l6-H(%$ڲ;o% )9@N \t1b|=i &[vPhN%?pc?oXllvQײ3PxbdAPK3T#MVXhc9-Z~vrȺ{޳'ʗ_$Q=JmUN- !NbGokuICC0rVR.i´ P)K~ͣiS-X6uIvω#?.|{ܴ ZRË+xc|_F}JuaԠVII ʗ? +t/o4NsԁH4?'Pr_#"~Kڻ h}9Ul$a16y>ˁ"ϾjvLYTV!JIOH++zAA_Q4C5hp=KoNZ(bMY"{2^ +F +wNC b"ߧ}$z`NH&^<2xp]V ؽ')u8˝+?r?W)R0\"[k -C[e֐1Yȕ NPPOe/#ΈHTB|NY!lj?Qحǂx+YlSQxhive}I a")l/tJX|C9m%M^G$cwo9> $n _] A5~Ŷ" n(fmZ0,S\ÐmTuH&p!7fws6dFcy*KK~Cc`^TAy<d/vP3 <ק~xPAg9sp2]fAwL#<Ą ],8+/5K$+ ltNioH/ز[;Y^6C{g480w39G +pjjN9 4FH[%^C/UJ}b}*g}t$ĝt"%0Z%6SGDB%_bma.V~рkQeS\QKzRd:?TF?S=)fc\oMl[eT'CJ3qHE'jAMυ9>{4J5{֬@Dq,p}sF|* +Eot drZtS 3yQL7]t[4s.bX1Au_z3b^5E6n/taO0o/@CwEӟGKe hMQNT59Q2Er9/Vj +6V ,rOAIeWq51ӆ6=dOtwʬK7SK^JaG ?#ey…yJߋ=b""+9Gpd?w?q=\ M mlbhaѲ08sX0?&t!.|Ǧ1ϥbkFPႀ򾖯<[0sIc5[c+B;x:SϞݖ DSu*Y=pP]ȿ)) ~вz \ G ̵F.Tvt7].S$7PUPt  PFY=0+ P96<-i);RԵRmvѐ7l{>U|L-H,nm4GxocM5a3VVWɹb"7X79 iv9\7h0 t+$)P w5X3ٕJfs9W 9Z~ۮֈmՊu6M V(QWs L"TAK'IYE\{D;"gNx>T|h;&F'=Tܬv*V +>lje'MimQ_,MmT#yI}v WGP\V Dz3'peCu,ֵ;1#xGD1}ͦ)^?\_Ij6fSR#aNV=MX6nmtmōIfz#Fu/-LQ pU5gSbf)HpŜUn$3ѫO]wN'1ľ1] 7^ҘD4m2.j3%;,[!MF5lDP.*J"QA݁< ۪~4dه9w.y]ԼXL7CTcF[fpyn؉h;N (߄AsMYي@ fx]V;0ݶS1haTvF+(`0n^Me52X^jjgoƬvӾ=Wo{Ւe g[2/Z8\Eas2<|UN'DueeeϮ7=AcSV:޲6þlv;Fu_ZB&,q`qP)?j\>k699,w1)־жD;jp_WZ;9ЮLi?wVc}hi +Uo69OiD Nt5SPq=?#vu)noi{=轕lbwG>끑?ڃS#1T2TY򨏱|~b*m-y<(PrJ]N=Ẉ5*lscTd~{=q:>&ܒ0*()wCl 0z`YjtH=ԣlҁi3jk3Vd[nr3 +slsy$ 'br'O>.IA_0I&JbWvD:[D]ޢİ +\F f'>QV].^8sTy5.NsJgR}vdԝU4qs &ViVR_'S$vݯ% dK)bmdF4hʄ0(!X%6_acBDcg`Y#'y< SP뇒^ц +v0i( @o!"M$htHx8x"9Ichz޴Zp{NgS8!15k݌Àr>- 4W^׺[."}ƗG~}+7Z.@T !ď(2AN}փI;kV3C;TXdէ̘2cB|w08ƌlRPX|{ 0+}Y-5] ߧRpsđjd2B[__*O9EN`Ĥ l-Z_ad)s3jkoO\@>+/&IrBHrF᎔QHWGlg!`u֞lS ǖί 3",շA)Uץ{0E$JvLӺ l }TSaꮣI 9c4CAhHJ3rwmqg_1,ݣ/hs^7vY˸.dW*,-{xͥ #z<Ҽ*^58XsF]3!Og"|.?~{< Z@*fFv>bfk =F.ͪl5eCEi /@ ,VļYiqzP2X۸h:xއ#;ǜ@JM3hcc}0m[[/ȋMRL"iCQ\|ǶE)C:bLW R;B 8yfC[ sǘoحG b2 +=5͓ehMg}kgij@σ+)w9Jqh!ҋpwh0txƸd?pZ) oCu!6#||bZ֕ X?Œy~ʉ 2uE=:k׭Q̋W5lB9XIZҮ?-㸱c\Du}s"`0F0.c&R5H +W6k~qRߵj%H:v  ڥY +er- Njgf93sf93]{d7cg:ii.\Kiڪ *.UU"x(AH}&* +HHHTJ#;L'ewv5rJ8\Rpe5= 28^S|鬅jJ.u ,KB+Rሑ%n'=ʑmSe7z!*<%";C$?$}O+KA}džq6R!q}Qwr/N9j6N?ɢPaw'+0p#l7cQIڎܳ ֢r[M^-G E>CL4L)Rv>dc֩edZߊiD-fT@,B@ &d0P{:2 uWe4to?B~EԩSg$Y3~6 [w]wGV{f9587ÏL| }q:p迲puGɦ}3L@^˖Z)dО\ +| ޷~ֺ`]m,W2ܴͯÝddJ ̝Is-F]?2Zfmv;y3~q<^{0[X o?$ Ժʖjm64G{/=FAnYY/Ao(s@a +!Y31{3kTj$#w 탴!@n'PPl聱F&2bP~Upwo;`ThgL<";6d)IGj8Cvpaq AnN60k$\C+aE+ v.!?[笋~Mddj76o+>b>;6Ye8A2P׫T2߷]r >w&ugڽ];$}$( 0D=C[_S/ld"AKΒhZX=k +yuúcmO)PwQsGz:H~snerPd&.JfrOz :W$U8,u$aXxP,t/ݐk{!#%&Jx +<4yMD9N:Z +nm7dPc">@%kVkФP8KL/quCB/i g:Uzt\d |7Sy6( د[ݧZd|nEzl#l55B +P]N,S٠YIieۉ?xN0\s ѹ HZ/T+9*)@NnAhG!n[׬ۆSԽC(d"/M$u d!~0>g9gל:cY$8qcI JCDMhTh @/{C .,7 qAAA\ +;3x7m`3<;*fsH0Yw:`>(X]U ++f+(OXH/8B\T}I3J#ۇ8>5Y9LBe@C Eu#ܾI|Œ_G +5B"`x.~Ir9~><4B~tၸ݃N];Z=pO\{[<Fڎ]!)@4S(p f}yi+GHӍ1-@/KKlk*+Y/^rz5#>˄ZgB,"[ +=q3flkOR#lՄ; _iDyפ\w0]8hq&P Xv0#[f1h~W*xLf2˚@ [\iȳv_H"s f7k zu=T5?=fFˡvm5Z> +gGm5@$IC\6nrC<ҼŽ.n^2ݘE9jB~?[o"`qvl̸27n]j +^ĖEžZ8R,|>y9T/DtcX2hx&ɉ2$X>?y>OCq60i?l>5`sF˯M N A +26UQ(ݺ*H;[xuVTCĕ6'ewBM9`ӥJq$-,^gVFyDR>6BE,M$am+g?abbZ3^P݈ He )0P@t}p_mv։UG-%Y59,69Y)Vh0x~| RۀKėJ0^\0utPqz5rC}7D_P/sGQ-M+Nc]w;Nr|CDѠo8T彨ppa?R kϺg2 Jb +3UQӹ骎}(c^-z6P+^91hS,3aMp D`~S{qW#3`&pp`x8ym5tp Wy ;m7zv8Nkg(p- Y+:C,z532)^蟄 LvAc瘨ONS¹^o>U"\ lAwRDg~܎&G.mg o\FT9u{5 *A +_K=i|JҨ1@K,g׈wΊ0 +F҅h 1]ʓ. /Gg1#ݵv^m_d9Yw a + +.z5> \ j|,툟~ЙNwqz-ի^ݳg=[wL388 J+1BDaQ؄MBB +ň\ !q`BHIğ@'0ͯc+Aj)t|˼Q]B+DDMƉM!NU}hzo\Oe~S3hF/)B]*e9 4YޱbcYB}g3:x7cl̥;k{վ73.`]pDю|<zM2l_6 2AN2)Bk'Ka8ru5 LQyODxR{c yP]YE $"r R i\Dbpϰ=[q4ĪKdU=b,0RУ!*h&z`Tiz<4b"N@2帗G}ZV_? n@v<=Jc ^So.wn9•R*?ܹUǾ?\χpKך~A oĉŭᷧT|my +4[mΛygj=¢^8DD'*DL<{KQor9Py^1PddR=_n ۩Ņ<1&E/@Qe I`MȆۉg'feRT{" +Xn\yG_~ߗI^XWFqec(˱dk<*R +բŗ|'T!$jD_Ĭw2}#N!3$OPoE?D' xBb[)H= (Dwj-OZ$򓛸tNd>=J-hGb3upm|lnժ},/#WMFe0N\ n+HCXwްgL蕗\+ɓU`xΉ|`| Q|V1C=1Aj=@iBM,pzc7؝Gq$0^s9ۅEf_F-*5O]rqNǻ/һP|u`Z+_:ŞNjmk%lY> +@4I3O(th7<7)i`ONzJ$NΜOKnhe/Hs lmsaa!u>GfL#QsHYp?)_-݈і~]-qk3RCw`+&0R 洆rjqD3F:Se ]waqrٜ^|W`I+h3Ptkm/ژ;$Oկ٘f&=m=xEu\'T@S4M,  +V$wO/Mk~]S;\P0XIDZε`cA/o 돑L Pa@*b n? +Nn/с4R0x&ҹ#* .,VZiji+K5\֑';> XO鼫EGh~hTc@,&d6GYx.[$ +ajE/ȕІ$e;x@n/^~|;TjwLs0qPjwc0LH4T'+FwDڧ]@'WJK8-Jˉj`m[-_X~ RljE<@J~8O =C/E+jO8m8a*ጶ/ToPRTkSѯ:FG#Yn K[UޒN\ +Dg+ӧf4* ',1 +VL +vY9eyhH>v/82#܇@OL`:Yw[e@ݣ5xLUbW7)#.5( "/@^xM_HU]]_-?jot Xn/D!ocx)=¿J?y܇q{'fJ6FF:XU Yt| +}3e5u)5蠪VMj {8s_ŷToZ,5: `$A0'3[PC/^b0viJ?BnGE7ydxkkuCpxX"kŢ^\ N貢F8Ď }C{j6/ MWGtRv\hO?N#7w|^id8z-1V ~h`hb8)L.gԎX6{a:ՙHuPɹ2Uo -j׸F)==2C$Ч) +[g@$ +[t>)3w3[ +kLn#Lb8Uޫ{wWwUtt>Yz8gE b +aQ$!d!8 q 'l$UWbG0tuwLo?lXRF=Mc5#=Znɣ*f}sqyC>q0noA,<_((]&n*s{'0_9׶{`pp3]2ap[@~]ZF2rZ +'v@?=/L7".*ȺIZ{'G'dD^3@烹;h٩)Kl9iݜSlvA #n»&oŽ{2~Zoc3a&&2q.myJ )}m=G^ tJΟB|xs€mYxجp:E(qpu*kUsZ> +OQO0ۡ)Xq xC \IWyϞV^j=D2?1X뽫 +E0a)Y.y攷 %lt]aty  ;= Ěϯ$辖a|@Lz?I? zˮv20"h +# ΅C t(eUޞhp~??s*3<.H~-Y2g螙5;wOa(E"m-bd;((?]tab㝊^|\G'^m%PL%Au(a ޭm q?Z!n7(fI\f_X<ҳ>}f ^JA}!M{6.OOQ +|etb)v2%NO(tQ:85}t][6sboZh=o[*8ZQjy{sCLZmՠ 7˓[p++kKtwR-ɯ*a wx\:vb\),LA{|z@Փ9Pī99y v'7  p ǚ e(X ) P10ѷvww[wfIRGԿ!,_fX+TDXi$&,BkC#ЦV'.H]QO8/FT=8)6T +_1v<<\d"IU-㙙_x},jh}qSXZ3"TvblCIjhlG>a3p.n7:LOxQݸVBp7.s.%%._LjDe}+ +?LH[FzNZx&{GΡjMr(q +evE/w)uAVy-qNj6hFpa{ր"iزb7F@gzmю J; +Y&!VғIcXm'%LKiZV \BUC.qW_*O_ĞSX6b譏̙3-l"趦ہY.#`CڳAԓXfO~7oGpr*ڃc׳m)>ܫGv?-LHi*^~l-fdcyA5?!O._]NtW˩J߱FNN9B"t,C/J㣁xv_˭7 {y}=cOı08irr $MI "EU-B*nn?^P ) +_PBBp 3CJ4ޚ{s<܉O5 U7 #UvO0Ѻe)_oC:G%nt3zP)Y`|HL a0:OK0[6y4y +ՌiVDqi9C3!}4 +K$ +$*/:~-v}^̀_!R^\iC\7 G(B_9k +IuMaoENNw8hTz7Y +>G{Q;haPm,ЮԞy/k! fP-pc7yΕޣmTTQ6СZm${qE9loWd˄r*Np(WKl}[(}O; U8Gϵ[2˹M{ω:wѣ*TWH8J*TƩ9l>;Y,g-\& g 4d8V 0#0tv + +Ւtyen4O.1l zg*7&nUڸ`}Čj-;vFY1DET&@ ;Kx^Nn>G +Hj0Q{3Jz#T^39LQi\svܧsfb$4±ĴE߀,$(,|^2lssIj'FAi_1VAe8qH~ȆCjdcHoD:M{Τ+L=d><{eC9ъЛ+z)Xu >^݃}@c'(KibŹ{ $ZQRiQ:fKəmCdf,M+kbhh:KtF]Br"hn+Z3u=>}e3∀%X;im}}o`3)򙴔a1 ]{Rn +U.,X춋^gTVm=JU0gNrc)^pi')| mfc KZo͌*j5gfy#*UL RFڻoDͥ?c5T?:/[ǃԠ &S^X#1`&#bI:uc9|c%agt;ї|pk^?aTIiWRs\C4F6`XN_8,wEc S}hr7R>Oa!JAHY3K`|FsX/55p?J"=bV0 ɭH-s4 kE[е^L\Cp17d h]U<t/+4JM63$I*4?wUoW?u5' ЗױCиJGܐo8@rvnP!sx!wsT7gݿG<X TA[EY1a|TUMaj]S֓GٍĮiݶlv3KgKܝwt31 +HrdpI*7f?;ʢuc_u5߮+(~ qR~1|ѥxe5C y +M7-rxjg`$ + #[YΏ279Zcx} ע7'ݯqX^i||3SGߟᢷOpNhaPt +S73g^^2Rzq:! R71 aUvEC%@M# = +vjzIm;ĤP:f>gڪJ и[v˺4% +Ao?Yb כ"-xHv<{^[wwu{zjv3=qfct"f\J@ܸBmVD1B qzD }nխ[ȃG!CS,BN+Y1`vxN9ct; W_]|g;n;4>tF_SԶksqºɄnتhg9N{:g\P*)P!:# 1@Ď*3myxȼcCj灗}k^gUmKTcf/og1tpnO7M עq_i1PI=: {/Hl$Q8\5Z/ #{qٰc*.Qjo8| oi#"nJya$Ap8!! qË Oҿ}k%c}7R,qoF%;TfiN &/ϪMH$oT} $~*xXH5v/I86S[:5JET6`Μn0Sӄ;S94WfU!%[ :5PSĢY y!r wmhL]ݣ1.FO?>Z2ՆDU'g3 +'U,^OWMwo^ybI~9?ҫ|?5T/GѲ#ny }hS7+| qBV:Ts= ]" +?^wE#^ڌ?֪`ȌR3 7@] \ѹ$-q5Nt<ӑ/vV,p[W wkm0o&gA.)HvOjlÃ5gH~8ԓ_% )[N^ ?t 8M pz7k >jV:evp%,ʘU˲}dvT5b\M1=5" n< 8+8jNBCCg8h\:km!JAe>S:;] BNDR_~p[7mL2ۥ*ZI׊fs%@ +[}@5+gsm/WC0l1g$yޚc t(H6c8 SCꕤӤvfK!Y y#& [vAbnxaX7/f 8pgXҁ윒lI>lP]6_'t`p?1U"Xs14ݜ灭BƟxh\IK/l{FG9 +G _71M{uGO\sb*7MG4b$"ğo"XVٰB~˥O=GB^KmfijZ:T%B޵5Ǝ e#N͕au'RSPKpRٍl|hv5]zCmj0[ w ,ٔhX{xyDGggg$# sX+\aٜ*]W{l#$E&rFdc.k=;vv`w='n:^#H5$KY4~hZqE}R8k b4/xHujy]&dj8\@G>Rkɺc_tJ4S3/\Ѵ;|)SᖾJlkZm~ \գM>:Hַ4#noT&j n^& q#ybln2TrF eȎ=rSw++7.$(k"1rQ~U-¿ہj7x2̱ H`ZGGj*w̜93g朙׻vl1ر0ȀLA @ !H*$z"!^%Di"DC4{6Whbog^؜XڦefB)mo'#S.BzDx68T3O6 ̂AF~H(,p鿁R[][o +e,~O٭yy/2w~ע[&p嘿jb8ջk@F*6\,n0&{!mNz/ FP@/tkSÑwdFXsZ\:>ܛ6C {ֳDȲj^2@)f+k8D}c$b5Xg;~BOJ' ?\^.Yl+ۻ{yTOj +L NҔo8߈/fGOCJyt7qض m눼Өޗ)V8f9T"ZUe4(~o,X떐 Hк@3 +tA}4P6/R%MP4G@Mj+V-WHy0%}mY#e=s+(Py,Q/mR֌{+J;G12|ߨ,nFXb<)2{熭:;_YdB~#ޡh7Tͼ2yH §k鷠lbe1 /OG(2YYvgbY@T8¬ ,8FR_l-_Ug+*_8ݼ`/|~Yrm>56ƿlnWV}$H > +^ʼnߊE-ܦ[?F.t{d=_krkGNA&ic9IuG{uyϹC_ H;Bmj`p tKD!_r)cyi$ǁ Tc%!F r#B/ү0hyU¢Uloƥ6We}K>6EZ]cWܪկr;g[>wVywEI&h-j(e,!N.笥)SN;9l81-`^wBEC[ :VFNd(HX2,O:2xV\7lyLasD>ч&Xaިcpɹsgot#JJ;_$lOv݆1Y-S!-Xy`"HAĶXeA}EQ$hr0X,31NV8\ǯ-R(bK/6BP,y#$R@ؘK PQ%}SA$V¾<~ŘBWI +Ϣ] +XSV"6esvϋ{~ZbW9 +G]u#7~WЂ=`h׈B&GғNϏpM )0Ʉ_7 +$*7)kJTd\<٢zy4@7>Kv $s[Tw3DE(: lLapXGʝ<`T7.9:wU]U]3ޞ^{23c{(8F(Q }ea}[ԅD<ROj܋@gh#ɢvf; >|8?gC[x&ɝD.c܈ΞN굯pQl^K=(٢$[7,JtSo$/!^MV +bz3˜ۧ\`utJZ֤xI#Z{vˆz!Q)Hi%3Gh]pj Gp@|m_Epu9HԲ%=7'{VZI%o$:Vb,+Q%UH% v:Ymm:s㠧{d Ox.T5K:Lj m4>*Sy{ SX^(K7L`( O+kACևP3/`^nҾ͖=6x26y0W KlooCѶ5\;s" ѪzZV3U\Od%ǔѮJp o-Ϸq.|LA//J0x1$-I$Yճ]^-V,˙umf8׽]KgRF9w2+Hi&? <0TVILL3pP5' 5{EOy.G iJ2;H:?.TIfK"ˏFW<TJy B3d@q>'2׾B?ߏK_Ku:ttbK7>%%&>(!3>6%i,Rm- +Lt%O8k*Z)މU07g*ft#PN!1}ѝ^"RY%Vh˜e@|B_D bðB3H^$u ؎4Uj$}ijq=7dލ~#B#܋0}>[Kt +AL4f쩢t+ 6Hn " GDvBS!꟠e$!pUHPaW Ơ[,M%f2!|VKQnvReL\`IDzx\D=I(3u…p?e7n[qAۉ0;|7#HW]ձ*"~ܸ T@ڵF'mo?Y@~H`~.W=0Vy*`6V:uBjM-Mty51UW +ѫzZy= KF2La]2H +-ȑAʴwk VN${[p܏EZ"G@mwKI0ʋc =T'OƟ#E6 xiSl#&diӝ f>vAc`Bv3r6oԨ.Cl uJ!4wN p~5L>hi/5Cwqq]U~cgvf>xgv:8(rHbcĒG((A"  + !EʍYB. p _?fvmH˞̬vTq-h%ygt<> s=g z. "ݮVf25 bjy }"+?AыZuTqx͂>8nr\g#\YKZH\@hx>!jɟFJn+F +!n/,Lank1u3Hs&~A9hhE䈕--#}H"ǥ~l;LKΰn&!d68 Amfx:"=%$BGb^"4pij=sw]D' cycs>; +ÇS/dE⾻⻋4߽/֨-G{3)|U;BMuN5Nu ձfl\-./?3B@##=Bő, { +E\9!;Y6n|&qLW5s ɏ4];NDrCmRX1˴RwK8Th$4AYN}q>Nhm9*|e_ m-%gN8>Fp(vBg#hlYB7$z6 "(=زoP5XAx;#ygpއйMcx񵺆cK4*ҩ=܇ّS-+o¯Y:WZn*oe&}vJHTB4ĶT(Zhxyi\te3KL.p/Eeh] Ӷh?wd?+%8=`-Bǫ09'yr(MW^'7g5u.Q[o5gzvvגk&Ʋqxx޸ 7fۢCJA9hrLnGX_,[^[ &xrے蒕&"p,I(H vl|)Ap(key;Y5MBS)*dw,S|``>4y@M57oAL6^f;pWz!سƍ{X4 ՀHj{;6A8QÁ *P7rc6gW@dSp- Iխ)x_/˩#yi7B QCT[REq"^SG &ݼuK[QnJdW{كK o3IawE3$6:߷2Ģp/>b"NdxݻǟȬhrw1 U7)0E0lj'xqxOj,T)|<(ZCj]/s0̧qnL#KONnX"2pݧ^c-w>Ϗ{N[bm3>)T@4W2_;@MkAadn=rGă{AJZO VkB&$/?nOWvɃZ/U#Uի^Umfdz[cEIpb{fXE pD"$"BXvCD +pr)#gϡGz5S Ԑ+R1MޮLiNa{c +2m9޺B[vK `-MD5^]~B*8:)+[-\Ƿ8)_JMkSxH=E{1"KV"ʻ;py-fLI6qh=] F/_ +?pLgp,^|3rT$T7Ft9 \V "6H˱ 3I}sNXMC)$֙lEf"T9N@ +Hq穁 ܿ^)7 fY*]w]QQTwF4n=[8tc?L +O +w$ 7$E335$Qi<4LQ"W,H.@l-q<b%GyM_slqr~A.\!5,d)ǘQ峌^aYGK;qD0 'e#-,vX҆7B>VYB'S^nwXC(~˔U?g z&2$6*f&K&f"Wʪ[pй6+Э}NͯFqڬQbb o*Bt%5_\g1|&{X*1}{w)^05l œqj/Cp N3Qe\y1c1e0f{WG )VஉC( (ځ8Fb`-? FtsEG +[FuH7HZvYh'G2!G5#Jv. h̤DR;lI Y+z + Jހj} gAZRCHU}a8t|O %/L'~9נ6dB. +7>Ďg֕ߦ Z?7~T!=~P^BkTzWB˄p}9R6۪*E* + kiM適}(' UO9aݓy,Ұ 0g{Z).l_y£7&ɪaۋr(Q4zu% N!R殻:BK[q?r^s#GaMksQTtiC"9ȧDŽs>`ج֛d +P15KPoѷ] Xx1▒&̎&+GcF]N&/Om{ٿ.C&ŚwGM/}^ݜ͖f b*W cV=4G/`f<^N 7nmS{07XS.Zs%KרF`;dh^q vԘait6i1Eɜߑs #vJb\ mGJm*ɽNO8 +)J*MmWhLWS^δ&;RK@zve[dc.Z<ՊmZ~I5oX m?i6VHl0 +Gr8AɅ:Ov/%|aI{Nd(M$њYvU U O¶<) vO(Xx6TnHŶ*CdEHJF(J*V5vK^Jw$0]稜Y˪6! SL{Kb?.0+ƃ"-EgդAƍrJF4Xq+'+o])/j/(74ȓ`UgkSO RuMk|(nG"5k5sYM)reb1Vʝq\pp]k[JE8y``"JoGs++_,k:g\X[o%Rִ(`hƴ- +v Anjڕ:޲\ԴASgJ_uq̂HcNrS}Dp)vj#w" dž3z$/s)qm_z2^Ql +ƃfŇi݅V% bwy'uAAUrN1>ws--UV6}ee*]:7sNT$@EO϶K2D!'\ XXO7reK,8xpe5]aj'QƝw y#߳Bϫ &)i8۠ x GFLeZ(  WZ:2X%H Şrt2U\N8gts.lr%fp;%b .M<Pj4B]4`C /n-H& _%tDB//L"?IRWE-SVei05}2sngjnd}+g]؞wcۭ]ņa8?]ؑa^3l8=֡NպToaMEDXn;x+ T߮ +b >nۓˣv2 C`V J0͒ U0P6HzN'>AQb폅FȠjB55LvC?2!0,֜rTlj&(GҦ(T (= ᢬^ԴVE /"B3\W_JkYsojk+]$ eiBإ%QeY-xއV2cУw<ZOXP68͎*XnKxlDT5  ^J7q-ZW@uK'Tgh`v=2l[WZ3aa[D"G//c0k֠{|$`)w})bzy?eT)J)F+^Ȋǭ;_]xlnhBC72]_2jD:N[º\HH 8RA6kHUsjæOG;uYڳ_)'ۼD|cq0`+6 +|5& W|Xub!$/8umK-rϏׂc'sor[,/X^}}N{IF%_qEd>Cy&P 3^U *] +}Vx@>D0#[ٴޣ׭̔`1 RY \S`L%nl?;?KH6 --E%jR[XgHN)^JO +ItFlXd'U`6[fâ\U;ݝQ:lWiuթ1#鑉k O&j<JޟLoC\nh\J-[+߾JܳBa F$qj}TuZǕdXJ7V]\3pe<68V e uaMZU򣟄Z$QcRg<[|SIܒQz.TlLM fNXÔ4,F u`Å\7(h@<O(<\Tov/^3^CGA*Eቨm$K%C&&k,p-9,2=ixfu"w6&J!J `b>[e-r(=䳙唱yɧS1~߀G^rBZ`L6P1{$v=B/-0B oNyTܠlJV5-N`c'RՒ`6fιAY+5K/kɭE O԰6{ ]l#$^ŭ|uwoBc3q4=ƿ)}L$O=:. !Ckh#e_YasAO}b0MyuAzVD G*6I>rX3^eu\e|朙sΜsf_^/I:q؉DU%C+QBB%,ZWxADP$$^7gYtZ̲ŕ%={Dro{p=%0{/8gZ[ꃿ厚;b]6Blj]:ҰmBc.uV| CG|,j%$ֳBBboݯoCFϤ_`#/+hWNǁ_]!h*+Oc {ۻ@Tޯ(_#'Dnв|nYqu-54<\)~V̔1EḒ߿A\̀,K=l|#bOX06}b_G}\MRƤi,Ma{]lQ:/'Tzz vK@7h0v2MuJǒ%qI(px? 5v$ɛa{.mU 1O-QzRx e D꿼p_3,mĈUӇezl{Zզq3:E"K}kwu`6]`Թgw"LP㎽:WO6-Ҝ*?z>Ka~0#">PI! >9W5?זTԖ+ctz Y>)Ðw(9+$ÆG-d~>tfNP4IثC,IsU]\t]XD)/b,8~sPsF%1^BP/ Ȼƿ}fPDc# T:ϋa:H| !]E&8Áaӷas0G!. ]6)Ud>{nqpޜ9,Yw}(9`U\mUCP]6T\!>bn3A׵;mМ;WGN+|ت$!bOƣt~ D0a@ZuUnu4ْȠU0ΤUK2ZуW7eiB"0 :D6'!eH =LC U˪FHF 3膚Mv 3ٲA]45~lͅ~XQƓSOmU?/,x`ӽd|ozɑzwbK)5Pי%7nlarIDwr[QI<"h4Lx 1]1O_Ѳ1j~.EmOXh!*2;Ֆ5kGӈ `'0gg nw +A[(m۾462ሆ?8k4(~Q[͟tZ0Ȏ3,aB+pi>*ק+}I[d0OC 0WtU`I}>w\ +܇/W" V@] *KQ.)O&@Uk/5i Np+ΚL eN1ShmD,"yX͠$+)(˷a"v/ڿ\Xvm jQ6^ܳ\M&1\e9&cCK8̒%KQ+V+uf-g`C=e`i;qvd&t)>܋&-yӌ 7>DWU.`E.'r@>#:TW>Đ&C=\Pټ_ |e7״]d@:+HaP4i7ef~p&ZzikkOr+1;pmF~ț=Z]]ZVdsXMȪv]vjA.Xڡd|I.:Rkgdpyy;!i^ƽVQ)w+[Dv: + +r˶Ks+osDf9'NQ;sP.$/D+у{z$I3O߱% ⌅#b[[Alq eSf"1|<j@Ն7WHk\QS`3S^d88RpQ V]4qppp?<ò2]s|`͈vzԳ=th!E䀮ֶ!LUzI1&GM(-nQU5x=Ya +LJJ,Q;3L.m'u(Y3Ȳ'..7cEǎ $v 5F /-l,c1pqP7WгeO5Msp'1^pd"ܤ)MGt`@c N6S8b/u7hV3_P`?'2e Nm1Wx,c:# Y̮_7xXig9cd9O`nZlx*Բ' rf̾qࠥmj/S22|],GQ&-nlfE,f6 uq" 3™LWzًePƱ6 3Xpes?&QC$E~xaH7r@R(*O%UČED fж9=E]Xxg Ekփ}yK|ȟ:X#'(z@5PxQ(ZLhvCogp XA]S&s:4$q۬[4$o[vy/WeRUH +|;V{90[S Lz +vc 2(}}\+ G7MM l^"2z\NԝZ3*~LĜ2NU iOi2XV7Yh=tD OxҤ5`svöՍ4p,8dX5qͲrScs1ywk+B&_B=F4|9JA(TdœMo"Im7RH"Qahm 'kfvūۮfo`|pTLw#cأ)d1N)?$rD}F(خP2i#^4\JeZY&E\e.+(+?IA$W#Gn:=?;[ƾij!kީ2&j]l7߁l|&& ȣ$o,LO96CkVJE$E|/ &D:A#o4FsU@ +NTx1qvcZ<ǮNkZztEuk}#x@aNJs#Ƭ!G`3(wB"/g"j S$&n+@R`7ry$oqZʫ\sPS%pu*w` 5e^V +wOy6)ϬV{m"`pzTdǵy#ZdzvR|Cm-:P!7(,&@)BU@ tXys&E8xvDD@A^T;k-c2Ybdj)"4TIpo'yΤV^'sLcf&=a+q$"^q"ߊxӕ F#VQF/ +z?u멢IZ}ΠEh/mFN~}8*5n;}q5.Nu`LOI~zvkԈ{R?O~8)[dGZ+KKny(v2^mq$es3gxر7Np6͎eIv#*1nvxE`7~Hxe ۾Wcsiœg_>{"=?[`t.r۔A!Z +s׬ߵ5m x: fp-[K>D'&j@#ui,nw=,k5r] +,fr6腦LM:nm:* Kpct]ZfP"ð\-M0A9K a ڲ)G'dkژ4o,lp~ @87UEBl40ST?#XoRSrH[>/?[8Hob^fL(>쐴=EݕjB +|$mNR9uztpzm pPʐDQm7,+$6[<J\Jhvdi9}niuax/7 {0v VY>p!! ibqlox2"2dM +Xr[RA2hi4#"ۘ\%J ]4XfG$&+jR9NHK1fX3q\17*xqc۷C`?pA\z^ߗqDOˁ=v򛃸3l`ngWP- NIb+Y!)K Yl4ã?Um{Jb+MDc +3ńF:Ut ܌k`d&̘xU^^؁~ ;S4 +K2⽎ 1繁ʼn- }_皋1hՃP|n._E'*^.ߦb;&{rv@8W@Lӣ[!ԍ%!Wԧ + *]s 43'cd濣Ǽf'>v߁uxY;Q_v=pE>|Ts?! SKϒ z1وzt yI_ࢨ ų &+ +d4l;uT4%$6*Jc_+~Ĥڍ\90w5s;cyPg.a EV 6}'x܇[VAJ.*RG{YNF>ZBSߦ 9X$pZ_+&@yD4X#bVgް7vEE~*aNX>P>}C}jҀN@N<%`* S.`4BšWoqNl;bJc8%.QOhp愩}&a;nq]_> 2!b`z1;̰^2Sڦv& tN͍-mot{)Img5)/r1 E43b_KQ0 QwTG1N35f5".6llz9 9'IOý5OTvvFJZzKSv&9IiN+=N> "1XEKg_!A΃;f! 1JO9)틁F5g1;;ȏߨeZFu1˖'/*E~4XP)ru4r'mv2 +Zw5iq]UٖД:vwnzKBYYpjaڥ"/5w +B;:yN[Nh*{L)$%9K;h ;~k~{D73 +ё$A0"}VR ۹@}p@GOKnc%&/+Ck_saN~$s.fJ{Yx'ǒ,-ݐ`m&Ua2t0ž8KKd**}fk)!*Y&t<,zԳׯN|Ǘ ZU\ϒ&4ߋ9!]{=}z諻onݏcS.>avxk.>6x8>edz8q +ѕ>)د(<+!gDD+)"*!DdhfqDDfJDqyfgDdqfWggvyFVf;=YB+OO%owAdG5̞!T{&b\*T)H#ZɞC͘Jyajfn^dpW[*@u/&k /57İPc]?]WkPMZ m!{ AbSNEՌyD ڦDĵ H9[Ih?oe\͌2{4(gA2t03#Ob[F:=(d)H$O=8&N~?B8@Y,q`ѣ>9'd`vs_ 0b/sȾJ@4)/Vo,LP vS׺f˷8ANg؆f} aÅ4*,7j;Uo?!Q +s٘"_rMaPu%n ves{4iiӆnJx\"0Y>puT7b1]dpR;qnP.ΉRr8 ȼw;/]\>-?vfDӻ@'>f- weK \`UrK* ȷR /Ȁi.fJ+89]Eh[w0a:\8Oפ+WD&6 l7g}8 &? Ts0S d*[L;Y:%[G ysP\q4҄]+i)>_d j84 #)Z" %9\%:YS+?2%5@ǔay,qȐ*?7 a@F8pk %EzAV Ri* DZ!Zbp]TS(ݾ6DWAʒب/}@jmor,[F{)I7ùy(1Hp0@PTɨ5XSM7)#{$jawBcg=E9]{*$4l|N)NEOS9L<MU^z|UQ=iyD0%{!޺Zw;XzloK;K}88 p0yu9%~}{=K&wo +Ӝ ՛@*lVzoqmtnߎq@v*{ρ6Pvzj? +_m%tz<}Fh. 짷pM<_ +ח./# ?_(}gall8Nb!ou6wb7zR4uppD?+H)- ~)-T( }~XN`Kҝ$ab0?-#) +մ;B?Քt*?;k0έjZti ô-̦Wi y͈V l3s:.sQ+aNsXG0dӻe#Ognv9UpuWXRH:U ]"pw ^,uÄfFuc8 +TR 7j}P|XSF5 p(˭̯m%^1MҊ_B(ݝzDw]01$ctcd#7ŕRH$q,5[v1v8VVh"[5&6at2J[[,(YV@L"~m6`YSmlMq@"P0O`2l:Zó ʑAS,b}ŽɍG] )ѡʬsnhb1qwX/DmF" =s1Nx*Qе U߿W?[t _ ԖofI +endstream +endobj + +803 0 obj +<> +endobj + +804 0 obj +<>/DW 1000/Type/Font>> +endobj + +806 0 obj +</Name/Comment/AP<>/T(Administrator)/Contents>> +endobj + +807 0 obj +<>>>>>/Subtype/Form/Length 397>> +stream +q 0.5 0.5 0.5 RG 1 1 0 rg 0.11 w /GS0 gs 1 2 m 1 2 1 1 2 1 c 2 1 l 16 1 l 16 1 17 1 17 2 c 17 2 l 17 14 l 17 14 17 15 16 15 c 16 15 l 2 15 l 2 15 1 15 1 14 c 1 14 l 1 2 l B h f 1 1 1 rg 0.11 w 4 5.2 m 4 5.2 4 4.5 4.8 4.5 c 4.8 4.5 l 8 4.5 l 9 3.2 l 10 4.5 l 13.3 4.5 l 13.3 4.5 14 4.5 14 5.2 c 14 5.2 l 14 11.3 l 14 11.3 14 12 13.3 12 c 13.3 12 l 4.8 12 l 4.8 12 4 12 4 11.3 c 4 11.3 l 4 5.2 l b Qendstream +endobj + +xref +0 808 +0000000786 65536 f +0000000017 00000 n +0000000256 00000 n +0000000813 00000 n +0000000947 00000 n +0000001082 00000 n +0000001217 00000 n +0000001352 00000 n +0000001487 00000 n +0000001622 00000 n +0000001757 00000 n +0000001893 00000 n +0000002033 00000 n +0000002169 00000 n +0000002309 00000 n +0000002445 00000 n +0000002581 00000 n +0000002717 00000 n +0000002856 00000 n +0000002992 00000 n +0000003131 00000 n +0000003267 00000 n +0000003407 00000 n +0000003544 00000 n +0000003685 00000 n +0000003822 00000 n +0000003959 00000 n +0000004096 00000 n +0000004237 00000 n +0000004374 00000 n +0000004515 00000 n +0000004652 00000 n +0000004793 00000 n +0000004930 00000 n +0000005067 00000 n +0000005204 00000 n +0000005345 00000 n +0000005482 00000 n +0000005623 00000 n +0000005760 00000 n +0000005897 00000 n +0000006034 00000 n +0000006175 00000 n +0000006312 00000 n +0000006454 00000 n +0000006591 00000 n +0000006733 00000 n +0000006870 00000 n +0000007011 00000 n +0000007148 00000 n +0000007289 00000 n +0000007426 00000 n +0000007568 00000 n +0000007705 00000 n +0000007847 00000 n +0000007984 00000 n +0000008126 00000 n +0000008263 00000 n +0000008405 00000 n +0000008542 00000 n +0000008684 00000 n +0000008821 00000 n +0000008963 00000 n +0000009100 00000 n +0000009242 00000 n +0000009380 00000 n +0000009517 00000 n +0000009655 00000 n +0000009797 00000 n +0000009935 00000 n +0000010077 00000 n +0000010215 00000 n +0000010356 00000 n +0000010494 00000 n +0000010636 00000 n +0000010774 00000 n +0000010915 00000 n +0000011050 00000 n +0000011192 00000 n +0000011327 00000 n +0000011468 00000 n +0000011606 00000 n +0000013124 00000 n +0000013179 00000 n +0000013234 00000 n +0000013289 00000 n +0000013344 00000 n +0000013399 00000 n +0000013454 00000 n +0000013509 00000 n +0000013564 00000 n +0000013619 00000 n +0000013674 00000 n +0000013729 00000 n +0000013784 00000 n +0000013839 00000 n +0000013894 00000 n +0000013949 00000 n +0000014004 00000 n +0000014059 00000 n +0000014114 00000 n +0000014170 00000 n +0000014226 00000 n +0000014282 00000 n +0000014338 00000 n +0000014394 00000 n +0000014450 00000 n +0000014506 00000 n +0000014562 00000 n +0000014618 00000 n +0000014674 00000 n +0000014730 00000 n +0000014786 00000 n +0000014842 00000 n +0000014898 00000 n +0000014954 00000 n +0000015010 00000 n +0000015066 00000 n +0000015122 00000 n +0000015178 00000 n +0000015234 00000 n +0000015290 00000 n +0000015346 00000 n +0000015402 00000 n +0000015458 00000 n +0000015514 00000 n +0000015570 00000 n +0000015626 00000 n +0000015682 00000 n +0000015738 00000 n +0000015794 00000 n +0000015850 00000 n +0000015906 00000 n +0000015962 00000 n +0000016018 00000 n +0000016074 00000 n +0000016130 00000 n +0000016186 00000 n +0000016242 00000 n +0000016298 00000 n +0000016354 00000 n +0000016410 00000 n +0000016466 00000 n +0000016522 00000 n +0000016578 00000 n +0000016634 00000 n +0000016690 00000 n +0000016746 00000 n +0000016802 00000 n +0000016858 00000 n +0000016914 00000 n +0000016970 00000 n +0000017026 00000 n +0000017082 00000 n +0000017138 00000 n +0000017194 00000 n +0000017250 00000 n +0000017306 00000 n +0000017362 00000 n +0000017418 00000 n +0000017474 00000 n +0000017705 00000 n +0000018461 00000 n +0000018603 00000 n +0000018742 00000 n +0000018885 00000 n +0000019024 00000 n +0000019167 00000 n +0000019306 00000 n +0000019449 00000 n +0000019588 00000 n +0000019731 00000 n +0000019870 00000 n +0000020013 00000 n +0000020152 00000 n +0000020295 00000 n +0000020434 00000 n +0000020577 00000 n +0000020716 00000 n +0000020859 00000 n +0000020998 00000 n +0000021141 00000 n +0000021280 00000 n +0000021423 00000 n +0000021562 00000 n +0000021705 00000 n +0000021844 00000 n +0000021987 00000 n +0000022126 00000 n +0000022269 00000 n +0000022408 00000 n +0000022551 00000 n +0000022690 00000 n +0000022833 00000 n +0000022972 00000 n +0000023115 00000 n +0000023254 00000 n +0000023397 00000 n +0000023536 00000 n +0000023679 00000 n +0000023818 00000 n +0000023961 00000 n +0000024100 00000 n +0000024243 00000 n +0000024382 00000 n +0000024525 00000 n +0000024664 00000 n +0000024807 00000 n +0000024946 00000 n +0000025089 00000 n +0000025228 00000 n +0000025371 00000 n +0000025510 00000 n +0000025653 00000 n +0000025792 00000 n +0000025935 00000 n +0000026074 00000 n +0000026217 00000 n +0000026356 00000 n +0000026499 00000 n +0000026638 00000 n +0000026781 00000 n +0000026920 00000 n +0000027063 00000 n +0000027202 00000 n +0000027345 00000 n +0000027484 00000 n +0000027627 00000 n +0000027766 00000 n +0000027909 00000 n +0000028048 00000 n +0000028191 00000 n +0000028330 00000 n +0000028473 00000 n +0000028612 00000 n +0000028755 00000 n +0000028894 00000 n +0000029037 00000 n +0000029176 00000 n +0000029319 00000 n +0000029458 00000 n +0000029601 00000 n +0000029740 00000 n +0000029883 00000 n +0000030022 00000 n +0000030165 00000 n +0000030304 00000 n +0000030447 00000 n +0000030586 00000 n +0000030729 00000 n +0000030868 00000 n +0000031014 00000 n +0000031156 00000 n +0000031299 00000 n +0000031438 00000 n +0000033076 00000 n +0000033132 00000 n +0000033188 00000 n +0000033244 00000 n +0000033300 00000 n +0000033356 00000 n +0000033412 00000 n +0000033468 00000 n +0000033524 00000 n +0000033580 00000 n +0000033636 00000 n +0000033692 00000 n +0000033748 00000 n +0000033804 00000 n +0000033860 00000 n +0000033916 00000 n +0000033972 00000 n +0000034028 00000 n +0000034084 00000 n +0000034140 00000 n +0000034196 00000 n +0000034252 00000 n +0000034308 00000 n +0000034364 00000 n +0000034420 00000 n +0000034476 00000 n +0000034532 00000 n +0000034588 00000 n +0000034644 00000 n +0000034700 00000 n +0000034756 00000 n +0000034812 00000 n +0000034868 00000 n +0000034924 00000 n +0000034980 00000 n +0000035036 00000 n +0000035092 00000 n +0000035148 00000 n +0000035204 00000 n +0000035260 00000 n +0000035316 00000 n +0000035372 00000 n +0000035428 00000 n +0000035484 00000 n +0000035540 00000 n +0000035596 00000 n +0000035652 00000 n +0000035708 00000 n +0000035764 00000 n +0000035820 00000 n +0000035876 00000 n +0000035932 00000 n +0000035988 00000 n +0000036044 00000 n +0000036100 00000 n +0000036156 00000 n +0000036212 00000 n +0000036268 00000 n +0000036324 00000 n +0000036380 00000 n +0000036436 00000 n +0000036492 00000 n +0000036548 00000 n +0000036604 00000 n +0000036660 00000 n +0000036716 00000 n +0000036772 00000 n +0000036828 00000 n +0000036884 00000 n +0000036940 00000 n +0000036996 00000 n +0000037052 00000 n +0000037108 00000 n +0000037164 00000 n +0000037220 00000 n +0000037276 00000 n +0000037332 00000 n +0000037388 00000 n +0000037444 00000 n +0000037500 00000 n +0000037556 00000 n +0000037612 00000 n +0000037668 00000 n +0000037724 00000 n +0000037780 00000 n +0000037836 00000 n +0000037892 00000 n +0000037948 00000 n +0000038004 00000 n +0000038060 00000 n +0000038116 00000 n +0000038172 00000 n +0000038228 00000 n +0000038459 00000 n +0000038767 00000 n +0000038910 00000 n +0000039049 00000 n +0000039192 00000 n +0000039331 00000 n +0000039474 00000 n +0000039613 00000 n +0000039756 00000 n +0000039895 00000 n +0000040038 00000 n +0000040177 00000 n +0000040320 00000 n +0000040459 00000 n +0000040602 00000 n +0000040741 00000 n +0000040884 00000 n +0000041023 00000 n +0000041166 00000 n +0000041305 00000 n +0000041448 00000 n +0000041587 00000 n +0000041729 00000 n +0000041868 00000 n +0000042010 00000 n +0000042149 00000 n +0000042286 00000 n +0000042425 00000 n +0000042568 00000 n +0000042707 00000 n +0000042850 00000 n +0000042989 00000 n +0000043132 00000 n +0000043271 00000 n +0000043414 00000 n +0000043553 00000 n +0000043690 00000 n +0000043829 00000 n +0000044805 00000 n +0000044861 00000 n +0000044917 00000 n +0000044973 00000 n +0000045029 00000 n +0000045085 00000 n +0000045141 00000 n +0000045197 00000 n +0000045253 00000 n +0000045309 00000 n +0000045365 00000 n +0000045421 00000 n +0000045477 00000 n +0000045533 00000 n +0000045589 00000 n +0000045645 00000 n +0000045701 00000 n +0000045757 00000 n +0000045813 00000 n +0000045869 00000 n +0000045925 00000 n +0000045981 00000 n +0000046037 00000 n +0000046093 00000 n +0000046149 00000 n +0000046205 00000 n +0000046261 00000 n +0000046317 00000 n +0000046373 00000 n +0000046429 00000 n +0000046485 00000 n +0000046541 00000 n +0000046597 00000 n +0000046653 00000 n +0000046709 00000 n +0000046765 00000 n +0000046821 00000 n +0000047063 00000 n +0000048940 00000 n +0000067998 00000 n +0000068308 00000 n +0000068495 00000 n +0000068780 00000 n +0000069009 00000 n +0000070299 00000 n +0000070540 00000 n +0000072209 00000 n +0000072480 00000 n +0000072508 00000 n +0000072645 00000 n +0000074858 00000 n +0000074914 00000 n +0000075185 00000 n +0000075213 00000 n +0000075350 00000 n +0000078083 00000 n +0000078139 00000 n +0000078410 00000 n +0000078438 00000 n +0000078574 00000 n +0000080682 00000 n +0000080738 00000 n +0000080967 00000 n +0000082961 00000 n +0000083190 00000 n +0000084527 00000 n +0000084756 00000 n +0000086513 00000 n +0000086742 00000 n +0000088184 00000 n +0000088428 00000 n +0000088472 00000 n +0000088608 00000 n +0000088745 00000 n +0000088879 00000 n +0000090918 00000 n +0000090974 00000 n +0000091030 00000 n +0000091086 00000 n +0000091330 00000 n +0000091366 00000 n +0000091501 00000 n +0000091635 00000 n +0000094779 00000 n +0000094835 00000 n +0000094891 00000 n +0000095135 00000 n +0000095187 00000 n +0000095321 00000 n +0000095458 00000 n +0000095595 00000 n +0000095732 00000 n +0000098154 00000 n +0000098210 00000 n +0000098266 00000 n +0000098322 00000 n +0000098378 00000 n +0000098607 00000 n +0000101213 00000 n +0000101442 00000 n +0000104080 00000 n +0000104324 00000 n +0000104360 00000 n +0000104498 00000 n +0000104636 00000 n +0000107157 00000 n +0000107213 00000 n +0000107269 00000 n +0000107498 00000 n +0000109487 00000 n +0000109716 00000 n +0000112213 00000 n +0000112457 00000 n +0000112501 00000 n +0000112641 00000 n +0000112779 00000 n +0000112913 00000 n +0000115262 00000 n +0000115318 00000 n +0000115374 00000 n +0000115430 00000 n +0000115674 00000 n +0000115718 00000 n +0000115856 00000 n +0000115994 00000 n +0000116132 00000 n +0000118844 00000 n +0000118900 00000 n +0000118956 00000 n +0000119012 00000 n +0000119256 00000 n +0000119284 00000 n +0000119422 00000 n +0000122208 00000 n +0000122264 00000 n +0000122508 00000 n +0000122544 00000 n +0000122681 00000 n +0000122812 00000 n +0000125556 00000 n +0000125612 00000 n +0000125668 00000 n +0000125912 00000 n +0000125956 00000 n +0000126093 00000 n +0000126230 00000 n +0000126367 00000 n +0000128985 00000 n +0000129041 00000 n +0000129097 00000 n +0000129153 00000 n +0000129382 00000 n +0000131227 00000 n +0000131471 00000 n +0000131507 00000 n +0000131645 00000 n +0000131783 00000 n +0000133761 00000 n +0000133817 00000 n +0000133873 00000 n +0000134117 00000 n +0000134177 00000 n +0000134315 00000 n +0000134453 00000 n +0000134591 00000 n +0000134729 00000 n +0000134867 00000 n +0000137892 00000 n +0000137948 00000 n +0000138004 00000 n +0000138060 00000 n +0000138116 00000 n +0000138172 00000 n +0000138413 00000 n +0000140218 00000 n +0000140462 00000 n +0000140514 00000 n +0000140648 00000 n +0000140780 00000 n +0000140915 00000 n +0000141052 00000 n +0000143324 00000 n +0000143380 00000 n +0000143436 00000 n +0000143492 00000 n +0000143548 00000 n +0000143792 00000 n +0000143836 00000 n +0000143966 00000 n +0000144105 00000 n +0000144242 00000 n +0000146302 00000 n +0000146358 00000 n +0000146414 00000 n +0000146470 00000 n +0000146714 00000 n +0000146774 00000 n +0000146916 00000 n +0000147054 00000 n +0000147186 00000 n +0000147324 00000 n +0000147461 00000 n +0000149938 00000 n +0000149994 00000 n +0000150050 00000 n +0000150106 00000 n +0000150162 00000 n +0000150218 00000 n +0000150462 00000 n +0000150506 00000 n +0000150645 00000 n +0000150783 00000 n +0000150921 00000 n +0000153231 00000 n +0000153287 00000 n +0000153343 00000 n +0000153399 00000 n +0000153655 00000 n +0000153707 00000 n +0000153841 00000 n +0000153978 00000 n +0000154113 00000 n +0000154250 00000 n +0000156506 00000 n +0000156562 00000 n +0000156618 00000 n +0000156674 00000 n +0000156730 00000 n +0000156974 00000 n +0000157026 00000 n +0000157164 00000 n +0000157299 00000 n +0000157437 00000 n +0000157568 00000 n +0000160317 00000 n +0000160373 00000 n +0000160429 00000 n +0000160485 00000 n +0000160541 00000 n +0000160785 00000 n +0000160829 00000 n +0000160965 00000 n +0000161102 00000 n +0000161239 00000 n +0000164028 00000 n +0000164084 00000 n +0000164140 00000 n +0000164196 00000 n +0000164440 00000 n +0000164492 00000 n +0000164623 00000 n +0000164760 00000 n +0000164901 00000 n +0000165038 00000 n +0000167634 00000 n +0000167690 00000 n +0000167746 00000 n +0000167802 00000 n +0000167858 00000 n +0000168102 00000 n +0000168154 00000 n +0000168282 00000 n +0000168419 00000 n +0000168556 00000 n +0000168693 00000 n +0000171846 00000 n +0000171902 00000 n +0000171958 00000 n +0000172014 00000 n +0000172070 00000 n +0000172314 00000 n +0000172366 00000 n +0000172502 00000 n +0000172639 00000 n +0000172776 00000 n +0000172914 00000 n +0000175498 00000 n +0000175554 00000 n +0000175610 00000 n +0000175666 00000 n +0000175722 00000 n +0000175966 00000 n +0000176002 00000 n +0000176139 00000 n +0000176274 00000 n +0000178950 00000 n +0000179006 00000 n +0000179062 00000 n +0000179306 00000 n +0000179350 00000 n +0000179481 00000 n +0000179619 00000 n +0000179749 00000 n +0000182059 00000 n +0000182115 00000 n +0000182171 00000 n +0000182227 00000 n +0000182471 00000 n +0000182507 00000 n +0000182637 00000 n +0000182769 00000 n +0000185260 00000 n +0000185316 00000 n +0000185372 00000 n +0000185616 00000 n +0000185676 00000 n +0000185814 00000 n +0000185952 00000 n +0000186090 00000 n +0000186228 00000 n +0000188816 00000 n +0000188872 00000 n +0000188928 00000 n +0000188984 00000 n +0000189040 00000 n +0000189284 00000 n +0000189328 00000 n +0000189462 00000 n +0000189603 00000 n +0000189739 00000 n +0000193118 00000 n +0000193174 00000 n +0000193230 00000 n +0000193286 00000 n +0000193557 00000 n +0000193593 00000 n +0000193729 00000 n +0000193866 00000 n +0000197029 00000 n +0000197085 00000 n +0000197141 00000 n +0000197412 00000 n +0000197464 00000 n +0000197600 00000 n +0000197737 00000 n +0000197874 00000 n +0000198009 00000 n +0000201354 00000 n +0000201410 00000 n +0000201466 00000 n +0000201522 00000 n +0000201578 00000 n +0000201834 00000 n +0000201886 00000 n +0000202014 00000 n +0000202148 00000 n +0000202278 00000 n +0000202416 00000 n +0000205270 00000 n +0000205326 00000 n +0000205382 00000 n +0000205438 00000 n +0000205494 00000 n +0000205750 00000 n +0000205794 00000 n +0000205932 00000 n +0000206063 00000 n +0000206200 00000 n +0000208638 00000 n +0000208694 00000 n +0000208750 00000 n +0000208806 00000 n +0000209050 00000 n +0000209078 00000 n +0000209212 00000 n +0000210146 00000 n +0000210202 00000 n +0000210443 00000 n +0000212487 00000 n +0000212728 00000 n +0000214662 00000 n +0000214903 00000 n +0000216695 00000 n +0000216924 00000 n +0000219151 00000 n +0000219380 00000 n +0000221592 00000 n +0000221821 00000 n +0000224309 00000 n +0000224538 00000 n +0000226213 00000 n +0000226442 00000 n +0000229088 00000 n +0000229344 00000 n +0000230993 00000 n +0000231129 00000 n +0000231353 00000 n +0000231810 00000 n +0000234480 00000 n +0000234518 00000 n +0000234557 00000 n +0000234584 00000 n +0000234681 00000 n +0000234823 00000 n +0000234967 00000 n +0000235111 00000 n +0000235255 00000 n +0000235399 00000 n +0000235543 00000 n +0000239204 00000 n +0000000805 00001 f +0000239402 00000 n +0000239509 00000 n +0000239750 00000 n +0000240223 00000 n +0000240356 00000 n +0000240601 00000 n +0000244335 00000 n +0000244413 00000 n +0000245152 00000 n +0000245285 00000 n +0000247055 00000 n +0000247222 00000 n +0000247473 00000 n +0000306439 00000 n +0000306678 00000 n +0000306955 00000 n +0000429040 00000 n +0000429279 00000 n +0000000000 00001 f +0000429529 00000 n +0000429780 00000 n + +trailer +<<8D25E97DD6500C49AB42D1A74EB2F56B>]>> + +startxref +430351 +%%EOF diff --git a/src/JT808.Protocol.Benchmark/JT808.Protocol.Benchmark.csproj b/src/JT808.Protocol.Benchmark/JT808.Protocol.Benchmark.csproj new file mode 100644 index 0000000..bfd5d32 --- /dev/null +++ b/src/JT808.Protocol.Benchmark/JT808.Protocol.Benchmark.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp2.2;net472 + true + AnyCPU + Exe + + + + + + + + + + + + + + + + + + + diff --git a/src/JT808.Protocol.Benchmark/JT808SerializerContext.cs b/src/JT808.Protocol.Benchmark/JT808SerializerContext.cs new file mode 100644 index 0000000..c958193 --- /dev/null +++ b/src/JT808.Protocol.Benchmark/JT808SerializerContext.cs @@ -0,0 +1,171 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.CsProj; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.Benchmark +{ + [Config(typeof(JT808SerializerConfig))] + [MarkdownExporterAttribute.GitHub] + [MemoryDiagnoser] + [CategoriesColumn] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + public class JT808SerializerContext + { + private byte[] bytes0x0200; + private byte[] bytes0x0100; + + [Params(100, 10000, 100000)] + public int N; + + private ushort MsgId0x0200; + private ushort MsgId0x0100; + JT808Serializer JT808Serializer; + [GlobalSetup] + public void Setup() + { + JT808Serializer = new JT808Serializer(); + bytes0x0200 = "7E0200005C11223344556622B8000000010000000200BA7F0E07E4F11C0028003C00001807151010100104000000640202003703020038040200011105010000000112060100000001011307000000020022012504000000172A0200F42B04000000F2300102310105167E".ToHexBytes(); + MsgId0x0200 = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(); + MsgId0x0100 = Enums.JT808MsgId.终端注册.ToUInt16Value(); + bytes0x0100 = "7E 01 00 00 2D 00 01 23 45 67 89 00 0A 00 28 00 32 31 32 33 34 30 73 6D 61 6C 6C 63 68 69 31 32 33 30 30 30 30 30 30 30 30 30 43 48 49 31 32 33 30 01 D4 C1 41 31 32 33 34 35 BA 7E".ToHexBytes(); + } + + [Benchmark(Description = "0x0200_All_AttachId_Serialize"), BenchmarkCategory("0x0200Serializer")] + public void TestJT808_0x0200_All_AttachId_Serialize() + { + for (int i = 0; i < N; i++) + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = MsgId0x0200, + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + }; + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200(); + jT808UploadLocationRequest.AlarmFlag = 1; + jT808UploadLocationRequest.Altitude = 40; + jT808UploadLocationRequest.GPSTime = DateTime.Parse("2018-07-15 10:10:10"); + jT808UploadLocationRequest.Lat = 12222222; + jT808UploadLocationRequest.Lng = 132444444; + jT808UploadLocationRequest.Speed = 60; + jT808UploadLocationRequest.Direction = 0; + jT808UploadLocationRequest.StatusFlag = 2; + jT808UploadLocationRequest.JT808LocationAttachData = new Dictionary(); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x03, new JT808_0x0200_0x03 + { + Speed=56 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x04, new JT808_0x0200_0x04 + { + EventId=1 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x11, new JT808_0x0200_0x11 + { + AreaId=1, + JT808PositionType= Enums.JT808PositionType.圆形区域 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x12, new JT808_0x0200_0x12 + { + AreaId = 1, + JT808PositionType = Enums.JT808PositionType.圆形区域, + Direction= Enums.JT808DirectionType.出 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x13, new JT808_0x0200_0x13 + { + DrivenRoute= Enums.JT808DrivenRouteType.过长, + DrivenRouteId=2, + Time=34 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x25, new JT808_0x0200_0x25 + { + CarSignalStatus=23 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x2A, new JT808_0x0200_0x2A + { + IOStatus=244 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x2B, new JT808_0x0200_0x2B + { + Analog = 242 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x30, new JT808_0x0200_0x30 + { + WiFiSignalStrength=0x02 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x31, new JT808_0x0200_0x31 + { + GNSSCount=0x05 + }); + jT808Package.Bodies = jT808UploadLocationRequest; + var result = JT808Serializer.Serialize(jT808Package); + } + } + + [Benchmark(Description = "0x0200_All_AttachId_Deserialize"), BenchmarkCategory("0x0200Serializer")] + public void TestJT808_0x0200_Deserialize() + { + for (int i = 0; i < N; i++) + { + var result = JT808Serializer.Deserialize(bytes0x0200); + } + } + + [Benchmark(Description = "0x0100Serialize"), BenchmarkCategory("0x0100Serializer")] + public void TestJT808_0x0100_Serialize() + { + for (int i = 0; i < N; i++) + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = MsgId0x0100, + MsgNum = (ushort)(i + 1), + TerminalPhoneNo = "112233445566", + }; + JT808_0x0100 jT808_0X0100 = new JT808_0x0100(); + jT808_0X0100.AreaID = 12345; + jT808_0X0100.CityOrCountyId = 23454; + jT808_0X0100.PlateColor = 0x02; + jT808_0X0100.PlateNo = "测A123456"; + jT808_0X0100.TerminalId = "1234567"; + jT808_0X0100.TerminalModel = "1234567890000"; + jT808_0X0100.MakerId = "12345"; + jT808Package.Bodies = jT808_0X0100; + var result = JT808Serializer.Serialize(jT808Package); + } + } + + [Benchmark(Description = "0x0100Deserialize"), BenchmarkCategory("0x0100Serializer")] + public void TestJT808_0x0100_Deserialize() + { + for (int i = 0; i < N; i++) + { + var result = JT808Serializer.Deserialize(bytes0x0100); + } + } + } + + public class JT808SerializerConfig : ManualConfig + { + public JT808SerializerConfig() + { + Add(Job.Default.WithGcServer(false).With(Runtime.Clr).With(Platform.AnyCpu)); + Add(Job.Default.WithGcServer(false).With(CsProjCoreToolchain.NetCoreApp22).With(Platform.AnyCpu)); + } + } +} diff --git a/src/JT808.Protocol.Benchmark/Program.cs b/src/JT808.Protocol.Benchmark/Program.cs new file mode 100644 index 0000000..21806ce --- /dev/null +++ b/src/JT808.Protocol.Benchmark/Program.cs @@ -0,0 +1,26 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; +using BenchmarkDotNet.Toolchains.CsProj; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace JT808.Protocol.Benchmark +{ + class Program + { + static void Main(string[] args) + { + //安装NuGet包,BenchmarkDotNet + //在需要做性能测试的方法前加上属性[Benchmark]。 + Summary summary = BenchmarkRunner.Run(); + //Summary summary1 = BenchmarkRunner.Run(); + //Summary summary2 = BenchmarkRunner.Run(); + } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808.Protocol.Extensions.DependencyInjection.Test.csproj b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808.Protocol.Extensions.DependencyInjection.Test.csproj new file mode 100644 index 0000000..7ab4c33 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808.Protocol.Extensions.DependencyInjection.Test.csproj @@ -0,0 +1,27 @@ + + + + Exe + netcoreapp2.2 + latest + + + + + + + + + + + + + + + + + Always + + + + diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0200_0x06Formatter.cs b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0200_0x06Formatter.cs new file mode 100644 index 0000000..5bd47f6 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0200_0x06Formatter.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Extensions.DependencyInjection.Test.JT808LocationAttach +{ + public class JT808_0x0200_0x06Formatter : IJT808MessagePackFormatter + { + public JT808LocationAttachImpl0x06 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808LocationAttachImpl0x06 jT808LocationAttachImpl0x06 = new JT808LocationAttachImpl0x06() { }; + jT808LocationAttachImpl0x06.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x06.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x06.Age = reader.ReadInt32(); + jT808LocationAttachImpl0x06.Gender = reader.ReadByte(); + jT808LocationAttachImpl0x06.UserName = reader.ReadRemainStringContent(); + return jT808LocationAttachImpl0x06; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808LocationAttachImpl0x06 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte( value.AttachInfoLength); + writer.WriteInt32(value.Age); + writer.WriteByte(value.Gender); + writer.WriteString(value.UserName); + } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs new file mode 100644 index 0000000..a47c564 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Extensions.DependencyInjection.Test.JT808_0x0701BodiesImpl; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Extensions.DependencyInjection.Test.JT808Formatters +{ + public class JT808_0x0701TestBodiesImplFormatter : IJT808MessagePackFormatter + { + public JT808_0x0701TestBodiesImpl Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0701TestBodiesImpl jT808_0X0701TestBodiesImpl = new JT808_0x0701TestBodiesImpl(); + jT808_0X0701TestBodiesImpl.Id = reader.ReadUInt32(); + jT808_0X0701TestBodiesImpl.UserNameLength = reader.ReadUInt16(); + return jT808_0X0701TestBodiesImpl; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0701TestBodiesImpl value, IJT808Config config) + { + writer.WriteUInt32(value.Id); + // 先计算内容长度(汉字为两个字节) + writer.Skip(2, out int position); + writer.WriteString(value.UserName); + writer.WriteUInt16Return((ushort)(writer.GetCurrentPosition()- position-2), position); + } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs new file mode 100644 index 0000000..8a3dba7 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs @@ -0,0 +1,21 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Extensions.DependencyInjection.Test.JT808LocationAttach +{ + ///

+ /// 自定义附加信息 + /// Age-word-2 + /// UserName-BCD(10) + /// Gerder-byte-1 + /// + [JT808Formatter(typeof(JT808_0x0200_0x06Formatter))] + public class JT808LocationAttachImpl0x06 : JT808_0x0200_BodyBase + { + public override byte AttachInfoId { get; set; } = 0x06; + public override byte AttachInfoLength { get; set; } = 13; + public int Age { get; set; } + public byte Gender { get; set; } + public string UserName { get; set; } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808_0x0701TestBodiesImpl.cs b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808_0x0701TestBodiesImpl.cs new file mode 100644 index 0000000..771fdd5 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/JT808LocationAttachExtensions/JT808_0x0701TestBodiesImpl.cs @@ -0,0 +1,16 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Extensions.DependencyInjection.Test.JT808Formatters; +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Extensions.DependencyInjection.Test.JT808_0x0701BodiesImpl +{ + [JT808Formatter(typeof(JT808_0x0701TestBodiesImplFormatter))] + public class JT808_0x0701TestBodiesImpl : JT808_0x0701_CustomBodyBase + { + public uint Id { get; set; } + + public ushort UserNameLength { get; set; } + + public string UserName { get; set; } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/Program.cs b/src/JT808.Protocol.Extensions.DependencyInjection.Test/Program.cs new file mode 100644 index 0000000..4c754cd --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/Program.cs @@ -0,0 +1,74 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; +using JT808.Protocol.MessageBody; +using System.Linq; +using JT808.Protocol.Extensions.DependencyInjection.Test.JT808LocationAttach; +using JT808.Protocol.Extensions.DependencyInjection.Test.JT808_0x0701BodiesImpl; +using System.Reflection; +using JT808.Protocol.Interfaces; + +namespace JT808.Protocol.Extensions.DependencyInjection.Test +{ + class Program + { + static void Main(string[] args) + { + //单个 + IServiceCollection serviceDescriptors1 = new ServiceCollection(); + serviceDescriptors1.AddJT808Configure(new DefaultConfig()); + var ServiceProvider1 = serviceDescriptors1.BuildServiceProvider(); + var defaultConfig = ServiceProvider1.GetRequiredService(); + + //多个 + IServiceCollection serviceDescriptors2 = new ServiceCollection(); + serviceDescriptors2.AddJT808Configure(new Config1()); + serviceDescriptors2.AddJT808Configure(new Config2()); + serviceDescriptors2.AddSingleton(factory => + { + Func accesor = key => + { + if (key.Equals("Config1")) + { + return factory.GetService(); + } + else if (key.Equals("Config2")) + { + return factory.GetService(); + } + else + { + throw new ArgumentException($"Not Support key : {key}"); + } + }; + return accesor; + }); + + var ServiceProvider2 = serviceDescriptors2.BuildServiceProvider(); + + var config1 = ServiceProvider2.GetRequiredService>()("Config1"); + var flag21 = config1.GetSerializer().SerializerId == "Config1"; + + var config2 = ServiceProvider2.GetRequiredService>()("Config2"); + var flag22 = config2.GetSerializer().SerializerId == "Config2"; + } + } + + public class DefaultConfig : GlobalConfigBase + { + public override string ConfigId => "test"; + } + + public class Config1 : GlobalConfigBase + { + public override string ConfigId => "Config1"; + } + + public class Config2 : GlobalConfigBase + { + public override string ConfigId => "Config2"; + } +} + diff --git a/src/JT808.Protocol.Extensions.DependencyInjection.Test/appsettings.json b/src/JT808.Protocol.Extensions.DependencyInjection.Test/appsettings.json new file mode 100644 index 0000000..bf7af53 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection.Test/appsettings.json @@ -0,0 +1,5 @@ +{ + "JT809Options": { + "SkipCRCCode": false + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection/DependencyInjectionExtensions.cs b/src/JT808.Protocol.Extensions.DependencyInjection/DependencyInjectionExtensions.cs new file mode 100644 index 0000000..261b33b --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection/DependencyInjectionExtensions.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Interfaces; +using Microsoft.Extensions.DependencyInjection; + +namespace JT808.Protocol.Extensions.DependencyInjection +{ + public static class DependencyInjectionExtensions + { + public static IServiceCollection AddJT808Configure(this IServiceCollection services, IJT808Config jT808Config) + { + services.AddSingleton(jT808Config.GetType(), jT808Config); + services.AddSingleton(jT808Config); + return services; + } + + public static IServiceCollection AddJT808Configure(this IServiceCollection services) + { + services.AddSingleton(new DefaultGlobalConfig()); + return services; + } + + class DefaultGlobalConfig : GlobalConfigBase + { + public override string ConfigId => "default"; + } + } +} diff --git a/src/JT808.Protocol.Extensions.DependencyInjection/JT808.Protocol.Extensions.DependencyInjection.csproj b/src/JT808.Protocol.Extensions.DependencyInjection/JT808.Protocol.Extensions.DependencyInjection.csproj new file mode 100644 index 0000000..ca124b9 --- /dev/null +++ b/src/JT808.Protocol.Extensions.DependencyInjection/JT808.Protocol.Extensions.DependencyInjection.csproj @@ -0,0 +1,31 @@ + + + + netcoreapp2.2 + latest + Copyright 2018. + SmallChi + JT808.Extensions.DependencyInjection + JT808.Extensions.DependencyInjection + JT808协议依赖注入扩展包 + JT808协议依赖注入扩展包 + false + https://github.com/SmallChi/JT808 + https://github.com/SmallChi/JT808 + https://github.com/SmallChi/JT808/blob/master/LICENSE + true + 2.0.0 + + + + + + + + + + + + + + diff --git a/src/JT808.Protocol.Test/Extensions/JT808EnumExtensionsTest.cs b/src/JT808.Protocol.Test/Extensions/JT808EnumExtensionsTest.cs new file mode 100644 index 0000000..7b135a8 --- /dev/null +++ b/src/JT808.Protocol.Test/Extensions/JT808EnumExtensionsTest.cs @@ -0,0 +1,18 @@ +using JT808.Protocol.Extensions; +using Xunit; + +namespace JT808.Protocol.Test.Extensions +{ + public class JT808EnumExtensionsTest + { + [Fact] + public void Test1() + { + var list0 = JT808EnumExtensions.GetEnumTypes(5, 32); + var list1 = JT808EnumExtensions.GetEnumTypes(16, 32); + var list2 = JT808EnumExtensions.GetEnumTypes(18, 32); + var list3 = JT808EnumExtensions.GetEnumTypes(24, 32); + var list4 = JT808EnumExtensions.GetEnumTypes(31, 32); + } + } +} diff --git a/src/JT808.Protocol.Test/Extensions/JT808PackageExtensionsTest.cs b/src/JT808.Protocol.Test/Extensions/JT808PackageExtensionsTest.cs new file mode 100644 index 0000000..8da9e41 --- /dev/null +++ b/src/JT808.Protocol.Test/Extensions/JT808PackageExtensionsTest.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Enums; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using JT808.Protocol.Extensions; +using System.Reflection; +using System.Linq; +using JT808.Protocol.Formatters; + +namespace JT808.Protocol.Test.Extensions +{ + public class JT808PackageExtensionsTest + { + [Fact] + public void CreatePackage() + { + var package= JT808MsgId.终端心跳.Create_终端心跳("123456789", new Protocol.MessageBody.JT808_0x0002 { + + }); + } + + + //[Fact] + //public void Get() + //{ + // string type = "222".Replace("",""); + // var a = Assembly.GetAssembly(typeof(JT808Package)).GetTypes().Where(w=>w.FullName.EndsWith("Formatter")).ToList(); + //} + } +} diff --git a/src/JT808.Protocol.Test/Files/test.txt b/src/JT808.Protocol.Test/Files/test.txt new file mode 100644 index 0000000..343e481 --- /dev/null +++ b/src/JT808.Protocol.Test/Files/test.txt @@ -0,0 +1 @@ +testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest \ No newline at end of file diff --git a/src/JT808.Protocol.Test/Internal/JT808MsgIdFactoryTest.cs b/src/JT808.Protocol.Test/Internal/JT808MsgIdFactoryTest.cs new file mode 100644 index 0000000..1cf8002 --- /dev/null +++ b/src/JT808.Protocol.Test/Internal/JT808MsgIdFactoryTest.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace JT808.Protocol.Test.Internal +{ + public class JT808MsgIdFactoryTest + { + [Fact] + public void Test1() + { + IJT808MsgIdFactory jT808MsgIdFactory = new JT808MsgIdFactory(); + + } + } +} diff --git a/src/JT808.Protocol.Test/Internal/JT808_0x0200_Custom_FactoryTest.cs b/src/JT808.Protocol.Test/Internal/JT808_0x0200_Custom_FactoryTest.cs new file mode 100644 index 0000000..43c3c20 --- /dev/null +++ b/src/JT808.Protocol.Test/Internal/JT808_0x0200_Custom_FactoryTest.cs @@ -0,0 +1,18 @@ +using JT808.Protocol.Internal; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace JT808.Protocol.Test.Internal +{ + public class JT808_0x0200_Custom_FactoryTest + { + [Fact] + public void Test1() + { + new JT808_0x0200_Custom_Factory().Register(Assembly.GetExecutingAssembly()); + } + } +} diff --git a/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj new file mode 100644 index 0000000..86b7381 --- /dev/null +++ b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj @@ -0,0 +1,126 @@ + + + + netcoreapp2.2 + false + 7.1 + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + Always + + + + diff --git a/src/JT808.Protocol.Test/JT808HeaderTest.cs b/src/JT808.Protocol.Test/JT808HeaderTest.cs new file mode 100644 index 0000000..8c761b4 --- /dev/null +++ b/src/JT808.Protocol.Test/JT808HeaderTest.cs @@ -0,0 +1,79 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using System; +using Xunit; + +namespace JT808.Protocol.Test +{ + public class JT808HeaderTest + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test3() + { + ReadOnlySpan dataLen = Convert.ToString(5, 2).PadLeft(10, '0').AsSpan(); + } + + [Fact] + public void Test4() + { + // "0000000000000101" + short a = Convert.ToInt16("0000000000000101",2); + var msgMethodBytes = BitConverter.GetBytes(a); + } + + [Fact] + public void Test1() + { + JT808Header jT808HeaderProperty = new JT808Header + { + TerminalPhoneNo = "13812345678" + }; + jT808HeaderProperty.MessageBodyProperty.DataLength = 5; + jT808HeaderProperty.MsgNum = 135; + jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value(); + + var hex = JT808Serializer.Serialize(jT808HeaderProperty).ToHexString(); + Assert.Equal("01 02 00 05 01 38 12 34 56 78 00 87".Replace(" ",""), hex); + } + + [Fact] + public void Test1_2() + { + //01 02 00 05 01 38 12 34 56 78 00 87 + byte[] headerBytes = "01 02 00 05 01 38 12 34 56 78 00 87".ToHexBytes(); + JT808Header jT808Header = JT808Serializer.Deserialize(headerBytes); + Assert.Equal(135, jT808Header.MsgNum); + Assert.Equal("13812345678", jT808Header.TerminalPhoneNo); + Assert.False(jT808Header.MessageBodyProperty.IsPackge); + Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId); + Assert.Equal(5, jT808Header.MessageBodyProperty.DataLength); + } + + [Fact] + public void Test5() + { + JT808Header jT808HeaderProperty = new JT808Header(); + jT808HeaderProperty.TerminalPhoneNo = "13812345678"; + jT808HeaderProperty.MessageBodyProperty.DataLength = 5; + jT808HeaderProperty.MsgNum = 135; + jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value(); + //"01 02 00 05 01 38 12 34 56 78 00 87" + var hex = JT808Serializer.Serialize(jT808HeaderProperty).ToHexString(); + Assert.Equal("010200050138123456780087", hex); + } + + [Fact] + public void Test5_2() + { + //01 02 00 05 01 38 12 34 56 78 00 87 + byte[] headerBytes = "01 02 00 05 01 38 12 34 56 78 00 87".ToHexBytes(); + JT808Header jT808Header = JT808Serializer.Deserialize(headerBytes); + Assert.Equal(135, jT808Header.MsgNum); + Assert.Equal("13812345678", jT808Header.TerminalPhoneNo); + Assert.False(jT808Header.MessageBodyProperty.IsPackge); + Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId); + Assert.Equal(5, jT808Header.MessageBodyProperty.DataLength); + } + } +} diff --git a/src/JT808.Protocol.Test/JT808SerializerTest.cs b/src/JT808.Protocol.Test/JT808SerializerTest.cs new file mode 100644 index 0000000..96a4898 --- /dev/null +++ b/src/JT808.Protocol.Test/JT808SerializerTest.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace JT808.Protocol.Test +{ + public class JT808SerializerTest + { + [Fact] + public void Test1() + { + var result = Parallel.For(0, 100, new ParallelOptions { MaxDegreeOfParallelism = 2 }, (i) => + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer jT808Serializer = new JT808Serializer(jT808Config); + }); + if (result.IsCompleted) + { + + } + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0X8900_Test_BodiesImplFormatter.cs b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0X8900_Test_BodiesImplFormatter.cs new file mode 100644 index 0000000..f92057b --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0X8900_Test_BodiesImplFormatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Test.MessageBody.JT808_0X8900_BodiesImpl; +using System; + +namespace JT808.Protocol.Test.MessageBody.JT808Formatters +{ + public class JT808_0X8900_Test_BodiesImplFormatter : IJT808MessagePackFormatter + { + public JT808_0X8900_Test_BodiesImpl Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0X8900_Test_BodiesImpl jT808_0X8900_Test_BodiesImpl = new JT808_0X8900_Test_BodiesImpl(); + jT808_0X8900_Test_BodiesImpl.Id = reader.ReadUInt32(); + jT808_0X8900_Test_BodiesImpl.Sex = reader.ReadByte(); + return jT808_0X8900_Test_BodiesImpl; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0X8900_Test_BodiesImpl value, IJT808Config config) + { + writer.WriteUInt32(value.Id); + writer.WriteByte(value.Sex); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0200_0x06Formatter.cs b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0200_0x06Formatter.cs new file mode 100644 index 0000000..b120046 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0200_0x06Formatter.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Test.JT808LocationAttach; +using System; + +namespace JT808.Protocol.Test.JT808Formatters.MessageBodyFormatters.JT808LocationAttach +{ + public class JT808_0x0200_0x06Formatter : IJT808MessagePackFormatter + { + public JT808LocationAttachImpl0x06 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808LocationAttachImpl0x06 jT808LocationAttachImpl0x06 = new JT808LocationAttachImpl0x06(); + jT808LocationAttachImpl0x06.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x06.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x06.Age = reader.ReadInt32(); + jT808LocationAttachImpl0x06.Gender = reader.ReadByte(); + jT808LocationAttachImpl0x06.UserName = reader.ReadRemainStringContent(); + return jT808LocationAttachImpl0x06; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808LocationAttachImpl0x06 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteInt32(value.Age); + writer.WriteByte(value.Gender); + writer.WriteString(value.UserName); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs new file mode 100644 index 0000000..2989332 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0701TestBodiesImplFormatter.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Test.MessageBody.JT808_0x0701BodiesImpl; +using System; + +namespace JT808.Protocol.Test.MessageBody.JT808Formatters +{ + public class JT808_0x0701TestBodiesImplFormatter : IJT808MessagePackFormatter + { + public JT808_0x0701TestBodiesImpl Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0701TestBodiesImpl jT808_0X0701TestBodiesImpl = new JT808_0x0701TestBodiesImpl(); + jT808_0X0701TestBodiesImpl.Id = reader.ReadUInt32(); + jT808_0X0701TestBodiesImpl.UserNameLength = reader.ReadUInt16(); + jT808_0X0701TestBodiesImpl.UserName = reader.ReadString(jT808_0X0701TestBodiesImpl.UserNameLength); + return jT808_0X0701TestBodiesImpl; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0701TestBodiesImpl value, IJT808Config config) + { + writer.WriteUInt32(value.Id); + writer.Skip(2,out int position); + writer.WriteString(value.UserName); + int strLength = writer.GetCurrentPosition() - position - 2; + writer.WriteUInt16Return((ushort)strLength, position); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0900_0x83Formatter.cs b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0900_0x83Formatter.cs new file mode 100644 index 0000000..cbf391c --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808Formatters/JT808_0x0900_0x83Formatter.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Test.JT808_0x0900_BodiesImpl; +using System; + +namespace JT808.Protocol.Test.MessageBody.JT808Formatters +{ + public class JT808_0x0900_0x83Formatter : IJT808MessagePackFormatter + { + public JT808_0x0900_0x83 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0900_0x83 jT808PassthroughType0x83 = new JT808_0x0900_0x83(); + jT808PassthroughType0x83.PassthroughContent = reader.ReadRemainStringContent(); + return jT808PassthroughType0x83; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0900_0x83 value, IJT808Config config) + { + writer.WriteString(value.PassthroughContent); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs b/src/JT808.Protocol.Test/MessageBody/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs new file mode 100644 index 0000000..f2c6983 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808LocationAttachExtensions/JT808LocationAttachImpl0x06.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.JT808Formatters.MessageBodyFormatters.JT808LocationAttach; + +namespace JT808.Protocol.Test.JT808LocationAttach +{ + /// + /// 自定义附加信息 + /// Age-word-2 + /// UserName-BCD(10) + /// Gerder-byte-1 + /// + [JT808Formatter(typeof(JT808_0x0200_0x06Formatter))] + public class JT808LocationAttachImpl0x06: JT808_0x0200_CustomBodyBase + { + public override byte AttachInfoId { get; set; } = 0x06; + public override byte AttachInfoLength { get; set; } = 13; + public int Age { get; set; } + public byte Gender { get; set; } + public string UserName { get; set; } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0X8900_BodiesImpl/JT808_0X8900_Test_BodiesImpl.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0X8900_BodiesImpl/JT808_0X8900_Test_BodiesImpl.cs new file mode 100644 index 0000000..6f4a803 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0X8900_BodiesImpl/JT808_0X8900_Test_BodiesImpl.cs @@ -0,0 +1,14 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.MessageBody.JT808Formatters; + +namespace JT808.Protocol.Test.MessageBody.JT808_0X8900_BodiesImpl +{ + [JT808Formatter(typeof(JT808_0X8900_Test_BodiesImplFormatter))] + public class JT808_0X8900_Test_BodiesImpl: JT808_0x8900_BodyBase + { + public uint Id { get; set; } + + public byte Sex { get; set; } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0001Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0001Test.cs new file mode 100644 index 0000000..7f3c3c1 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0001Test.cs @@ -0,0 +1,48 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0001Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端通用应答.ToUInt16Value(), + MsgNum = 1203, + TerminalPhoneNo = "012345678900" + }, + Bodies = new JT808_0x0001 + { + MsgId = Enums.JT808MsgId.终端心跳.ToUInt16Value(), + MsgNum = 1000, + JT808TerminalResult = Enums.JT808TerminalResult.Success + } + }; + //"7E 00 01 00 05 01 23 45 67 89 00 04 B3 03 E8 00 02 00 D3 7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0001000501234567890004B303E8000200D37E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E 00 01 00 05 01 23 45 67 89 00 04 B3 03 E8 00 02 00 D3 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端通用应答.ToValue(), jT808Package.Header.MsgId); + Assert.Equal(1203, jT808Package.Header.MsgNum); + + JT808_0x0001 JT808Bodies = (JT808_0x0001)jT808Package.Bodies; + Assert.Equal(Enums.JT808MsgId.终端心跳.ToUInt16Value(), JT808Bodies.MsgId); + Assert.Equal(1000, JT808Bodies.MsgNum); + Assert.Equal(Enums.JT808TerminalResult.Success, JT808Bodies.JT808TerminalResult); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0002Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0002Test.cs new file mode 100644 index 0000000..d148985 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0002Test.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0002Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端心跳.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "12345678900", + } + }; + //"7E 00 02 00 00 01 23 45 67 89 00 00 0A 81 7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E00020000012345678900000A817E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E 00 02 00 00 01 23 45 67 89 00 00 0A 81 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端心跳.ToValue(), jT808Package.Header.MsgId); + Assert.Equal(10, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + Assert.Null(jT808Package.Bodies); + } + + [Fact] + public void Test3() + { + var bytes = "7E 00 02 00 00 04 00 21 67 92 87 00 2B 7D 02 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端心跳.ToValue(), jT808Package.Header.MsgId); + Assert.Equal(43, jT808Package.Header.MsgNum); + Assert.Equal("40021679287", jT808Package.Header.TerminalPhoneNo); + Assert.Null(jT808Package.Bodies); + } + + [Fact] + public void Test4() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端心跳.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "12345678900", + }, + Bodies= new JT808_0x0002() + }; + //"7E 00 02 00 00 01 23 45 67 89 00 00 0A 81 7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E00020000012345678900000A817E", hex); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0003Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0003Test.cs new file mode 100644 index 0000000..ad58673 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0003Test.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Extensions; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0003Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端注销.ToUInt16Value(), + MsgNum = 1, + TerminalPhoneNo = "12345678900", + } + }; + //"7E 00 03 00 00 01 23 45 67 89 00 00 01 8B 7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0003000001234567890000018B7E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E 00 03 00 00 01 23 45 67 89 00 00 01 8B 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端注销.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(1, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + Assert.Null(jT808Package.Bodies); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs new file mode 100644 index 0000000..961e665 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs @@ -0,0 +1,56 @@ +using Xunit; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0100Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + + [Fact] + public void Test1() + { + JT808Package jT808_0X0100 = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端注册.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "123456789", + }, + Bodies = new JT808_0x0100 + { + AreaID = 40, + CityOrCountyId = 50, + MakerId = "1234", + PlateColor = 1, + PlateNo = "粤A12345", + TerminalId = "CHI123", + TerminalModel = "smallchi123" + } + }; + var hex = JT808Serializer.Serialize(jT808_0X0100).ToHexString(); + Assert.Equal("7E0100002D000123456789000A002800323132333430736D616C6C6368693132333030303030303030304348493132333001D4C1413132333435BA7E", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "7E 01 00 00 2D 00 01 23 45 67 89 00 0A 00 28 00 32 31 32 33 34 30 73 6D 61 6C 6C 63 68 69 31 32 33 30 30 30 30 30 30 30 30 30 43 48 49 31 32 33 30 01 D4 C1 41 31 32 33 34 35 BA 7E".ToHexBytes(); + JT808Package jT808_0X0100 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端注册.ToUInt16Value(), jT808_0X0100.Header.MsgId); + Assert.Equal(10, jT808_0X0100.Header.MsgNum); + Assert.Equal("123456789", jT808_0X0100.Header.TerminalPhoneNo); + + JT808_0x0100 JT808Bodies = (JT808_0x0100)jT808_0X0100.Bodies; + Assert.Equal(40, JT808Bodies.AreaID); + Assert.Equal(50, JT808Bodies.CityOrCountyId); + Assert.Equal("12340", JT808Bodies.MakerId); + Assert.Equal(1, JT808Bodies.PlateColor); + Assert.Equal("粤A12345", JT808Bodies.PlateNo); + Assert.Equal("CHI1230", JT808Bodies.TerminalId); + Assert.Equal("smallchi123000000000", JT808Bodies.TerminalModel); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs new file mode 100644 index 0000000..1b02e62 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs @@ -0,0 +1,62 @@ +using Xunit; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0102Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0102 jT808LoginRequestProperty = new JT808_0x0102 + { + Code = "45612" + }; + string hex = JT808Serializer.Serialize(jT808LoginRequestProperty).ToHexString(); + Assert.Equal("3435363132", hex); + } + + [Fact] + public void Test2() + { + byte[] bodys = "34 35 36 31 32".ToHexBytes(); + JT808_0x0102 jT808LoginRequest = JT808Serializer.Deserialize(bodys); + Assert.Equal("45612", jT808LoginRequest.Code); + } + + [Fact] + public void Test3() + { + JT808Package jT808LoginRequest = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端鉴权.ToUInt16Value(), + MsgNum = 12345, + TerminalPhoneNo = "12345678900", + }, + Bodies = new JT808_0x0102 + { + Code = "456121111" + } + }; + string hex = JT808Serializer.Serialize(jT808LoginRequest).ToHexString(); + Assert.Equal("7E010200090123456789003039343536313231313131BE7E", hex); + } + + [Fact] + public void Test4() + { + byte[] bodys = "7E 01 02 00 09 01 23 45 67 89 00 30 39 34 35 36 31 32 31 31 31 31 BE 7E".ToHexBytes(); + JT808Package jT808LoginRequest = JT808Serializer.Deserialize(bodys); + Assert.Equal(Enums.JT808MsgId.终端鉴权.ToUInt16Value(), jT808LoginRequest.Header.MsgId); + Assert.Equal(12345, jT808LoginRequest.Header.MsgNum); + Assert.Equal("12345678900", jT808LoginRequest.Header.TerminalPhoneNo); + + JT808_0x0102 JT808Bodies = (JT808_0x0102)jT808LoginRequest.Bodies; + Assert.Equal("456121111", JT808Bodies.Code); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0104Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0104Test.cs new file mode 100644 index 0000000..5608bef --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0104Test.cs @@ -0,0 +1,125 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0104Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.查询终端参数应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "123456789", + }, + Bodies = new JT808_0x0104 + { + MsgNum = 20, + AnswerParamsCount = 1, + ParamList = new List { + new JT808_0x8103_0x0001() { + ParamId=0x0001, + ParamLength=4, + ParamValue=10 + } + } + } + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0104000C000123456789000A00140100000001040000000A907E", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "7E0104000C000123456789000A00140100000001040000000A907E".ToHexBytes(); + JT808Package jT808_0X8104 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.查询终端参数应答.ToUInt16Value(), jT808_0X8104.Header.MsgId); + Assert.Equal(10, jT808_0X8104.Header.MsgNum); + Assert.Equal("123456789", jT808_0X8104.Header.TerminalPhoneNo); + + JT808_0x0104 JT808Bodies = (JT808_0x0104)jT808_0X8104.Bodies; + Assert.Equal(20, JT808Bodies.MsgNum); + Assert.Equal(1, JT808Bodies.AnswerParamsCount); + foreach (var item in JT808Bodies.ParamList) + { + Assert.Equal(0x0001u, ((JT808_0x8103_0x0001)item).ParamId); + Assert.Equal(4, ((JT808_0x8103_0x0001)item).ParamLength); + Assert.Equal(10u, ((JT808_0x8103_0x0001)item).ParamValue); + } + } + + + [Fact] + public void Test2() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.查询终端参数应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "123456789", + }, + Bodies = new JT808_0x0104 + { + MsgNum = 20, + AnswerParamsCount = 2, + ParamList = new List { + new JT808_0x8103_0x0001() { + ParamId=0x0001, + ParamLength=4, + ParamValue=10 + }, + new JT808_0x8103_0x0013(){ + ParamId=0x0013, + ParamValue="www.baidu.com" + } + } + } + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + //7E0104001E000123456789000A00140200000001040000000A000000130F7777772E62616964752E636F6DF07E + //7E0104001E000123456789000A00140200000001040000000A000000130D7777772E62616964752E636F6DF27E + Assert.Equal("7E0104001E000123456789000A00140200000001040000000A000000130D7777772E62616964752E636F6DF27E", hex); + } + + [Fact] + public void Test2_1() + { + byte[] bytes = "7E0104001E000123456789000A00140200000001040000000A000000130D7777772E62616964752E636F6DF27E".ToHexBytes(); + JT808Package jT808_0X8104 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.查询终端参数应答.ToUInt16Value(), jT808_0X8104.Header.MsgId); + Assert.Equal(10, jT808_0X8104.Header.MsgNum); + Assert.Equal("123456789", jT808_0X8104.Header.TerminalPhoneNo); + + JT808_0x0104 JT808Bodies = (JT808_0x0104)jT808_0X8104.Bodies; + Assert.Equal(20, JT808Bodies.MsgNum); + Assert.Equal(2, JT808Bodies.AnswerParamsCount); + foreach (var item in JT808Bodies.ParamList) + { + switch (item.ParamId) + { + case 0x0001: + Assert.Equal(0x0001u, ((JT808_0x8103_0x0001)item).ParamId); + Assert.Equal(4, ((JT808_0x8103_0x0001)item).ParamLength); + Assert.Equal(10u, ((JT808_0x8103_0x0001)item).ParamValue); + break; + case 0x0013: + Assert.Equal(0x0013u, ((JT808_0x8103_0x0013)item).ParamId); + Assert.Equal("www.baidu.com", ((JT808_0x8103_0x0013)item).ParamValue); + break; + default: + break; + } + } + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0107Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0107Test.cs new file mode 100644 index 0000000..152da38 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0107Test.cs @@ -0,0 +1,63 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0107Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.查询终端属性应答.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + } + }; + JT808_0x0107 jT808_0X0107 = new JT808_0x0107 + { + // 00000000 00000101 + TerminalType = 5, + MakerId = "10601", + TerminalModel = "10455545955103", + TerminalId = "4d6a13", + Terminal_SIM_ICCID = "1232355987", + Terminal_Hardware_Version_Num = "abcdefg", + Terminal_Firmware_Version_Num = "poiuytrewq", + // 00000111 + GNSSModule = 7, + // 00001001 + CommunicationModule = 9 + }; + jT808Package.Bodies = jT808_0X0107; + string hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + //"7E 01 07 00 3C 11 22 33 44 55 66 22 B8 00 05 31 30 36 30 31 31 30 34 35 35 35 34 35 39 35 35 31 30 33 30 30 30 30 30 30 34 64 36 61 31 33 30 12 32 35 59 87 07 61 62 63 64 65 66 67 0A 70 6F 69 75 79 74 72 65 77 71 07 09 6C 7E" + Assert.Equal("7E 01 07 00 3C 11 22 33 44 55 66 22 B8 00 05 31 30 36 30 31 31 30 34 35 35 35 34 35 39 35 35 31 30 33 30 30 30 30 30 30 34 64 36 61 31 33 30 12 32 35 59 87 07 61 62 63 64 65 66 67 0A 70 6F 69 75 79 74 72 65 77 71 07 09 6C 7E".Replace(" ", ""), hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "7E 01 07 00 3C 11 22 33 44 55 66 22 B8 00 05 31 30 36 30 31 31 30 34 35 35 35 34 35 39 35 35 31 30 33 30 30 30 30 30 30 34 64 36 61 31 33 30 12 32 35 59 87 07 61 62 63 64 65 66 67 0A 70 6F 69 75 79 74 72 65 77 71 07 09 6C 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + JT808_0x0107 jT808_0X0107 = (JT808_0x0107)jT808Package.Bodies; + Assert.Equal(8888, jT808Package.Header.MsgNum); + Assert.Equal("112233445566", jT808Package.Header.TerminalPhoneNo); + Assert.Equal(Enums.JT808MsgId.查询终端属性应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(5, jT808_0X0107.TerminalType); + Assert.Equal("10601", jT808_0X0107.MakerId); + Assert.Equal("10455545955103000000", jT808_0X0107.TerminalModel); + Assert.Equal("4d6a130", jT808_0X0107.TerminalId); + Assert.Equal("1232355987", jT808_0X0107.Terminal_SIM_ICCID); + Assert.Equal("abcdefg", jT808_0X0107.Terminal_Hardware_Version_Num); + Assert.Equal("poiuytrewq", jT808_0X0107.Terminal_Firmware_Version_Num); + Assert.Equal(7, jT808_0X0107.GNSSModule); + Assert.Equal(9, jT808_0X0107.CommunicationModule); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0108Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0108Test.cs new file mode 100644 index 0000000..b7881f0 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0108Test.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0108Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0108 jT808_0X0108 = new JT808_0x0108 + { + UpgradeType = JT808UpgradeType.北斗卫星定位模块, + UpgradeResult = JT808UpgradeResult.成功 + }; + string hex = JT808Serializer.Serialize(jT808_0X0108).ToHexString(); + Assert.Equal("3400", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "34 00".ToHexBytes(); + JT808_0x0108 jT808_0X0108 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808UpgradeResult.成功, jT808_0X0108.UpgradeResult); + Assert.Equal(JT808UpgradeType.北斗卫星定位模块, jT808_0X0108.UpgradeType); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0200Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0200Test.cs new file mode 100644 index 0000000..ecede6c --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0200Test.cs @@ -0,0 +1,375 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.JT808LocationAttach; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0200Test + { + JT808Serializer JT808Serializer; + + public JT808_0x0200Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + [Fact] + public void Test1() + { + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + var hex = JT808Serializer.Serialize(jT808UploadLocationRequest).ToHexString(); + Assert.Equal("000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037", hex); + } + + [Fact] + public void Parallel_Test1_1() + { + ConcurrentBag hexs = new ConcurrentBag(); + Parallel.For(1, 20, new ParallelOptions + { + MaxDegreeOfParallelism=5 + }, (i) => + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), + MsgNum = (ushort)i, + TerminalPhoneNo = "1122334455"+i.ToString(), + }; + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10").AddSeconds(i), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808Package.Bodies = jT808UploadLocationRequest; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + hexs.Add(hex); + }); + //7E02000026 112233445519 0013 000000010000000200BA7F0E07E4F11C0028003C0000 180715101029 01040000006402020037987E, + //7E02000026 112233445518 0012 000000010000000200BA7F0E07E4F11C0028003C0000 180715101028 01040000006402020037997E, + //7E02000026 112233445517 0011 000000010000000200BA7F0E07E4F11C0028003C0000 180715101027 010400000064020200379A7E, + //7E02000026 112233445516 0010 000000010000000200BA7F0E07E4F11C0028003C0000 180715101026 010400000064020200379B7E, + //7E02000026 112233445515 000F 000000010000000200BA7F0E07E4F11C0028003C0000 180715101025 01040000006402020037847E, + //7E02000026 112233445514 000E 000000010000000200BA7F0E07E4F11C0028003C0000 180715101024 01040000006402020037857E, + //7E02000026 112233445513 000D 000000010000000200BA7F0E07E4F11C0028003C0000 180715101023 01040000006402020037867E, + //7E02000026 112233445512 000C 000000010000000200BA7F0E07E4F11C0028003C0000 180715101022 01040000006402020037877E, + //7E02000026 112233445511 000B 000000010000000200BA7F0E07E4F11C0028003C0000 180715101021 01040000006402020037807E, + //7E02000026 112233445510 000A 000000010000000200BA7F0E07E4F11C0028003C0000 180715101020 01040000006402020037817E, + //7E02000026 011223344559 0009 000000010000000200BA7F0E07E4F11C0028003C0000 180715101019 01040000006402020037A27E, + //7E02000026 011223344558 0008 000000010000000200BA7F0E07E4F11C0028003C0000 180715101018 01040000006402020037A37E, + //7E02000026 011223344557 0007 000000010000000200BA7F0E07E4F11C0028003C0000 180715101017 01040000006402020037AC7E, + //7E02000026 011223344556 0006 000000010000000200BA7F0E07E4F11C0028003C0000 180715101016 01040000006402020037AD7E, + //7E02000026 011223344555 0005 000000010000000200BA7F0E07E4F11C0028003C0000 180715101015 01040000006402020037AE7E, + //7E02000026 011223344554 0004 000000010000000200BA7F0E07E4F11C0028003C0000 180715101014 01040000006402020037AF7E, + //7E02000026 011223344553 0003 000000010000000200BA7F0E07E4F11C0028003C0000 180715101013 01040000006402020037A87E, + //7E02000026 011223344552 0002 000000010000000200BA7F0E07E4F11C0028003C0000 180715101012 01040000006402020037A97E, + //7E02000026 011223344551 0001 000000010000000200BA7F0E07E4F11C0028003C0000 180715101011 01040000006402020037AA7E, + //7E02000026 011223344550 0001 000000010000000200BA7F0E07E4F11C0028003C0000 180715101010 01040000006402020037AA7E + //7E02000026 011223344550 0000 000000010000000200BA7F0E07E4F11C0028003C0000 180715101010 01040000006402020037AB7E, + string result = "7E020000260112233445500000000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037AB7E,7E020000260112233445570007000000010000000200BA7F0E07E4F11C0028003C000018071510101701040000006402020037AC7E,7E020000260112233445560006000000010000000200BA7F0E07E4F11C0028003C000018071510101601040000006402020037AD7E,7E020000260112233445550005000000010000000200BA7F0E07E4F11C0028003C000018071510101501040000006402020037AE7E,7E020000260112233445540004000000010000000200BA7F0E07E4F11C0028003C000018071510101401040000006402020037AF7E,7E020000261122334455190013000000010000000200BA7F0E07E4F11C0028003C000018071510102901040000006402020037987E,7E020000261122334455180012000000010000000200BA7F0E07E4F11C0028003C000018071510102801040000006402020037997E,7E020000261122334455170011000000010000000200BA7F0E07E4F11C0028003C0000180715101027010400000064020200379A7E,7E020000261122334455160010000000010000000200BA7F0E07E4F11C0028003C0000180715101026010400000064020200379B7E,7E02000026112233445515000F000000010000000200BA7F0E07E4F11C0028003C000018071510102501040000006402020037847E,7E02000026112233445514000E000000010000000200BA7F0E07E4F11C0028003C000018071510102401040000006402020037857E,7E02000026112233445513000D000000010000000200BA7F0E07E4F11C0028003C000018071510102301040000006402020037867E,7E02000026112233445512000C000000010000000200BA7F0E07E4F11C0028003C000018071510102201040000006402020037877E,7E020000260112233445530003000000010000000200BA7F0E07E4F11C0028003C000018071510101301040000006402020037A87E,7E020000260112233445520002000000010000000200BA7F0E07E4F11C0028003C000018071510101201040000006402020037A97E,7E020000260112233445510001000000010000000200BA7F0E07E4F11C0028003C000018071510101101040000006402020037AA7E,7E02000026112233445511000B000000010000000200BA7F0E07E4F11C0028003C000018071510102101040000006402020037807E,7E02000026112233445510000A000000010000000200BA7F0E07E4F11C0028003C000018071510102001040000006402020037817E,7E020000260112233445590009000000010000000200BA7F0E07E4F11C0028003C000018071510101901040000006402020037A27E,7E020000260112233445580008000000010000000200BA7F0E07E4F11C0028003C000018071510101801040000006402020037A37E"; + //7E020000260112233445500001000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037AA7E + List resultHexs = result.Split(',').ToList(); + string hexStr = string.Join(',', hexs); + foreach (var item in hexs) + { + Assert.Contains(item, resultHexs); + } + } + + [Fact] + public void Test2() + { + byte[] bodys = "00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 07 15 10 10 10 01 04 00 00 00 64 02 02 00 37".ToHexBytes(); + JT808_0x0200 jT808UploadLocationRequest = JT808Serializer.Deserialize(bodys); + Assert.Equal((uint)1, jT808UploadLocationRequest.AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), jT808UploadLocationRequest.GPSTime); + Assert.Equal(12222222, jT808UploadLocationRequest.Lat); + Assert.Equal(132444444, jT808UploadLocationRequest.Lng); + Assert.Equal(60, jT808UploadLocationRequest.Speed); + Assert.Equal((uint)2, jT808UploadLocationRequest.StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + + [Fact] + public void Test3() + { + + //00 00 00 01 + //00 00 00 02 + //00 BA 7F 0E + //07 E4 F1 1C + //00 28 + //00 3C + //00 00 + //18 07 15 10 10 10 + //01 + // 04 + // 00 00 00 64 + //02 + // 02 + // 00 37 + //06 + // 0D + // 00 00 00 12 01 73 6D 61 6C 6C 63 68 69" + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary(), + JT808CustomLocationAttachData = new Dictionary() + }; + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808UploadLocationRequest.JT808CustomLocationAttachData.Add(0x06, new JT808LocationAttachImpl0x06 + { + Age = 18, + Gender = 1, + UserName = "smallchi" + }); + var hex = JT808Serializer.Serialize(jT808UploadLocationRequest).ToHexString(); + Assert.Equal("000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037060D0000001201736D616C6C636869", hex); + } + + [Fact] + public void Test4() + { + // 1.添加自定义附加信息扩展 AddJT808LocationAttachMethod + byte[] bodys = "00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 07 15 10 10 10 01 04 00 00 00 64 02 02 00 37 06 0D 00 00 00 12 01 73 6D 61 6C 6C 63 68 69".ToHexBytes(); + JT808_0x0200 jT808UploadLocationRequest = JT808Serializer.Deserialize(bodys); + Assert.Equal((uint)1, jT808UploadLocationRequest.AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), jT808UploadLocationRequest.GPSTime); + Assert.Equal(12222222, jT808UploadLocationRequest.Lat); + Assert.Equal(132444444, jT808UploadLocationRequest.Lng); + Assert.Equal(60, jT808UploadLocationRequest.Speed); + Assert.Equal((uint)2, jT808UploadLocationRequest.StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + var jT808LocationAttachImpl0x06 = JT808Serializer.Deserialize(jT808UploadLocationRequest.JT808CustomLocationAttachOriginalData[0x06]); + Assert.Equal(18, jT808LocationAttachImpl0x06.Age); + Assert.Equal(1, jT808LocationAttachImpl0x06.Gender); + Assert.Equal("smallchi", jT808LocationAttachImpl0x06.UserName); + } + + [Fact] + public void Test5_1() + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + //MessageBodyProperty=new JT808MessageBodyProperty(38), + }; + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808Package.Bodies = jT808UploadLocationRequest; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + } + + [Fact] + public void Test5() + { + //7E + //02 00 + //00 33 + //11 22 33 44 55 66 + //22 B8 + //00 00 00 01 + //00 00 00 02 + //00 BA 7F 0E + //07 E4 F1 1C + //00 28 + //00 3C + //00 00 + //18 07 15 10 10 10 + //01 + // 04 + // 00 00 00 64 + //02 + // 02 + // 00 37 + //42 7E + + + byte[] bytes = "7E 02 00 00 26 11 22 33 44 55 66 22 B8 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 07 15 10 10 10 01 04 00 00 00 64 02 02 00 37 57 7E".ToHexBytes(); + var jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.位置信息汇报.ToValue(), jT808Package.Header.MsgId); + + Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); + Assert.Equal(8888, jT808Package.Header.MsgNum); + Assert.Equal("112233445566", jT808Package.Header.TerminalPhoneNo); + //Assert.Equal(1, jT808Package.Header.MessageBodyProperty.DataLength); + Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); + Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); + Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); + Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); + + JT808_0x0200 jT808UploadLocationRequest = (JT808_0x0200)jT808Package.Bodies; + Assert.Equal((uint)1, jT808UploadLocationRequest.AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), jT808UploadLocationRequest.GPSTime); + Assert.Equal(12222222, jT808UploadLocationRequest.Lat); + Assert.Equal(132444444, jT808UploadLocationRequest.Lng); + Assert.Equal(60, jT808UploadLocationRequest.Speed); + Assert.Equal((uint)2, jT808UploadLocationRequest.StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)jT808UploadLocationRequest.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + + [Fact] + public void Test_all_attcahids() + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + }; + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200(); + jT808UploadLocationRequest.AlarmFlag = 1; + jT808UploadLocationRequest.Altitude = 40; + jT808UploadLocationRequest.GPSTime = DateTime.Parse("2018-07-15 10:10:10"); + jT808UploadLocationRequest.Lat = 12222222; + jT808UploadLocationRequest.Lng = 132444444; + jT808UploadLocationRequest.Speed = 60; + jT808UploadLocationRequest.Direction = 0; + jT808UploadLocationRequest.StatusFlag = 2; + jT808UploadLocationRequest.JT808LocationAttachData = new Dictionary(); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x03, new JT808_0x0200_0x03 + { + Speed = 56 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x04, new JT808_0x0200_0x04 + { + EventId = 1 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x11, new JT808_0x0200_0x11 + { + AreaId = 1, + JT808PositionType = Enums.JT808PositionType.圆形区域 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x12, new JT808_0x0200_0x12 + { + AreaId = 1, + JT808PositionType = Enums.JT808PositionType.圆形区域, + Direction = Enums.JT808DirectionType.出 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x13, new JT808_0x0200_0x13 + { + DrivenRoute = Enums.JT808DrivenRouteType.过长, + DrivenRouteId = 2, + Time = 34 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x25, new JT808_0x0200_0x25 + { + CarSignalStatus = 23 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x2A, new JT808_0x0200_0x2A + { + IOStatus = 244 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x2B, new JT808_0x0200_0x2B + { + Analog = 242 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x30, new JT808_0x0200_0x30 + { + WiFiSignalStrength = 0x02 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x31, new JT808_0x0200_0x31 + { + GNSSCount = 0x05 + }); + jT808Package.Bodies = jT808UploadLocationRequest; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0200005C11223344556622B8000000010000000200BA7F0E07E4F11C0028003C00001807151010100104000000640202003703020038040200011105010000000112060100000001011307000000020022012504000000172A0200F42B04000000F2300102310105167E", hex); + //7E0200005C11223344556622B8000000010000000200BA7F0E07E4F11C0028003C00001807151010100104000000640202003703020038040200011105010000000112060100000001011307000000020022012504000000172A0200F42B04000000F2300102310105167E + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0201Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0201Test.cs new file mode 100644 index 0000000..e67296a --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0201Test.cs @@ -0,0 +1,72 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0201Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.位置信息查询应答.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + } + }; + JT808_0x0201 jT808_0X0201 = new JT808_0x0201 + { + MsgNum = 12345 + }; + JT808_0x0200 jT808UploadLocationRequest = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + jT808UploadLocationRequest.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808_0X0201.Position = jT808UploadLocationRequest; + jT808Package.Bodies = jT808_0X0201; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0201002811223344556622B83039000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037517E".Length, hex.Length); + Assert.Equal("7E0201002811223344556622B83039000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037517E", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "7E0201002811223344556622B83039000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037517E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + JT808_0x0201 jT808_0X0201 = (JT808_0x0201) jT808Package.Bodies; + Assert.Equal(12345, jT808_0X0201.MsgNum); + Assert.Equal((uint)1, jT808_0X0201.Position.AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), jT808_0X0201.Position.GPSTime); + Assert.Equal(12222222, jT808_0X0201.Position.Lat); + Assert.Equal(132444444, jT808_0X0201.Position.Lng); + Assert.Equal(60, jT808_0X0201.Position.Speed); + Assert.Equal((uint)2, jT808_0X0201.Position.StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)jT808_0X0201.Position.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)jT808_0X0201.Position.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0301Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0301Test.cs new file mode 100644 index 0000000..ef93524 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0301Test.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0301Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0301 jT808_0X0301 = new JT808_0x0301 + { + EventId = 123 + }; + var hex = JT808Serializer.Serialize(jT808_0X0301).ToHexString(); + Assert.Equal("7B", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "7B".ToHexBytes(); + JT808_0x0301 jT808_0X8104 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X8104.EventId); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0302Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0302Test.cs new file mode 100644 index 0000000..f38128f --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0302Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0302Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0302 jT808_0X0302 = new JT808_0x0302 + { + AnswerId = 123, + ReplySNo = 4521 + }; + var hex = JT808Serializer.Serialize(jT808_0X0302).ToHexString(); + Assert.Equal("11A97B", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "11A97B".ToHexBytes(); + JT808_0x0302 jT808_0X0302 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X0302.AnswerId); + Assert.Equal(4521, jT808_0X0302.ReplySNo); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0303Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0303Test.cs new file mode 100644 index 0000000..fd88b4d --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0303Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0303Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0303 jT808_0X0303 = new JT808_0x0303 + { + Flag = 123, + InformationType = 12 + }; + var hex = JT808Serializer.Serialize(jT808_0X0303).ToHexString(); + Assert.Equal("0C7B", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "0C7B".ToHexBytes(); + JT808_0x0303 jT808_0X0303 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X0303.Flag); + Assert.Equal(12, jT808_0X0303.InformationType); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0500Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0500Test.cs new file mode 100644 index 0000000..6c88a64 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0500Test.cs @@ -0,0 +1,74 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0500Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.车辆控制应答.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + } + }; + JT808_0x0500 jT808_0X0500 = new JT808_0x0500(); + JT808_0x0200 JT808_0x0200_1 = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + JT808_0x0200_1.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + JT808_0x0200_1.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + jT808_0X0500.JT808_0x0200 = JT808_0x0200_1; + jT808_0X0500.MsgNum = 1000; + jT808Package.Bodies = jT808_0X0500; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0500002811223344556622B803E8000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037B57E".Length, hex.Length); + Assert.Equal("7E0500002811223344556622B803E8000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037B57E", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "7E0500002811223344556622B803E8000000010000000200BA7F0E07E4F11C0028003C000018071510101001040000006402020037B57E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.车辆控制应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(8888, jT808Package.Header.MsgNum); + Assert.Equal("112233445566", jT808Package.Header.TerminalPhoneNo); + JT808_0x0500 JT808Bodies = (JT808_0x0500)jT808Package.Bodies; + Assert.Equal(1000, JT808Bodies.MsgNum); + Assert.Equal((uint)1, JT808Bodies.JT808_0x0200.AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), JT808Bodies.JT808_0x0200.GPSTime); + Assert.Equal(12222222, JT808Bodies.JT808_0x0200.Lat); + Assert.Equal(132444444, JT808Bodies.JT808_0x0200.Lng); + Assert.Equal(0, JT808Bodies.JT808_0x0200.Direction); + Assert.Equal(60, JT808Bodies.JT808_0x0200.Speed); + Assert.Equal((uint)2, JT808Bodies.JT808_0x0200.StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)JT808Bodies.JT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)JT808Bodies.JT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0701BodiesImpl/JT808_0x0701TestBodiesImpl.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0701BodiesImpl/JT808_0x0701TestBodiesImpl.cs new file mode 100644 index 0000000..0dccd65 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0701BodiesImpl/JT808_0x0701TestBodiesImpl.cs @@ -0,0 +1,16 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.MessageBody.JT808Formatters; + +namespace JT808.Protocol.Test.MessageBody.JT808_0x0701BodiesImpl +{ + [JT808Formatter(typeof(JT808_0x0701TestBodiesImplFormatter))] + public class JT808_0x0701TestBodiesImpl: JT808_0x0701_CustomBodyBase + { + public uint Id { get; set; } + + public ushort UserNameLength { get; set; } + + public string UserName { get; set; } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0701Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0701Test.cs new file mode 100644 index 0000000..ad9f176 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0701Test.cs @@ -0,0 +1,47 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.MessageBody.JT808_0x0701BodiesImpl; +using System.Reflection; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0701Test + { + JT808Serializer JT808Serializer; + + public JT808_0x0701Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + [Fact] + public void Test1() + { + JT808_0x0701 jT808_0X0701 = new JT808_0x0701(); + var body = new JT808_0x0701TestBodiesImpl + { + Id = 333, + UserName = "汉smallchi" + }; + jT808_0X0701.ElectronicContentObj = body; + var hex = JT808Serializer.Serialize(jT808_0X0701).ToHexString(); + Assert.Equal("000000100000014D000ABABA736D616C6C636869", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "000000100000014D000ABABA736D616C6C636869".ToHexBytes(); + JT808_0x0701 jT808_0X0701 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)16, jT808_0X0701.ElectronicWaybillLength); + JT808_0x0701TestBodiesImpl jT808_0X0701_content = JT808Serializer.Deserialize(jT808_0X0701.ElectronicContent); + Assert.Equal((uint)333, jT808_0X0701_content.Id); + Assert.Equal("汉smallchi", jT808_0X0701_content.UserName); + Assert.Equal(10, jT808_0X0701_content.UserNameLength); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0702Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0702Test.cs new file mode 100644 index 0000000..b824bfc --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0702Test.cs @@ -0,0 +1,88 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0702Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0702 jT808_0X0702 = new JT808_0x0702 + { + IC_Card_Status = JT808ICCardStatus.从业资格证IC卡拔出_驾驶员下班, + IC_Card_PlugDateTime = DateTime.Parse("2018-08-16 09:16:16") + }; + var hex = JT808Serializer.Serialize(jT808_0X0702).ToHexString(); + Assert.Equal("02 18 08 16 09 16 16".Replace(" ", ""), hex); + } + + [Fact] + public void Test1_2() + { + byte[] bytes = "02 18 08 16 09 16 16".ToHexBytes(); + JT808_0x0702 jT808_0X0702 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808ICCardStatus.从业资格证IC卡拔出_驾驶员下班, jT808_0X0702.IC_Card_Status); + Assert.Equal(DateTime.Parse("2018-08-16 09:16:16"), jT808_0X0702.IC_Card_PlugDateTime); + } + + [Fact] + public void Test2() + { + JT808_0x0702 jT808_0X0702 = new JT808_0x0702 + { + IC_Card_Status = JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班, + IC_Card_PlugDateTime = DateTime.Parse("2018-08-16 09:16:16"), + IC_Card_ReadResult = JT808ICCardReadResult.读卡失败_原因为卡片密钥认证未通过 + }; + var hex = JT808Serializer.Serialize(jT808_0X0702).ToHexString(); + Assert.Equal("01 18 08 16 09 16 16 01".Replace(" ", ""), hex); + } + + [Fact] + public void Test2_2() + { + byte[] bytes = "01 18 08 16 09 16 16 01".ToHexBytes(); + JT808_0x0702 jT808_0X0702 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班, jT808_0X0702.IC_Card_Status); + Assert.Equal(DateTime.Parse("2018-08-16 09:16:16"), jT808_0X0702.IC_Card_PlugDateTime); + Assert.Equal(JT808ICCardReadResult.读卡失败_原因为卡片密钥认证未通过, jT808_0X0702.IC_Card_ReadResult); + } + + [Fact] + public void Test3() + { + JT808_0x0702 jT808_0X0702 = new JT808_0x0702 + { + IC_Card_Status = JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班, + IC_Card_PlugDateTime = DateTime.Parse("2018-08-16 09:16:16"), + IC_Card_ReadResult = JT808ICCardReadResult.IC卡读卡成功, + DriverUserName = "koike", + QualificationCode = "qwe123456aaa", + LicenseIssuing = "qwertx", + CertificateExpiresDate = DateTime.Parse("2018-08-16") + }; + var hex = JT808Serializer.Serialize(jT808_0X0702).ToHexString(); + Assert.Equal("01 18 08 16 09 16 16 00 05 6B 6F 69 6B 65 71 77 65 31 32 33 34 35 36 61 61 61 30 30 30 30 30 30 30 30 06 71 77 65 72 74 78 07 E2 08 16".Replace(" ", ""), hex); + //"01 18 08 16 09 16 16 00 05 6B 6F 69 6B 65 71 77 65 31 32 33 34 35 36 61 61 61 30 30 30 30 30 30 30 30 06 71 77 65 72 74 78 07 E2 08 16" + } + + [Fact] + public void Test3_1() + { + byte[] bytes = "01 18 08 16 09 16 16 00 05 6B 6F 69 6B 65 71 77 65 31 32 33 34 35 36 61 61 61 30 30 30 30 30 30 30 30 06 71 77 65 72 74 78 07 E2 08 16".ToHexBytes(); + JT808_0x0702 jT808_0X0702 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班, jT808_0X0702.IC_Card_Status); + Assert.Equal(DateTime.Parse("2018-08-16 09:16:16"), jT808_0X0702.IC_Card_PlugDateTime); + Assert.Equal(JT808ICCardReadResult.IC卡读卡成功, jT808_0X0702.IC_Card_ReadResult); + Assert.Equal("koike", jT808_0X0702.DriverUserName); + Assert.Equal("qwe123456aaa00000000", jT808_0X0702.QualificationCode); + Assert.Equal("qwertx", jT808_0X0702.LicenseIssuing); + Assert.Equal(DateTime.Parse("2018-08-16"), jT808_0X0702.CertificateExpiresDate); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs new file mode 100644 index 0000000..a743808 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0704Test.cs @@ -0,0 +1,155 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0704Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.定位数据批量上传.ToUInt16Value(), + MsgNum = 8888, + TerminalPhoneNo = "112233445566", + } + }; + + JT808_0x0704 jT808_0X0704 = new JT808_0x0704 + { + Count = 2, + LocationType = JT808_0x0704.BatchLocationType.正常位置批量汇报 + }; + + JT808_0x0200 JT808_0x0200_1 = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-07-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + JT808_0x0200_1.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + JT808_0x0200_1.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 55 + }); + + List jT808_0X0200s = new List(); + jT808_0X0200s.Add(JT808_0x0200_1); + + JT808_0x0200 JT808_0x0200_2 = new JT808_0x0200 + { + AlarmFlag = 2, + Altitude = 41, + GPSTime = DateTime.Parse("2018-07-15 10:10:30"), + Lat = 13333333, + Lng = 132555555, + Speed = 54, + Direction = 120, + StatusFlag = 1, + JT808LocationAttachData = new Dictionary() + }; + JT808_0x0200_2.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 96 + }); + JT808_0x0200_2.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 66 + }); + jT808_0X0200s.Add(JT808_0x0200_2); + jT808_0X0704.Positions = jT808_0X0200s; + jT808Package.Bodies = jT808_0X0704; + //7E + //07 04 + //00 53 + //11 22 33 44 55 66 + //22 B8 + //00 02 + //00 + //00 26 + //00 00 00 01 + //00 00 00 02 + //00 BA 7F 0E + //07 E4 F1 1C + //00 28 + //00 3C + //00 00 + //18 07 15 10 10 10 + //01 + // 04 + // 00 00 00 64 + //02 + // 02 + // 00 37 + //00 26 + //00 00 00 02 + //00 00 00 01 + //00 CB 73 55 + //07 E6 A3 23 + //00 29 + //00 36 + //00 78 + //18 07 15 10 10 30 + //01 + // 04 + // 00 00 00 60 + //02 + // 02 + // 00 42 + //D4 + //7E + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E0704005311223344556622B80002000026000000010000000200BA7F0E07E4F11C0028003C0000180715101010010400000064020200370026000000020000000100CB735507E6A32300290036007818071510103001040000006002020042D47E", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "7E 07 04 00 53 11 22 33 44 55 66 22 B8 00 02 00 00 26 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 07 15 10 10 10 01 04 00 00 00 64 02 02 00 37 00 26 00 00 00 02 00 00 00 01 00 CB 73 55 07 E6 A3 23 00 29 00 36 00 78 18 07 15 10 10 30 01 04 00 00 00 60 02 02 00 42 D4 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.定位数据批量上传.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(8888, jT808Package.Header.MsgNum); + Assert.Equal("112233445566", jT808Package.Header.TerminalPhoneNo); + + JT808_0x0704 JT808Bodies = (JT808_0x0704)jT808Package.Bodies; + Assert.Equal(2, JT808Bodies.Count); + Assert.Equal(JT808_0x0704.BatchLocationType.正常位置批量汇报, JT808Bodies.LocationType); + + Assert.Equal((uint)1, JT808Bodies.Positions[0].AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:10"), JT808Bodies.Positions[0].GPSTime); + Assert.Equal(12222222, JT808Bodies.Positions[0].Lat); + Assert.Equal(132444444, JT808Bodies.Positions[0].Lng); + Assert.Equal(0, JT808Bodies.Positions[0].Direction); + Assert.Equal(60, JT808Bodies.Positions[0].Speed); + Assert.Equal((uint)2, JT808Bodies.Positions[0].StatusFlag); + Assert.Equal(100, ((JT808_0x0200_0x01)JT808Bodies.Positions[0].JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(55, ((JT808_0x0200_0x02)JT808Bodies.Positions[0].JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + + Assert.Equal((uint)2, JT808Bodies.Positions[1].AlarmFlag); + Assert.Equal(DateTime.Parse("2018-07-15 10:10:30"), JT808Bodies.Positions[1].GPSTime); + Assert.Equal(13333333, JT808Bodies.Positions[1].Lat); + Assert.Equal(132555555, JT808Bodies.Positions[1].Lng); + Assert.Equal(54, JT808Bodies.Positions[1].Speed); + Assert.Equal(120, JT808Bodies.Positions[1].Direction); + Assert.Equal((uint)1, JT808Bodies.Positions[1].StatusFlag); + Assert.Equal(96, ((JT808_0x0200_0x01)JT808Bodies.Positions[1].JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + Assert.Equal(66, ((JT808_0x0200_0x02)JT808Bodies.Positions[1].JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0705Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0705Test.cs new file mode 100644 index 0000000..5a5ac2f --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0705Test.cs @@ -0,0 +1,52 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0705Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0705 jT808_0X0705 = new JT808_0x0705 + { + FirstCanReceiveTime = DateTime.Parse("2018-11-15 20:00:05.350"), + CanItems = new List() + }; + jT808_0X0705.CanItems.Add(new JT808CanProperty() + { + CanId = new byte[] { 0x01, 0x02, 0x03, 0x04 }, + CanData = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }, + }); + jT808_0X0705.CanItems.Add(new JT808CanProperty() + { + CanId = new byte[] { 0x05, 0x06, 0x07, 0x08 }, + CanData = new byte[] { 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01 }, + }); + var hex = JT808Serializer.Serialize(jT808_0X0705).ToHexString(); + Assert.Equal("0002200005015E010203040102030401020304050607080103040506070801", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0002200005015E010203040102030401020304050607080103040506070801".ToHexBytes(); + JT808_0x0705 jT808_0X0705 = JT808Serializer.Deserialize(bytes); + + Assert.Equal(2, jT808_0X0705.CanItemCount); + + Assert.Equal(DateTime.Parse("20:00:05.350"), jT808_0X0705.FirstCanReceiveTime); + + Assert.Equal(new byte[] { 0x01, 0x02, 0x03, 0x04 }, jT808_0X0705.CanItems[0].CanId); + Assert.Equal(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }, jT808_0X0705.CanItems[0].CanData); + + Assert.Equal(new byte[] { 0x05, 0x06, 0x07, 0x08 }, jT808_0X0705.CanItems[1].CanId); + Assert.Equal(new byte[] { 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01 }, jT808_0X0705.CanItems[1].CanData); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0800Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0800Test.cs new file mode 100644 index 0000000..3b689b1 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0800Test.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0800Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0800 jT808_0X0800 = new JT808_0x0800 + { + MultimediaId = 5569, + MultimediaType = 0x01, + MultimediaCodingFormat = 0x02, + ChannelId = 0x06, + EventItemCoding = 0x01 + }; + var hex = JT808Serializer.Serialize(jT808_0X0800).ToHexString(); + Assert.Equal("000015C101020106", hex); + } + + [Fact] + public void Test2() + { + var bytes = "000015C101020106".ToHexBytes(); + JT808_0x0800 jT808_0X0800 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)5569, jT808_0X0800.MultimediaId); + Assert.Equal(0x01, jT808_0X0800.MultimediaType); + Assert.Equal(0x02, jT808_0X0800.MultimediaCodingFormat); + Assert.Equal(0x06, jT808_0X0800.ChannelId); + Assert.Equal(0x01, jT808_0X0800.EventItemCoding); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0801Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0801Test.cs new file mode 100644 index 0000000..0a97c64 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0801Test.cs @@ -0,0 +1,95 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using System; +using System.Reflection; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0801Test + { + JT808Serializer JT808Serializer; + + public JT808_0x0801Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + jT808Config.SkipCRCCode = true; + JT808Serializer = new JT808Serializer(jT808Config); + } + + [Fact] + public void Test1() + { + JT808_0x0801 jT808_0X0801 = new JT808_0x0801 + { + ChannelId = 123, + EventItemCoding = JT808EventItemCoding.定时动作.ToByteValue(), + MultimediaCodingFormat = JT808MultimediaCodingFormat.JPEG.ToByteValue(), + MultimediaId = 2567, + MultimediaType = JT808MultimediaType.图像.ToByteValue(), + MultimediaDataPackage = new byte[] { 0x01, 0x02, 0x03, 0x04 }, + Position = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-11-15 23:26:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2 + } + }; + string hex = JT808Serializer.Serialize(jT808_0X0801).ToHexString(); + Assert.Equal("00000A070000017B000000010000000200BA7F0E07E4F11C0028003C000018111523261001020304", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00000A070000017B000000010000000200BA7F0E07E4F11C0028003C000018111523261001020304".ToHexBytes(); + JT808_0x0801 jT808_0X0801 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X0801.ChannelId); + Assert.Equal(JT808EventItemCoding.定时动作.ToByteValue(), jT808_0X0801.EventItemCoding); + Assert.Equal(JT808MultimediaCodingFormat.JPEG.ToByteValue(), jT808_0X0801.MultimediaCodingFormat); + Assert.Equal((uint)2567, jT808_0X0801.MultimediaId); + Assert.Equal(JT808MultimediaType.图像.ToByteValue(), jT808_0X0801.MultimediaType); + Assert.Equal(new byte[] { 0x01, 0x02, 0x03, 0x04 }, jT808_0X0801.MultimediaDataPackage); + Assert.Equal((uint)1, jT808_0X0801.Position.AlarmFlag); + Assert.Equal(40, jT808_0X0801.Position.Altitude); + Assert.Equal(DateTime.Parse("2018-11-15 23:26:10"), jT808_0X0801.Position.GPSTime); + Assert.Equal(40, jT808_0X0801.Position.Altitude); + Assert.Equal(12222222, jT808_0X0801.Position.Lat); + Assert.Equal(132444444, jT808_0X0801.Position.Lng); + Assert.Equal(60, jT808_0X0801.Position.Speed); + Assert.Equal(0, jT808_0X0801.Position.Direction); + Assert.Equal((uint)2, jT808_0X0801.Position.StatusFlag); + } + + [Fact] + public void Package1() + { + byte[] bytes = "7e080123240138123456782031000a00010000271d0000010100000000000c200301d2400a063296a501e100000000190104092952ffd8ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232fffe000b4750456e636f646572ffdb0043000d090a0b0a080d0b0a0b0e0e0d0f13201513121213271c1e17202e2931302e292d2c333a4a3e333646372c2d405741464c4e525352323e5a615a50604a51524fffdb0043010e0e0e131113261515264f352d354f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4fffc000110800f0014003012100021101031101ffc4001f000001050101010101010000000000000000010203041c7e".ToHexBytes(); + JT808Package jT808_0X0801 = JT808Serializer.Deserialize(bytes); + } + + [Fact] + public void Package2() + { + byte[] bytes = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); + JT808Package jT808_0X0801 = JT808Serializer.Deserialize(bytes); + } + + [Fact] + public void Package3() + { + byte[] bytes = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); + JT808HeaderPackage jT808_0X0801 = JT808Serializer.Deserialize(bytes); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0802Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0802Test.cs new file mode 100644 index 0000000..672214e --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0802Test.cs @@ -0,0 +1,103 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0802Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0802 jT808_0X0802 = new JT808_0x0802 + { + MsgNum = 12369, + MultimediaSearchItems = new List() + }; + + jT808_0X0802.MultimediaSearchItems.Add(new JT808MultimediaSearchProperty() + { + ChannelId = 123, + EventItemCoding = JT808EventItemCoding.定时动作.ToByteValue(), + MultimediaId = 258, + MultimediaType = JT808MultimediaType.图像.ToByteValue(), + Position = new JT808_0x0200() + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-11-16 20:20:20"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + } + }); + + jT808_0X0802.MultimediaSearchItems.Add(new JT808MultimediaSearchProperty() + { + ChannelId = 124, + EventItemCoding = JT808EventItemCoding.平台下发指令.ToByteValue(), + MultimediaId = 259, + MultimediaType = JT808MultimediaType.视频.ToByteValue(), + Position = new JT808_0x0200() + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-11-16 22:22:22"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + } + }); + + string hex = JT808Serializer.Serialize(jT808_0X0802).ToHexString(); + Assert.Equal("3051000200000102007B01000000010000000200BA7F0E07E4F11C0028003C000018111620202000000103027C00000000010000000200BA7F0E07E4F11C0028003C0000181116222222", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "3051000200000102007B01000000010000000200BA7F0E07E4F11C0028003C000018111620202000000103027C00000000010000000200BA7F0E07E4F11C0028003C0000181116222222".ToHexBytes(); + JT808_0x0802 jT808_0X0802 = JT808Serializer.Deserialize(bytes); + Assert.Equal(12369, jT808_0X0802.MsgNum); + Assert.Equal(2, jT808_0X0802.MultimediaItemCount); + + + Assert.Equal(123, jT808_0X0802.MultimediaSearchItems[0].ChannelId); + Assert.Equal(JT808EventItemCoding.定时动作.ToByteValue(), jT808_0X0802.MultimediaSearchItems[0].EventItemCoding); + Assert.Equal(JT808MultimediaType.图像.ToByteValue(), jT808_0X0802.MultimediaSearchItems[0].MultimediaType); + Assert.Equal((uint)258, jT808_0X0802.MultimediaSearchItems[0].MultimediaId); + + Assert.Equal((uint)1, jT808_0X0802.MultimediaSearchItems[0].Position.AlarmFlag); + Assert.Equal((ushort)40, jT808_0X0802.MultimediaSearchItems[0].Position.Altitude); + Assert.Equal(DateTime.Parse("2018-11-16 20:20:20"), jT808_0X0802.MultimediaSearchItems[0].Position.GPSTime); + Assert.Equal(12222222, jT808_0X0802.MultimediaSearchItems[0].Position.Lat); + Assert.Equal(132444444, jT808_0X0802.MultimediaSearchItems[0].Position.Lng); + Assert.Equal((ushort)60, jT808_0X0802.MultimediaSearchItems[0].Position.Speed); + Assert.Equal((ushort)0, jT808_0X0802.MultimediaSearchItems[0].Position.Direction); + Assert.Equal((uint)2, jT808_0X0802.MultimediaSearchItems[0].Position.StatusFlag); + + Assert.Equal(124, jT808_0X0802.MultimediaSearchItems[1].ChannelId); + Assert.Equal(JT808EventItemCoding.平台下发指令.ToByteValue(), jT808_0X0802.MultimediaSearchItems[1].EventItemCoding); + Assert.Equal(JT808MultimediaType.视频.ToByteValue(), jT808_0X0802.MultimediaSearchItems[1].MultimediaType); + Assert.Equal((uint)259, jT808_0X0802.MultimediaSearchItems[1].MultimediaId); + + Assert.Equal((uint)1, jT808_0X0802.MultimediaSearchItems[1].Position.AlarmFlag); + Assert.Equal((ushort)40, jT808_0X0802.MultimediaSearchItems[1].Position.Altitude); + Assert.Equal(DateTime.Parse("2018-11-16 22:22:22"), jT808_0X0802.MultimediaSearchItems[1].Position.GPSTime); + Assert.Equal(12222222, jT808_0X0802.MultimediaSearchItems[1].Position.Lat); + Assert.Equal(132444444, jT808_0X0802.MultimediaSearchItems[1].Position.Lng); + Assert.Equal((ushort)60, jT808_0X0802.MultimediaSearchItems[1].Position.Speed); + Assert.Equal((ushort)0, jT808_0X0802.MultimediaSearchItems[1].Position.Direction); + Assert.Equal((uint)2, jT808_0X0802.MultimediaSearchItems[1].Position.StatusFlag); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0805Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0805Test.cs new file mode 100644 index 0000000..10cd73a --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0805Test.cs @@ -0,0 +1,41 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0805Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x0805 jT808_0X0805 = new JT808_0x0805(); + jT808_0X0805.MsgNum = 12456; + jT808_0X0805.Result = 1; + jT808_0X0805.MultimediaIds = new List() + { + 12306, + 12580 + }; + string hex = JT808Serializer.Serialize(jT808_0X0805).ToHexString(); + Assert.Equal("30A80100020000301200003124", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "30A80100020000301200003124".ToHexBytes(); + JT808_0x0805 jT808_0X0805 = JT808Serializer.Deserialize(bytes); + Assert.Equal(12456, jT808_0X0805.MsgNum); + Assert.Equal(1, jT808_0X0805.Result); + Assert.Equal(2, jT808_0X0805.MultimediaIdCount); + Assert.Equal(new List() + { + 12306, + 12580 + }, jT808_0X0805.MultimediaIds); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0900Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0900Test.cs new file mode 100644 index 0000000..57e1d24 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0900Test.cs @@ -0,0 +1,57 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.JT808_0x0900_BodiesImpl; +using System.Reflection; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0900Test + { + JT808Serializer JT808Serializer; + + public JT808_0x0900Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + + JT808Serializer = new JT808Serializer(jT808Config); + } + [Fact] + public void Test1() + { + JT808Package jT808_0X0900 = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.数据上行透传.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "123456789", + }, + Bodies = new JT808_0x0900 + { + JT808_0x0900_BodyBase = new JT808_0x0900_0x83() { PassthroughContent = "smallchi" }, + PassthroughType = 0x83 + } + }; + var hex = JT808Serializer.Serialize(jT808_0X0900).ToHexString(); + Assert.Equal("7E09000009000123456789000A83736D616C6C6368691D7E", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "7E 09 00 00 09 00 01 23 45 67 89 00 0A 83 73 6D 61 6C 6C 63 68 69 1D 7E".ToHexBytes(); + JT808Package jT808_0X0900 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.数据上行透传.ToUInt16Value(), jT808_0X0900.Header.MsgId); + Assert.Equal(10, jT808_0X0900.Header.MsgNum); + Assert.Equal("123456789", jT808_0X0900.Header.TerminalPhoneNo); + JT808_0x0900 JT808Bodies = (JT808_0x0900)jT808_0X0900.Bodies; + JT808_0x0900_0x83 jT808_0x0900_0x83 = JT808Serializer.Deserialize(JT808Bodies.PassthroughData); + Assert.Equal("smallchi", jT808_0x0900_0x83.PassthroughContent); + Assert.Equal(0x83, JT808Bodies.PassthroughType); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0900_BodiesImpl/JT808_0x0900_0x83.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0900_BodiesImpl/JT808_0x0900_0x83.cs new file mode 100644 index 0000000..d790946 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0900_BodiesImpl/JT808_0x0900_0x83.cs @@ -0,0 +1,15 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.MessageBody.JT808Formatters; + +namespace JT808.Protocol.Test.JT808_0x0900_BodiesImpl +{ + [JT808Formatter(typeof(JT808_0x0900_0x83Formatter))] + public class JT808_0x0900_0x83 : JT808_0x0900_BodyBase + { + /// + /// 透传内容 + /// + public string PassthroughContent { get; set; } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0901Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0901Test.cs new file mode 100644 index 0000000..cfe1a2f --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0901Test.cs @@ -0,0 +1,41 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Runtime.InteropServices; +using System.Text; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0901Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + const string UserName = "smallchismallchismallchismallchismallchismallchismallchismallchismallchismallchismallchi"; + + [Fact] + public void Test1() + { + JT808_0x0901 jT808_0X0901 = new JT808_0x0901(); + var data = Encoding.UTF8.GetBytes(UserName); + jT808_0X0901.UnCompressMessage = data; + var hex = JT808Serializer.Serialize(jT808_0X0901).ToHexString(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Assert.Equal("0000001F1F8B08000000000000032BCE4DCCC949CEC82CA6320D0027F897E258000000", hex); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Equal("0000001F1F8B080000000000000B2BCE4DCCC949CEC82CA6320D0027F897E258000000", hex); + } + + } + + [Fact] + public void Test2() + { + byte[] bytes = "0000001F1F8B080000000000000B2BCE4DCCC949CEC82CA6320D0027F897E258000000".ToHexBytes(); + JT808_0x0901 jT808_0X8600 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)88, jT808_0X8600.UnCompressMessageLength); + Assert.Equal(Encoding.UTF8.GetBytes(UserName), jT808_0X8600.UnCompressMessage); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0A00Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0A00Test.cs new file mode 100644 index 0000000..8a26a4e --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0A00Test.cs @@ -0,0 +1,40 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Linq; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x0A00Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + byte[] N; + public JT808_0x0A00Test() + { + + N = Enumerable.Range(0, 128).Select(s => Convert.ToByte(s)).ToArray(); + } + + [Fact] + public void Test1() + { + JT808_0x0A00 jT808_0X0A00 = new JT808_0x0A00 + { + E = 128, + N = N + }; + string hex = JT808Serializer.Serialize(jT808_0X0A00).ToHexString(); + Assert.Equal("00000080000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00000080000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F".ToHexBytes(); + JT808_0x0A00 jT808_0X0A00 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)128, jT808_0X0A00.E); + Assert.Equal(N, jT808_0X0A00.N); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8001Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8001Test.cs new file mode 100644 index 0000000..d70e843 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8001Test.cs @@ -0,0 +1,57 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8001Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.平台通用应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "12345678900", + }, + Bodies = new JT808_0x8001 + { + MsgId = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), + JT808PlatformResult = Enums.JT808PlatformResult.成功, + MsgNum = 100 + } + }; + //"7E + //80 01 + //00 05 + //01 23 45 67 89 00 + //00 0A + //00 64 + //02 00 + //00 + //61 + //7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E80010005012345678900000A0064020000617E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E 80 01 00 05 01 23 45 67 89 00 00 0A 00 64 02 00 00 61 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.平台通用应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(10, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + JT808_0x8001 JT808Bodies = (JT808_0x8001)jT808Package.Bodies; + Assert.Equal(Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), JT808Bodies.MsgId); + Assert.Equal(100, JT808Bodies.MsgNum); + Assert.Equal(Enums.JT808PlatformResult.成功, JT808Bodies.JT808PlatformResult); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8003Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8003Test.cs new file mode 100644 index 0000000..ef5a8d8 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8003Test.cs @@ -0,0 +1,33 @@ +using System.Text; +using Xunit; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8003Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8003 jT808_0X8003 = new JT808_0x8003 + { + OriginalMsgNum = 1234, + AgainPackageData = new byte[] { 0x01, 0x02, 0x02, 0x03 } + }; + var hex = JT808Serializer.Serialize(jT808_0X8003).ToHexString(); + Assert.Equal("04D20201020203", hex); + } + + [Fact] + public void Test2() + { + var bytes = "04D20201020203".ToHexBytes(); + JT808_0x8003 jT808_0X8003 = JT808Serializer.Deserialize(bytes); + Assert.Equal(1234, jT808_0X8003.OriginalMsgNum); + Assert.Equal(new byte[] { 0x01, 0x02, 0x02, 0x03 }, jT808_0X8003.AgainPackageData); + Assert.Equal(2, jT808_0X8003.AgainPackageCount); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8100Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8100Test.cs new file mode 100644 index 0000000..ee84b62 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8100Test.cs @@ -0,0 +1,142 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8100Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端注册应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "012345678900", + }, + Bodies = new JT808_0x8100 + { + Code = "123456", + JT808TerminalRegisterResult = Enums.JT808TerminalRegisterResult.成功, + MsgNum = 100 + } + }; + //"7E + //81 00 + //00 09 + //01 23 45 67 89 00 + //00 0A + //00 64 + //00 + //31 32 33 34 35 36 + //68 + //7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E81000009012345678900000A006400313233343536687E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E 81 00 00 09 01 23 45 67 89 00 00 0A 00 64 00 31 32 33 34 35 36 68 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端注册应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(10, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + JT808_0x8100 JT808Bodies = (JT808_0x8100)jT808Package.Bodies; + Assert.Equal("123456", JT808Bodies.Code); + Assert.Equal(100, JT808Bodies.MsgNum); + Assert.Equal(Enums.JT808TerminalRegisterResult.成功, JT808Bodies.JT808TerminalRegisterResult); + } + + [Fact] + public void Test3() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端注册应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "12345678900", + }, + Bodies = new JT808_0x8100 + { + Code = "123456", + JT808TerminalRegisterResult = Enums.JT808TerminalRegisterResult.数据库中无该终端, + MsgNum = 100 + } + }; + //"7E + //81 00 + //00 03 + //01 23 45 67 89 00 + //00 0A + //00 64 + //04 + //61 + //7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E81000003012345678900000A006404617E", hex); + } + + [Fact] + public void Test4() + { + var bytes = "7E 81 00 00 03 01 23 45 67 89 00 00 0A 00 64 04 61 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端注册应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(10, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + JT808_0x8100 JT808Bodies = (JT808_0x8100)jT808Package.Bodies; + Assert.Null(JT808Bodies.Code); + Assert.Equal(100, JT808Bodies.MsgNum); + Assert.Equal(Enums.JT808TerminalRegisterResult.数据库中无该终端, JT808Bodies.JT808TerminalRegisterResult); + } + + + [Fact] + public void Test5() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端注册应答.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "12345678900", + }, + Bodies = new JT808_0x8100 + { + Code = "zssdaf23124sfdsc", + JT808TerminalRegisterResult = Enums.JT808TerminalRegisterResult.成功, + MsgNum = 100 + } + }; + //"7E 81 00 00 13 01 23 45 67 89 00 00 0A 00 64 00 7A 73 73 64 61 66 32 33 31 32 34 73 66 64 73 63 3B 7E" + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E81000013012345678900000A0064007A7373646166323331323473666473633B7E", hex); + } + + [Fact] + public void Test6() + { + var bytes = "7E 81 00 00 13 01 23 45 67 89 00 00 0A 00 64 00 7A 73 73 64 61 66 32 33 31 32 34 73 66 64 73 63 3B 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端注册应答.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(10, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + JT808_0x8100 JT808Bodies = (JT808_0x8100)jT808Package.Bodies; + Assert.Equal("zssdaf23124sfdsc", JT808Bodies.Code); + Assert.Equal(100, JT808Bodies.MsgNum); + Assert.Equal(Enums.JT808TerminalRegisterResult.成功, JT808Bodies.JT808TerminalRegisterResult); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8103Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8103Test.cs new file mode 100644 index 0000000..a04d775 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8103Test.cs @@ -0,0 +1,126 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using System.Reflection; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8103Test + { + JT808Serializer JT808Serializer; + + public JT808_0x8103Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.设置终端参数.ToUInt16Value(), + MsgNum = 10, + TerminalPhoneNo = "123456789", + }, + Bodies = new JT808_0x8103 + { + ParamList = new List { + new JT808_0x8103_0x0001() { + ParamId=0x0001, + ParamLength=4, + ParamValue=10 + } + } + } + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E8103000A000123456789000A0100000001040000000A057E", hex); + } + + [Fact] + public void Test1_1() + { + //7E + //81 03 + //00 0A + //00 + //01 23 45 67 89 00 + //0A 01 + //00 00 00 01 + //04 + // 00 00 00 0A + //05 + //7E + + byte[] bytes = "7E8103000A000123456789000A0100000001040000000A057E".ToHexBytes(); + JT808Package jT808_0X8103 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.设置终端参数.ToUInt16Value(), jT808_0X8103.Header.MsgId); + Assert.Equal(10, jT808_0X8103.Header.MsgNum); + Assert.Equal("123456789", jT808_0X8103.Header.TerminalPhoneNo); + + JT808_0x8103 JT808Bodies = (JT808_0x8103)jT808_0X8103.Bodies; + foreach (var item in JT808Bodies.ParamList) + { + Assert.Equal(0x0001u, ((JT808_0x8103_0x0001)item).ParamId); + Assert.Equal(4, ((JT808_0x8103_0x0001)item).ParamLength); + Assert.Equal(10u, ((JT808_0x8103_0x0001)item).ParamValue); + } + } + + + [Fact] + public void Test2() + { + var JT808_0x8103 = new JT808_0x8103 + { + ParamList = new List { + new JT808_0x8103_0x0001() { + ParamId=0x0001, + ParamLength=4, + ParamValue=10 + }, + new JT808_0x8103_0x0013(){ + ParamId=0x0013, + ParamValue="www.baidu.com" + } + } + }; + var hex = JT808Serializer.Serialize(JT808_0x8103).ToHexString(); + //"0200000001040000000A000000130D7777772E62616964752E636F6D" + Assert.Equal("0200000001040000000A000000130D7777772E62616964752E636F6D", hex); + } + + [Fact] + public void Test2_1() + { + byte[] bytes = "0200000001040000000A000000130D7777772E62616964752E636F6D".ToHexBytes(); + JT808_0x8103 jT808_0X8103 = JT808Serializer.Deserialize(bytes); + + foreach (var item in jT808_0X8103.ParamList) + { + switch (item.ParamId) + { + case 0x0001: + Assert.Equal(0x0001u, ((JT808_0x8103_0x0001)item).ParamId); + Assert.Equal(4, ((JT808_0x8103_0x0001)item).ParamLength); + Assert.Equal(10u, ((JT808_0x8103_0x0001)item).ParamValue); + break; + case 0x0013: + Assert.Equal(0x0013u, ((JT808_0x8103_0x0013)item).ParamId); + Assert.Equal("www.baidu.com", ((JT808_0x8103_0x0013)item).ParamValue); + break; + default: + break; + } + + } + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8104Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8104Test.cs new file mode 100644 index 0000000..96cb97d --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8104Test.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8104Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.查询终端参数.ToUInt16Value(), + MsgNum = 1, + TerminalPhoneNo = "12345678900", + } + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E8104000001234567890000010D7E", hex); + } + + [Fact] + public void Test2() + { + var bytes = "7E8104000001234567890000010D7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.查询终端参数.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(1, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + Assert.Null(jT808Package.Bodies); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8105Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8105Test.cs new file mode 100644 index 0000000..6970fde --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8105Test.cs @@ -0,0 +1,105 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8105Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端控制.ToUInt16Value(), + MsgNum = 1, + TerminalPhoneNo = "12345678900", + }, + Bodies = new JT808_0x8105 + { + CommandWord = 1, + CommandValue = new CommandParams + { + ConnectionControl = 1, + DialPointName = "TKName", + DialUserName = "TK", + DialPwd = "TK123", + FirmwareVersion = "1.0", + HardwareVersion = "2.0", + ConnectTimeLimit = 60, + ManufacturerCode = 12345, + MonitoringPlatformAuthenticationCode = "code", + ServerUrl = "www.baidu.com", + TCPPort = 8806, + UDPPort = 3306, + URL = "www.TK.com" + } + } + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E8105004B012345678900000101313B544B4E616D653B544B3B544B3132333B7777772E62616964752E636F6D3B383830363B333330363B31323334353B636F64653B322E303B312E303B7777772E544B2E636F6D3B3630227E", hex); + } + + [Fact] + public void Test1_1() + { + var bytes = "7E8105004B012345678900000101313B544B4E616D653B544B3B544B3132333B7777772E62616964752E636F6D3B383830363B333330363B31323334353B636F64653B322E303B312E303B7777772E544B2E636F6D3B3630227E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端控制.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(1, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + var JT808_0x8105 = (JT808_0x8105)jT808Package.Bodies; + Assert.Equal(1, JT808_0x8105.CommandWord); + Assert.Equal("www.TK.com", JT808_0x8105.CommandValue.URL); + Assert.Equal(3306, (int)JT808_0x8105.CommandValue.UDPPort); + Assert.Equal(8806, (int)JT808_0x8105.CommandValue.TCPPort); + Assert.Equal("www.baidu.com", JT808_0x8105.CommandValue.ServerUrl); + Assert.Equal("code", JT808_0x8105.CommandValue.MonitoringPlatformAuthenticationCode); + Assert.Equal(12345, JT808_0x8105.CommandValue.ManufacturerCode); + Assert.Equal("2.0", JT808_0x8105.CommandValue.HardwareVersion); + Assert.Equal("1.0", JT808_0x8105.CommandValue.FirmwareVersion); + Assert.Equal("TK", JT808_0x8105.CommandValue.DialUserName); + Assert.Equal("TK123", JT808_0x8105.CommandValue.DialPwd); + Assert.Equal("TKName", JT808_0x8105.CommandValue.DialPointName); + Assert.Equal(1, (byte)JT808_0x8105.CommandValue.ConnectionControl); + Assert.Equal(60, (UInt16)JT808_0x8105.CommandValue.ConnectTimeLimit); + } + + + [Fact] + public void Test2() + { + JT808Package jT808Package = new JT808Package(); + jT808Package.Header = new JT808Header + { + MsgId = Enums.JT808MsgId.终端控制.ToUInt16Value(), + MsgNum = 1, + TerminalPhoneNo = "12345678900", + }; + jT808Package.Bodies = new JT808_0x8105 + { + CommandWord = 5 + }; + var hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E81050001012345678900000105087E", hex); + } + + [Fact] + public void Test2_1() + { + var bytes = "7E81050001012345678900000105087E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MsgId.终端控制.ToUInt16Value(), jT808Package.Header.MsgId); + Assert.Equal(1, jT808Package.Header.MsgNum); + Assert.Equal("12345678900", jT808Package.Header.TerminalPhoneNo); + + var JT808_0x8105 = (JT808_0x8105)jT808Package.Bodies; + Assert.Equal(5, JT808_0x8105.CommandWord); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8106Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8106Test.cs new file mode 100644 index 0000000..d4f87a2 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8106Test.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8106Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8106 jT808_0X8106 = new JT808_0x8106 + { + ParameterCount = 2, + Parameters = new uint[] { 0x0001, 0x0002 } + }; + + string hex = JT808Serializer.Serialize(jT808_0X8106).ToHexString(); + Assert.Equal("020000000100000002", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "020000000100000002".ToHexBytes(); + JT808_0x8106 jT808_0X8106 = JT808Serializer.Deserialize(bytes); + Assert.Equal(2, jT808_0X8106.ParameterCount); + Assert.Equal(new uint[] { 0x0001, 0x0002 }, jT808_0X8106.Parameters); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8108Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8108Test.cs new file mode 100644 index 0000000..de24c54 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8108Test.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8108Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8108 jT808_0X8108 = new JT808_0x8108 + { + UpgradeType = JT808UpgradeType.北斗卫星定位模块, + MakerId = "asdfg", + VersionNum = "qscvhiuytrew", + UpgradePackage = new byte[] { 1, 2, 3, 4, 5 } + }; + //"34 61 73 64 66 67 0C 71 73 63 76 68 69 75 79 74 72 65 77 00 00 00 05 01 02 03 04 05" + string hex = JT808Serializer.Serialize(jT808_0X8108).ToHexString(); + Assert.Equal("3461736466670C717363766869757974726577000000050102030405", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "34 61 73 64 66 67 0C 71 73 63 76 68 69 75 79 74 72 65 77 00 00 00 05 01 02 03 04 05".ToHexBytes(); + JT808_0x8108 jT808_0X8108 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808UpgradeType.北斗卫星定位模块, jT808_0X8108.UpgradeType); + Assert.Equal("asdfg", jT808_0X8108.MakerId); + Assert.Equal("qscvhiuytrew", jT808_0X8108.VersionNum); + Assert.Equal(new byte[] { 1, 2, 3, 4, 5 }, jT808_0X8108.UpgradePackage); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8202Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8202Test.cs new file mode 100644 index 0000000..4482103 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8202Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8202Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8202 jT808_0X8202 = new JT808_0x8202 + { + Interval = 69, + LocationTrackingValidity = 123 + }; + string hex = JT808Serializer.Serialize(jT808_0X8202).ToHexString(); + Assert.Equal("00450000007B", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00 45 00 00 00 7B".ToHexBytes(); + JT808_0x8202 jT808_0X8108 = JT808Serializer.Deserialize(bytes); + Assert.Equal(69, jT808_0X8108.Interval); + Assert.Equal(123, jT808_0X8108.LocationTrackingValidity); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8203Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8203Test.cs new file mode 100644 index 0000000..aff2b6d --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8203Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8203Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8203 jT808_0X8203 = new JT808_0x8203 + { + AlarmMsgNum = 5554, + ManualConfirmAlarmType = 123 + }; + string hex = JT808Serializer.Serialize(jT808_0X8203).ToHexString(); + Assert.Equal("15B20000007B", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "15B20000007B".ToHexBytes(); + JT808_0x8203 jT808_0X8203 = JT808Serializer.Deserialize(bytes); + Assert.Equal(5554, jT808_0X8203.AlarmMsgNum); + Assert.Equal((uint)123, jT808_0X8203.ManualConfirmAlarmType); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8300Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8300Test.cs new file mode 100644 index 0000000..9fe8a26 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8300Test.cs @@ -0,0 +1,43 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8300Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + //"7E 83 00 00 0D 01 23 45 67 89 00 00 01 05 73 6D 61 6C 6C 63 68 69 20 35 31 38 02 7E" + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = Enums.JT808MsgId.文本信息下发.ToUInt16Value(), + MsgNum = 1, + TerminalPhoneNo = "012345678900", + } + }; + JT808_0x8300 jT808TextSend = new JT808_0x8300 + { + TextInfo = "smallchi 518", + TextFlag = 5 + }; + jT808Package.Bodies = jT808TextSend; + string hex = JT808Serializer.Serialize(jT808Package).ToHexString(); + Assert.Equal("7E8300000D012345678900000105736D616C6C63686920353138027E", hex); + } + + [Fact] + public void Test1_2() + { + byte[] bytes = "7E 83 00 00 0D 01 23 45 67 89 00 00 01 05 73 6D 61 6C 6C 63 68 69 20 35 31 38 02 7E".ToHexBytes(); + JT808Package jT808Package = JT808Serializer.Deserialize(bytes); + JT808_0x8300 jT808TextSend = (JT808_0x8300)jT808Package.Bodies; + Assert.Equal("smallchi 518", jT808TextSend.TextInfo); + Assert.Equal(5, jT808TextSend.TextFlag); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8301Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8301Test.cs new file mode 100644 index 0000000..50feb44 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8301Test.cs @@ -0,0 +1,52 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8301Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8301 jT808_0X8301 = new JT808_0x8301 + { + SettingType = JT808EventSettingType.删除终端现有所有事件_该命令后不带后继字节.ToByteValue(), + EventItems = new List() + }; + jT808_0X8301.EventItems.Add(new JT808EventProperty + { + EventId=1, + EventContent="123456" + }); + jT808_0X8301.EventItems.Add(new JT808EventProperty + { + EventId = 2, + EventContent = "789456" + }); + + var hex = JT808Serializer.Serialize(jT808_0X8301).ToHexString(); + Assert.Equal("000201063132333435360206373839343536", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "000201063132333435360206373839343536".ToHexBytes(); + JT808_0x8301 jT808_0X8301 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808EventSettingType.删除终端现有所有事件_该命令后不带后继字节.ToByteValue(), jT808_0X8301.SettingType); + Assert.Equal(2, jT808_0X8301.SettingCount); + + Assert.Equal(1, jT808_0X8301.EventItems[0].EventId); + Assert.Equal(6, jT808_0X8301.EventItems[0].EventContentLength); + Assert.Equal("123456", jT808_0X8301.EventItems[0].EventContent); + Assert.Equal(2, jT808_0X8301.EventItems[1].EventId); + Assert.Equal(6, jT808_0X8301.EventItems[1].EventContentLength); + Assert.Equal("789456", jT808_0X8301.EventItems[1].EventContent); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8302Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8302Test.cs new file mode 100644 index 0000000..e9f4990 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8302Test.cs @@ -0,0 +1,45 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8302Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8302 jT808_0X8302 = new JT808_0x8302 + { + AnswerId = 128, + AnswerContent = "123456", + Flag = 1, + Issue = "sdddaff" + }; + var hex = JT808Serializer.Serialize(jT808_0X8302).ToHexString(); + //01 + //07 + //73 64 64 64 61 66 66 + //80 + //06 00 + //31 32 33 34 35 36 + //010006646464616666800000313233343536 + //010773646464616666800006313233343536 + Assert.Equal("010773646464616666800006313233343536", hex); + } + + [Fact] + public void Test1_1() + { + byte[] bytes = "010773646464616666800006313233343536".ToHexBytes(); + JT808_0x8302 jT808_0X8302 = JT808Serializer.Deserialize(bytes); + Assert.Equal(128, jT808_0X8302.AnswerId); + Assert.Equal("123456", jT808_0X8302.AnswerContent); + Assert.Equal(1, jT808_0X8302.Flag); + Assert.Equal("sdddaff", jT808_0X8302.Issue); + Assert.Equal(6, jT808_0X8302.AnswerContentLength); + Assert.Equal(7, jT808_0X8302.IssueContentLength); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8303Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8303Test.cs new file mode 100644 index 0000000..34bd866 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8303Test.cs @@ -0,0 +1,51 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8303Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8303 jT808_0X8303 = new JT808_0x8303 + { + SettingType = JT808InformationSettingType.删除终端全部信息项.ToByteValue(), + InformationItems = new List() + }; + jT808_0X8303.InformationItems.Add(new JT808InformationItemProperty + { + InformationType=11, + InformationName="smallchi1" + }); + jT808_0X8303.InformationItems.Add(new JT808InformationItemProperty + { + InformationType = 22, + InformationName = "smallchi2" + }); + var hex = JT808Serializer.Serialize(jT808_0X8303).ToHexString(); + Assert.Equal("00020B0009736D616C6C63686931160009736D616C6C63686932", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00020B0009736D616C6C63686931160009736D616C6C63686932".ToHexBytes(); + JT808_0x8303 jT808_0X8303 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808InformationSettingType.删除终端全部信息项.ToByteValue(), jT808_0X8303.SettingType); + + Assert.Equal(11, jT808_0X8303.InformationItems[0].InformationType); + Assert.Equal("smallchi1", jT808_0X8303.InformationItems[0].InformationName); + Assert.Equal(9, jT808_0X8303.InformationItems[0].InformationLength); + + Assert.Equal(22, jT808_0X8303.InformationItems[1].InformationType); + Assert.Equal("smallchi2", jT808_0X8303.InformationItems[1].InformationName); + Assert.Equal(9, jT808_0X8303.InformationItems[1].InformationLength); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8304Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8304Test.cs new file mode 100644 index 0000000..1c6d616 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8304Test.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8304Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8304 jT808_0X8304 = new JT808_0x8304 + { + InformationType = 123, + InformationContent = "信息内容" + }; + var hex = JT808Serializer.Serialize(jT808_0X8304).ToHexString(); + Assert.Equal("7B0008D0C5CFA2C4DAC8DD", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "7B0008D0C5CFA2C4DAC8DD".ToHexBytes(); + JT808_0x8304 jT808_0X8304 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X8304.InformationType); + Assert.Equal("信息内容", jT808_0X8304.InformationContent); + Assert.Equal(8, jT808_0X8304.InformationLength); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8400Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8400Test.cs new file mode 100644 index 0000000..cab7b55 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8400Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8400Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8400 jT808_0X8400 = new JT808_0x8400 + { + CallBack = Enums.JT808CallBackType.普通通话, + PhoneNumber = "12345679810" + }; + var hex = JT808Serializer.Serialize(jT808_0X8400).ToHexString(); + Assert.Equal("003132333435363739383130", hex); + } + + [Fact] + public void Test2() + { + var bytes = "00 31 32 33 34 35 36 37 39 38 31 30".ToHexBytes(); + JT808_0x8400 jT808_0X8400 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808CallBackType.普通通话, jT808_0X8400.CallBack); + Assert.Equal("12345679810", jT808_0X8400.PhoneNumber); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8401Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8401Test.cs new file mode 100644 index 0000000..3416f48 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8401Test.cs @@ -0,0 +1,56 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8401Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8401 jT808_0X8401 = new JT808_0x8401 + { + SettingTelephoneBook = Enums.JT808SettingTelephoneBook.追加电话本 + }; + List jT808ContactProperties = new List(); + jT808ContactProperties.Add(new JT808ContactProperty + { + TelephoneBookContactType= Enums.JT808TelephoneBookContactType.呼入, + Contact="smallchi", + PhoneNumber="13456smallch" + }); + jT808ContactProperties.Add(new JT808ContactProperty + { + TelephoneBookContactType = Enums.JT808TelephoneBookContactType.呼入_呼出, + Contact = "koike", + PhoneNumber = "koike123456" + }); + jT808_0X8401.JT808ContactProperties = jT808ContactProperties; + var hex = JT808Serializer.Serialize(jT808_0X8401).ToHexString(); + Assert.Equal("0202010C3133343536736D616C6C636808736D616C6C636869030B6B6F696B65313233343536056B6F696B65", hex); + //"02 02 01 0C 31 33 34 35 36 73 6D 61 6C 6C 63 68 08 73 6D 61 6C 6C 63 68 69 03 0B 6B 6F 69 6B 65 31 32 33 34 35 36 05 6B 6F 69 6B 65" + } + + [Fact] + public void Test2() + { + var bytes = "02 02 01 0C 31 33 34 35 36 73 6D 61 6C 6C 63 68 08 73 6D 61 6C 6C 63 68 69 03 0B 6B 6F 69 6B 65 31 32 33 34 35 36 05 6B 6F 69 6B 65".ToHexBytes(); + JT808_0x8401 jT808_0X8401 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808SettingTelephoneBook.追加电话本, jT808_0X8401.SettingTelephoneBook); + Assert.Equal(2, jT808_0X8401.ContactCount); + + Assert.Equal("13456smallch", jT808_0X8401.JT808ContactProperties[0].PhoneNumber); + Assert.Equal(Enums.JT808TelephoneBookContactType.呼入, jT808_0X8401.JT808ContactProperties[0].TelephoneBookContactType); + Assert.Equal("smallchi", jT808_0X8401.JT808ContactProperties[0].Contact); + + Assert.Equal("koike123456", jT808_0X8401.JT808ContactProperties[1].PhoneNumber); + Assert.Equal(Enums.JT808TelephoneBookContactType.呼入_呼出, jT808_0X8401.JT808ContactProperties[1].TelephoneBookContactType); + Assert.Equal("koike", jT808_0X8401.JT808ContactProperties[1].Contact); + + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8500Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8500Test.cs new file mode 100644 index 0000000..f25f157 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8500Test.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8500Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8500 jT808_0X8500 = new JT808_0x8500 + { + ControlFlag = 12 + }; + var hex = JT808Serializer.Serialize(jT808_0X8500).ToHexString(); + Assert.Equal("0C", hex); + } + + [Fact] + public void Test2() + { + var bytes = "0C".ToHexBytes(); + JT808_0x8500 jT808_0X8500 = JT808Serializer.Deserialize(bytes); + Assert.Equal(12, jT808_0X8500.ControlFlag); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs new file mode 100644 index 0000000..9fbcaa2 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8600Test.cs @@ -0,0 +1,108 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8600Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8600 jT808_0X8600 = new JT808_0x8600 + { + SettingAreaProperty = JT808SettingProperty.追加区域.ToByteValue(), + AreaItems = new List() + }; + jT808_0X8600.AreaItems.Add(new JT808CircleAreaProperty + { + AreaId = 1522, + AreaProperty = 222, + CenterPointLat = 123456789, + CenterPointLng = 123456789, + Radius = 200, + StartTime = DateTime.Parse("2018-10-18 00:00:12"), + EndTime = DateTime.Parse("2018-10-19 00:00:12"), + HighestSpeed = 60, + OverspeedDuration = 200 + }); + jT808_0X8600.AreaItems.Add(new JT808CircleAreaProperty + { + AreaId = 1523, + AreaProperty = 0, + CenterPointLat = 123456789, + CenterPointLng = 123456789, + Radius = 200, + StartTime = DateTime.Parse("2018-10-18 00:00:12"), + EndTime = DateTime.Parse("2018-10-19 00:00:12"), + HighestSpeed = 60, + OverspeedDuration = 200 + }); + jT808_0X8600.AreaItems.Add(new JT808CircleAreaProperty + { + AreaId = 1524, + AreaProperty = 2211, + CenterPointLat = 123456789, + CenterPointLng = 123456789, + Radius = 200, + StartTime = DateTime.Parse("2018-10-18 00:00:12"), + EndTime = DateTime.Parse("2018-10-19 00:00:12"), + HighestSpeed = 60, + OverspeedDuration = 200 + }); + var hex = JT808Serializer.Serialize(jT808_0X8600).ToHexString(); + //"01 03 00 00 05 F2 00 DE 07 5B CD 15 07 5B CD 15 00 00 00 C8 00 3C C8 00 00 05 F3 00 00 07 5B CD 15 07 5B CD 15 00 00 00 C8 00 00 05 F4 08 A3 07 5B CD 15 07 5B CD 15 00 00 00 C8 18 10 18 00 00 12 18 10 19 00 00 12 00 3C C8" + Assert.Equal("0103000005F200DE075BCD15075BCD15000000C8003CC8000005F30000075BCD15075BCD15000000C8000005F408A3075BCD15075BCD15000000C8181018000012181019000012003CC8", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "01 03 00 00 05 F2 00 DE 07 5B CD 15 07 5B CD 15 00 00 00 C8 00 3C C8 00 00 05 F3 00 00 07 5B CD 15 07 5B CD 15 00 00 00 C8 00 00 05 F4 08 A3 07 5B CD 15 07 5B CD 15 00 00 00 C8 18 10 18 00 00 12 18 10 19 00 00 12 00 3C C8".ToHexBytes(); + JT808_0x8600 jT808_0X8600 = JT808Serializer.Deserialize(bytes); + + Assert.Equal(JT808SettingProperty.追加区域.ToByteValue(), jT808_0X8600.SettingAreaProperty); + Assert.Equal(3, jT808_0X8600.AreaCount); + + var item0 = jT808_0X8600.AreaItems[0]; + Assert.Equal((uint)1522, item0.AreaId); + Assert.Equal((ushort)222, item0.AreaProperty); + Assert.Equal((uint)123456789, item0.CenterPointLat); + Assert.Equal((uint)123456789, item0.CenterPointLng); + Assert.Equal((uint)200, item0.Radius); + Assert.Null(item0.StartTime); + Assert.Null(item0.EndTime); + Assert.Equal((ushort)60, item0.HighestSpeed); + Assert.Equal((byte)200, item0.OverspeedDuration); + + var item1 = jT808_0X8600.AreaItems[1]; + Assert.Equal((uint)1523, item1.AreaId); + Assert.Equal(0, item1.AreaProperty); + Assert.Equal((uint)123456789, item1.CenterPointLat); + Assert.Equal((uint)123456789, item1.CenterPointLng); + Assert.Equal((uint)200, item1.Radius); + Assert.Null(item1.StartTime); + Assert.Null(item1.EndTime); + Assert.Null(item1.HighestSpeed); + Assert.Null(item1.OverspeedDuration); + + + var item2 = jT808_0X8600.AreaItems[2]; + Assert.Equal((uint)1524, item2.AreaId); + Assert.Equal((ushort)2211, item2.AreaProperty); + Assert.Equal((uint)123456789, item2.CenterPointLat); + Assert.Equal((uint)123456789, item2.CenterPointLng); + Assert.Equal((uint)200, item2.Radius); + Assert.Equal(DateTime.Parse("2018-10-18 00:00:12"), item2.StartTime); + Assert.Equal(DateTime.Parse("2018-10-19 00:00:12"), item2.EndTime); + Assert.Equal((ushort)60, item2.HighestSpeed); + Assert.Equal((byte)200, item2.OverspeedDuration); + + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8601Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8601Test.cs new file mode 100644 index 0000000..ad63fb4 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8601Test.cs @@ -0,0 +1,33 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8601Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8601 jT808_0X8601 = new JT808_0x8601(); + jT808_0X8601.AreaIds = new List() + { + 1,2 + }; + var hex = JT808Serializer.Serialize(jT808_0X8601).ToHexString(); + Assert.Equal("020000000100000002", hex); + } + + [Fact] + public void Test2() + { + var bytes = "020000000100000002".ToHexBytes(); + JT808_0x8601 jT808_0X8601 = JT808Serializer.Deserialize(bytes); + Assert.Equal(2, jT808_0X8601.AreaCount); + Assert.Equal((uint)1, jT808_0X8601.AreaIds[0]); + Assert.Equal((uint)2, jT808_0X8601.AreaIds[1]); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8602Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8602Test.cs new file mode 100644 index 0000000..aa8eb63 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8602Test.cs @@ -0,0 +1,90 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8602Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8602 jT808_0X8602 = new JT808_0x8602 + { + SettingAreaProperty = JT808SettingProperty.追加区域.ToByteValue(), + AreaItems = new List() + }; + jT808_0X8602.AreaItems.Add(new JT808RectangleAreaProperty + { + AreaId = 1522, + AreaProperty = 222, + LowRightPointLat= 123456789, + LowRightPointLng= 123456788, + UpLeftPointLat= 123456787, + UpLeftPointLng= 123456786, + StartTime = DateTime.Parse("2018-11-20 00:00:12"), + EndTime = DateTime.Parse("2018-11-21 00:00:12"), + HighestSpeed = 60, + OverspeedDuration = 200 + }); + jT808_0X8602.AreaItems.Add(new JT808RectangleAreaProperty + { + AreaId = 1523, + AreaProperty = 10, + LowRightPointLat = 123456700, + LowRightPointLng = 123456701, + UpLeftPointLat = 123456702, + UpLeftPointLng = 123456703, + StartTime = DateTime.Parse("2018-11-20 12:12:12"), + EndTime = DateTime.Parse("2018-11-21 11:11:11"), + HighestSpeed = 60, + OverspeedDuration = 200 + }); + var hex = JT808Serializer.Serialize(jT808_0X8602).ToHexString(); + Assert.Equal("0102000005F200DE075BCD13075BCD12075BCD15075BCD14003CC8000005F3000A075BCCBE075BCCBF075BCCBC075BCCBD003CC8", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0102000005F200DE075BCD13075BCD12075BCD15075BCD14003CC8000005F3000A075BCCBE075BCCBF075BCCBC075BCCBD003CC8".ToHexBytes(); + JT808_0x8602 jT808_0X8602 = JT808Serializer.Deserialize(bytes); + + Assert.Equal(JT808SettingProperty.追加区域.ToByteValue(), jT808_0X8602.SettingAreaProperty); + Assert.Equal(2, jT808_0X8602.AreaCount); + + var item0 = jT808_0X8602.AreaItems[0]; + Assert.Equal((uint)1522, item0.AreaId); + Assert.Equal((ushort)222, item0.AreaProperty); + + Assert.Equal((uint)123456789, item0.LowRightPointLat); + Assert.Equal((uint)123456788, item0.LowRightPointLng); + Assert.Equal((uint)123456787, item0.UpLeftPointLat); + Assert.Equal((uint)123456786, item0.UpLeftPointLng); + + Assert.Null(item0.StartTime); + Assert.Null(item0.EndTime); + Assert.Equal((ushort)60, item0.HighestSpeed); + Assert.Equal((byte)200, item0.OverspeedDuration); + + var item1 = jT808_0X8602.AreaItems[1]; + Assert.Equal((uint)1523, item1.AreaId); + Assert.Equal(10, item1.AreaProperty); + + Assert.Equal((uint)123456700, item1.LowRightPointLat); + Assert.Equal((uint)123456701, item1.LowRightPointLng); + Assert.Equal((uint)123456702, item1.UpLeftPointLat); + Assert.Equal((uint)123456703, item1.UpLeftPointLng); + + Assert.Null(item1.StartTime); + Assert.Null(item1.EndTime); + Assert.Equal((ushort)60, item1.HighestSpeed); + Assert.Equal((byte)200, item1.OverspeedDuration); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8603Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8603Test.cs new file mode 100644 index 0000000..de922e9 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8603Test.cs @@ -0,0 +1,35 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8603Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8603 jT808_0X8603 = new JT808_0x8603(); + jT808_0X8603.AreaIds = new List() + { + 2838,1717,772 + }; + + var hex = JT808Serializer.Serialize(jT808_0X8603).ToHexString(); + Assert.Equal("0300000B16000006B500000304", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0300000B16000006B500000304".ToHexBytes(); + JT808_0x8603 jT808_0X8603 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)2838, jT808_0X8603.AreaIds[0]); + Assert.Equal((uint)1717, jT808_0X8603.AreaIds[1]); + Assert.Equal((uint)772, jT808_0X8603.AreaIds[2]); + Assert.Equal(3, jT808_0X8603.AreaCount); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8604Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8604Test.cs new file mode 100644 index 0000000..c6bcb26 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8604Test.cs @@ -0,0 +1,60 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8604Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8604 jT808_0X8604 = new JT808_0x8604 + { + AreaId = 1234, + AreaProperty = JT808SettingProperty.追加区域.ToByteValue(), + StartTime = DateTime.Parse("2018-11-20 00:00:12"), + EndTime = DateTime.Parse("2018-11-21 00:00:12"), + HighestSpeed = 62, + OverspeedDuration = 218, + PeakItems = new List() + }; + jT808_0X8604.PeakItems.Add(new JT808PeakProperty + { + Lat= 123456789, + Lng= 123456788 + }); + jT808_0X8604.PeakItems.Add(new JT808PeakProperty + { + Lat = 123456700, + Lng = 123456701 + }); + var hex = JT808Serializer.Serialize(jT808_0X8604).ToHexString(); + Assert.Equal("000004D200011811200000121811210000120002075BCD15075BCD14075BCCBC075BCCBD", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "000004D200011811200000121811210000120002075BCD15075BCD14075BCCBC075BCCBD".ToHexBytes(); + JT808_0x8604 jT808_0X8604 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)1234, jT808_0X8604.AreaId); + Assert.Equal(JT808SettingProperty.追加区域.ToByteValue(), jT808_0X8604.AreaProperty); + Assert.Null(jT808_0X8604.HighestSpeed); + Assert.Null(jT808_0X8604.OverspeedDuration); + + Assert.Equal(DateTime.Parse("2018-11-20 00:00:12"),jT808_0X8604.StartTime); + Assert.Equal(DateTime.Parse("2018-11-21 00:00:12"),jT808_0X8604.EndTime); + Assert.Equal(2, jT808_0X8604.PeakItems.Count); + Assert.Equal((uint)123456789, jT808_0X8604.PeakItems[0].Lat); + Assert.Equal((uint)123456788, jT808_0X8604.PeakItems[0].Lng); + Assert.Equal((uint)123456700, jT808_0X8604.PeakItems[1].Lat); + Assert.Equal((uint)123456701, jT808_0X8604.PeakItems[1].Lng); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8605Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8605Test.cs new file mode 100644 index 0000000..0372bc3 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8605Test.cs @@ -0,0 +1,35 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System.Collections.Generic; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8605Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8605 jT808_0X8605 = new JT808_0x8605(); + jT808_0X8605.AreaIds = new List() + { + 2838,1717,772 + }; + + var hex = JT808Serializer.Serialize(jT808_0X8605).ToHexString(); + Assert.Equal("0300000B16000006B500000304", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0300000B16000006B500000304".ToHexBytes(); + JT808_0x8605 jT808_0X8605 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)2838, jT808_0X8605.AreaIds[0]); + Assert.Equal((uint)1717, jT808_0X8605.AreaIds[1]); + Assert.Equal((uint)772, jT808_0X8605.AreaIds[2]); + Assert.Equal(3, jT808_0X8605.AreaCount); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8606Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8606Test.cs new file mode 100644 index 0000000..fdf53eb --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8606Test.cs @@ -0,0 +1,213 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using Xunit; +using JT808.Protocol.Metadata; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8606Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8606 jT808_0X8606 = new JT808_0x8606 + { + RouteId = 9999, + RouteProperty = 1268, + StartTime = DateTime.Parse("2018-11-20 00:00:12"), + EndTime = DateTime.Parse("2018-11-21 00:00:12"), + InflectionPointItems = new List() + }; + jT808_0X8606.InflectionPointItems.Add(new JT808InflectionPointProperty() + { + InflectionPointId = 1000, + InflectionPointLat = 123456789, + InflectionPointLng = 123456788, + SectionDrivingUnderThreshold = 123, + SectionHighestSpeed = 69, + SectionId = 1287, + SectionLongDrivingThreshold = 50, + SectionOverspeedDuration = 23, + SectionProperty = 89, + SectionWidth = 56 + }); + jT808_0X8606.InflectionPointItems.Add(new JT808InflectionPointProperty() + { + InflectionPointId = 1001, + InflectionPointLat = 123456780, + InflectionPointLng = 123456781, + SectionDrivingUnderThreshold = 124, + SectionHighestSpeed = 42, + SectionId = 12007, + SectionLongDrivingThreshold = 58, + SectionOverspeedDuration = 26, + SectionProperty = 50, + SectionWidth = 75 + }); + var hex = JT808Serializer.Serialize(jT808_0X8606).ToHexString(); + //00 00 27 0F + //04 F4 + //00 02 + //00 00 03 E8 + //00 00 05 07 + //07 5B CD 15 + //07 5B CD 14 + //38 + //59 //‭0101 1001‬ + //00 32 + //00 7B + //00 00 03 E9 + //00 00 2E E7 + //07 5B CD 0C + //07 5B CD 0D + //4B + //32 //‭‭0011 0010‬ + //00 2A + //1A + Assert.Equal("0000270F04F40002000003E800000507075BCD15075BCD1438590032007B000003E900002EE7075BCD0C075BCD0D4B32002A1A", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0000270F04F40002000003E800000507075BCD15075BCD1438590032007B000003E900002EE7075BCD0C075BCD0D4B32002A1A".ToHexBytes(); + JT808_0x8606 jT808_0X8606 = JT808Serializer.Deserialize(bytes); + + Assert.Equal((uint)9999, jT808_0X8606.RouteId); + Assert.Equal((uint)1268, jT808_0X8606.RouteProperty); + //Assert.Equal(DateTime.Parse("2018-11-20 00:00:12"), jT808_0X8606.StartTime); + //Assert.Equal(DateTime.Parse("2018-11-21 00:00:12"), jT808_0X8606.EndTime); + Assert.Null(jT808_0X8606.StartTime); + Assert.Null(jT808_0X8606.EndTime); + + Assert.Equal(2, jT808_0X8606.InflectionPointItems.Count); + + Assert.Equal((uint)1000, jT808_0X8606.InflectionPointItems[0].InflectionPointId); + Assert.Equal((uint)123456789, jT808_0X8606.InflectionPointItems[0].InflectionPointLat); + Assert.Equal((uint)123456788, jT808_0X8606.InflectionPointItems[0].InflectionPointLng); + + Assert.Equal((ushort)123, jT808_0X8606.InflectionPointItems[0].SectionDrivingUnderThreshold); + //Assert.Equal((ushort)69, jT808_0X8606.InflectionPointItems[0].SectionHighestSpeed); + Assert.Null(jT808_0X8606.InflectionPointItems[0].SectionHighestSpeed); + Assert.Equal((uint)1287, jT808_0X8606.InflectionPointItems[0].SectionId); + Assert.Equal((ushort)50, jT808_0X8606.InflectionPointItems[0].SectionLongDrivingThreshold); + //Assert.Equal((byte)23, jT808_0X8606.InflectionPointItems[0].SectionOverspeedDuration); + Assert.Equal(89, jT808_0X8606.InflectionPointItems[0].SectionProperty); + Assert.Equal(56, jT808_0X8606.InflectionPointItems[0].SectionWidth); + + Assert.Equal((uint)1001, jT808_0X8606.InflectionPointItems[1].InflectionPointId); + Assert.Equal((uint)123456780, jT808_0X8606.InflectionPointItems[1].InflectionPointLat); + Assert.Equal((uint)123456781, jT808_0X8606.InflectionPointItems[1].InflectionPointLng); + //Assert.Equal((ushort)124, jT808_0X8606.InflectionPointItems[1].SectionDrivingUnderThreshold); + Assert.Null(jT808_0X8606.InflectionPointItems[1].SectionDrivingUnderThreshold); + Assert.Equal((ushort)42, jT808_0X8606.InflectionPointItems[1].SectionHighestSpeed); + Assert.Equal((uint)12007, jT808_0X8606.InflectionPointItems[1].SectionId); + //Assert.Equal((ushort)58, jT808_0X8606.InflectionPointItems[1].SectionLongDrivingThreshold); + Assert.Null(jT808_0X8606.InflectionPointItems[1].SectionLongDrivingThreshold); + + Assert.Equal((byte)26, jT808_0X8606.InflectionPointItems[1].SectionOverspeedDuration); + Assert.Equal(50, jT808_0X8606.InflectionPointItems[1].SectionProperty); + Assert.Equal(75, jT808_0X8606.InflectionPointItems[1].SectionWidth); + } + + [Fact] + public void Test3() + { + JT808_0x8606 jT808_0X8606 = new JT808_0x8606 + { + RouteId = 9999, + RouteProperty = 51, + StartTime = DateTime.Parse("2018-11-20 00:00:12"), + EndTime = DateTime.Parse("2018-11-21 00:00:12"), + InflectionPointItems = new List() + }; + jT808_0X8606.InflectionPointItems.Add(new JT808InflectionPointProperty() + { + InflectionPointId = 1000, + InflectionPointLat = 123456789, + InflectionPointLng = 123456788, + SectionDrivingUnderThreshold = 123, + SectionHighestSpeed = 69, + SectionId = 1287, + SectionLongDrivingThreshold = 50, + SectionOverspeedDuration = 23, + SectionProperty = 3, + SectionWidth = 56 + }); + jT808_0X8606.InflectionPointItems.Add(new JT808InflectionPointProperty() + { + InflectionPointId = 1001, + InflectionPointLat = 123456780, + InflectionPointLng = 123456781, + SectionDrivingUnderThreshold = 124, + SectionHighestSpeed = 42, + SectionId = 12007, + SectionLongDrivingThreshold = 58, + SectionOverspeedDuration = 26, + SectionProperty = 3, + SectionWidth = 75 + }); + var hex = JT808Serializer.Serialize(jT808_0X8606).ToHexString(); + //00 00 27 0F + //04 F4 + //00 02 + //00 00 03 E8 + //00 00 05 07 + //07 5B CD 15 + //07 5B CD 14 + //38 + //59 //‭0000000000110011 + //00 32 + //00 7B + //00 00 03 E9 + //00 00 2E E7 + //07 5B CD 0C + //07 5B CD 0D + //4B + //32 //‭‭0000000000000011 + //00 2A + //1A + Assert.Equal("0000270F00331811200000121811210000120002000003E800000507075BCD15075BCD1438030032007B004517000003E900002EE7075BCD0C075BCD0D4B03003A007C002A1A", hex); + } + + [Fact] + public void Test4() + { + byte[] bytes = "0000270F00331811200000121811210000120002000003E800000507075BCD15075BCD1438030032007B004517000003E900002EE7075BCD0C075BCD0D4B03003A007C002A1A".ToHexBytes(); + JT808_0x8606 jT808_0X8606 = JT808Serializer.Deserialize(bytes); + + Assert.Equal((uint)9999, jT808_0X8606.RouteId); + Assert.Equal((uint)51, jT808_0X8606.RouteProperty); + Assert.Equal(DateTime.Parse("2018-11-20 00:00:12"), jT808_0X8606.StartTime); + Assert.Equal(DateTime.Parse("2018-11-21 00:00:12"), jT808_0X8606.EndTime); + + Assert.Equal(2, jT808_0X8606.InflectionPointItems.Count); + + Assert.Equal((uint)1000, jT808_0X8606.InflectionPointItems[0].InflectionPointId); + Assert.Equal((uint)123456789, jT808_0X8606.InflectionPointItems[0].InflectionPointLat); + Assert.Equal((uint)123456788, jT808_0X8606.InflectionPointItems[0].InflectionPointLng); + + Assert.Equal((ushort)123, jT808_0X8606.InflectionPointItems[0].SectionDrivingUnderThreshold); + Assert.Equal((ushort)69, jT808_0X8606.InflectionPointItems[0].SectionHighestSpeed); + Assert.Equal((uint)1287, jT808_0X8606.InflectionPointItems[0].SectionId); + Assert.Equal((ushort)50, jT808_0X8606.InflectionPointItems[0].SectionLongDrivingThreshold); + Assert.Equal((byte)23, jT808_0X8606.InflectionPointItems[0].SectionOverspeedDuration); + Assert.Equal(3, jT808_0X8606.InflectionPointItems[0].SectionProperty); + Assert.Equal(56, jT808_0X8606.InflectionPointItems[0].SectionWidth); + + Assert.Equal((uint)1001, jT808_0X8606.InflectionPointItems[1].InflectionPointId); + Assert.Equal((uint)123456780, jT808_0X8606.InflectionPointItems[1].InflectionPointLat); + Assert.Equal((uint)123456781, jT808_0X8606.InflectionPointItems[1].InflectionPointLng); + Assert.Equal((ushort)124, jT808_0X8606.InflectionPointItems[1].SectionDrivingUnderThreshold); + Assert.Equal((ushort)42, jT808_0X8606.InflectionPointItems[1].SectionHighestSpeed); + Assert.Equal((uint)12007, jT808_0X8606.InflectionPointItems[1].SectionId); + Assert.Equal((ushort)58, jT808_0X8606.InflectionPointItems[1].SectionLongDrivingThreshold); + Assert.Equal((byte)26, jT808_0X8606.InflectionPointItems[1].SectionOverspeedDuration); + Assert.Equal(3, jT808_0X8606.InflectionPointItems[1].SectionProperty); + Assert.Equal(75, jT808_0X8606.InflectionPointItems[1].SectionWidth); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8800Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8800Test.cs new file mode 100644 index 0000000..74016c4 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8800Test.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8800Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8800 jT808_0X8800 = new JT808_0x8800 + { + MultimediaId = 129, + RetransmitPackageIds = new byte[] { 0x01, 0x02, 0x03, 0x04 } + }; + string hex = JT808Serializer.Serialize(jT808_0X8800).ToHexString(); + Assert.Equal("000000810201020304", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "000000810201020304".ToHexBytes(); + JT808_0x8800 jT808_0X8800 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)129, jT808_0X8800.MultimediaId); + Assert.Equal(2, jT808_0X8800.RetransmitPackageCount); + Assert.Equal(new byte[] { 0x01, 0x02, 0x03, 0x04 }, jT808_0X8800.RetransmitPackageIds); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8801Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8801Test.cs new file mode 100644 index 0000000..fa2c576 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8801Test.cs @@ -0,0 +1,47 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8801Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8801 jT808_0X8801 = new JT808_0x8801 + { + ChannelId = 128, + Chroma = 245, + Contrast = 126, + Lighting = 235, + Resolution = 0x08, + Saturability = 120, + SaveFlag = 1, + ShootingCommand = 0, + VideoQuality = 9, + VideoTime = 2686 + }; + string hex = JT808Serializer.Serialize(jT808_0X8801).ToHexString(); + Assert.Equal("8000000A7E010809EB7E78F5", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "8000000A7E010809EB7E78F5".ToHexBytes(); + JT808_0x8801 jT808_0X8801 = JT808Serializer.Deserialize(bytes); + Assert.Equal(128, jT808_0X8801.ChannelId); + Assert.Equal(245, jT808_0X8801.Chroma); + Assert.Equal(126, jT808_0X8801.Contrast); + Assert.Equal(235, jT808_0X8801.Lighting); + Assert.Equal(0x08, jT808_0X8801.Resolution); + Assert.Equal(120, jT808_0X8801.Saturability); + Assert.Equal(1, jT808_0X8801.SaveFlag); + Assert.Equal(0, jT808_0X8801.ShootingCommand); + Assert.Equal(9, jT808_0X8801.VideoQuality); + Assert.Equal(2686, jT808_0X8801.VideoTime); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8802Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8802Test.cs new file mode 100644 index 0000000..9afb41f --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8802Test.cs @@ -0,0 +1,39 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8802Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8802 jT808_0X8802 = new JT808_0x8802 + { + ChannelId = 123, + EventItemCoding = JT808EventItemCoding.碰撞侧翻报警触发.ToByteValue(), + MultimediaType = JT808MultimediaType.视频.ToByteValue(), + StartTime = DateTime.Parse("2018-11-16 21:00:08"), + EndTime = DateTime.Parse("2018-11-16 22:00:08") + }; + string hex = JT808Serializer.Serialize(jT808_0X8802).ToHexString(); + Assert.Equal("027B03181116210008181116220008", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "027B03181116210008181116220008".ToHexBytes(); + JT808_0x8802 jT808_0X8802 = JT808Serializer.Deserialize(bytes); + Assert.Equal(123, jT808_0X8802.ChannelId); + Assert.Equal(JT808EventItemCoding.碰撞侧翻报警触发.ToByteValue(), jT808_0X8802.EventItemCoding); + Assert.Equal(JT808MultimediaType.视频.ToByteValue(), jT808_0X8802.MultimediaType); + Assert.Equal(DateTime.Parse("2018-11-16 21:00:08"), jT808_0X8802.StartTime); + Assert.Equal(DateTime.Parse("2018-11-16 22:00:08"), jT808_0X8802.EndTime); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8803Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8803Test.cs new file mode 100644 index 0000000..3bb3d9b --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8803Test.cs @@ -0,0 +1,41 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8803Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8803 jT808_0X8803 = new JT808_0x8803 + { + ChannelId = 128, + EventItemCoding = JT808EventItemCoding.平台下发指令.ToByteValue(), + MultimediaDeleted = JT808MultimediaDeleted.删除.ToByteValue(), + MultimediaType = JT808MultimediaType.图像.ToByteValue(), + StartTime = DateTime.Parse("2018-11-16 22:00:21"), + EndTime = DateTime.Parse("2018-11-16 23:00:21") + }; + string hex = JT808Serializer.Serialize(jT808_0X8803).ToHexString(); + Assert.Equal("00800018111622002118111623002101", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00800018111622002118111623002101".ToHexBytes(); + JT808_0x8803 jT808_0X8803 = JT808Serializer.Deserialize(bytes); + Assert.Equal(128, jT808_0X8803.ChannelId); + Assert.Equal(JT808EventItemCoding.平台下发指令.ToByteValue(), jT808_0X8803.EventItemCoding); + Assert.Equal(JT808MultimediaDeleted.删除.ToByteValue(), jT808_0X8803.MultimediaDeleted); + Assert.Equal(JT808MultimediaType.图像.ToByteValue(), jT808_0X8803.MultimediaType); + Assert.Equal(DateTime.Parse("2018-11-16 22:00:21"), jT808_0X8803.StartTime); + Assert.Equal(DateTime.Parse("2018-11-16 23:00:21"), jT808_0X8803.EndTime); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8804Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8804Test.cs new file mode 100644 index 0000000..5f74506 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8804Test.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8804Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8804 jT808_0X8804 = new JT808_0x8804 + { + RecordCmd = JT808RecordCmd.停止录音, + RecordTime = 30, + RecordSave = JT808RecordSave.实时上传, + AudioSampleRate = 1 + }; + string hex = JT808Serializer.Serialize(jT808_0X8804).ToHexString(); + //"00 00 1E 00 01" + Assert.Equal("00001E0001", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00 00 1E 00 01".ToHexBytes(); + JT808_0x8804 jT808_0X8804 = JT808Serializer.Deserialize(bytes); + Assert.Equal(JT808RecordCmd.停止录音, jT808_0X8804.RecordCmd); + Assert.Equal(30, jT808_0X8804.RecordTime); + Assert.Equal(JT808RecordSave.实时上传, jT808_0X8804.RecordSave); + Assert.Equal(1, jT808_0X8804.AudioSampleRate); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8805Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8805Test.cs new file mode 100644 index 0000000..a5787b0 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8805Test.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8805Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + [Fact] + public void Test1() + { + JT808_0x8805 jT808_0X8805 = new JT808_0x8805 + { + MultimediaId = 10000, + MultimediaDeleted = Enums.JT808MultimediaDeleted.保留.ToByteValue() + }; + string hex = JT808Serializer.Serialize(jT808_0X8805).ToHexString(); + Assert.Equal("0000271000", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00 00 27 10 00".ToHexBytes(); + JT808_0x8805 jT808_0X8805 = JT808Serializer.Deserialize(bytes); + Assert.Equal(Enums.JT808MultimediaDeleted.保留.ToByteValue(), jT808_0X8805.MultimediaDeleted); + Assert.Equal((uint)10000, jT808_0X8805.MultimediaId); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8900Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8900Test.cs new file mode 100644 index 0000000..7630e00 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8900Test.cs @@ -0,0 +1,48 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Test.MessageBody.JT808_0X8900_BodiesImpl; +using System.Reflection; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8900Test + { + JT808Serializer JT808Serializer; + + public JT808_0x8900Test() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + [Fact] + public void Test1() + { + JT808_0x8900 jT808_0X8900 = new JT808_0x8900 + { + PassthroughType = 0x0B, + JT808_0X8900_BodyBase = new JT808_0X8900_Test_BodiesImpl + { + Id = 12345, + Sex = 0x01 + } + }; + string hex = JT808Serializer.Serialize(jT808_0X8900).ToHexString(); + Assert.Equal("0B0000303901", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "0B0000303901".ToHexBytes(); + JT808_0x8900 jT808_0X8900 = JT808Serializer.Deserialize(bytes); + JT808_0X8900_Test_BodiesImpl jT808_0X8900_Test_BodiesImpl = JT808Serializer.Deserialize(jT808_0X8900.PassthroughData); + Assert.Equal(0x0B, jT808_0X8900.PassthroughType); + Assert.Equal((uint)12345, jT808_0X8900_Test_BodiesImpl.Id); + Assert.Equal(0x01, jT808_0X8900_Test_BodiesImpl.Sex); + } + } +} diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8A00Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8A00Test.cs new file mode 100644 index 0000000..450dc49 --- /dev/null +++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8A00Test.cs @@ -0,0 +1,40 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using System.Linq; +using Xunit; + +namespace JT808.Protocol.Test.MessageBody +{ + public class JT808_0x8A00Test + { + JT808Serializer JT808Serializer = new JT808Serializer(); + byte[] N; + public JT808_0x8A00Test() + { + + N = Enumerable.Range(0, 128).Select(s => Convert.ToByte(s)).ToArray(); + } + + [Fact] + public void Test1() + { + JT808_0x8A00 jT808_0X8A00 = new JT808_0x8A00 + { + E = 128, + N = N + }; + string hex = JT808Serializer.Serialize(jT808_0X8A00).ToHexString(); + Assert.Equal("00000080000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F", hex); + } + + [Fact] + public void Test2() + { + byte[] bytes = "00000080000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F".ToHexBytes(); + JT808_0x8A00 jT808_0X8A00 = JT808Serializer.Deserialize(bytes); + Assert.Equal((uint)128, jT808_0X8A00.E); + Assert.Equal(N, jT808_0X8A00.N); + } + } +} diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs new file mode 100644 index 0000000..1f59d22 --- /dev/null +++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs @@ -0,0 +1,224 @@ +using JT808.Protocol.MessagePack; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using System.Buffers; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.MessagePack +{ + public class JT808MessagePackReaderTest + { + [Fact] + public void JT808MessagePackReaderConstructorTest() + { + byte[] bytes = "7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(new byte[4096]); + Assert.Equal(0x13, jT808MessagePackReader.CalculateCheckXorCode); + Assert.Equal(jT808MessagePackReader.SrcBuffer.Length, bytes.Length); + byte[] bytes1 = "7E 02 00 00 26 12 34 56 78 90 12 00 7E 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 13 7E".ToHexBytes(); + //7E02000026123456789012007E000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D137D + //7E02000026123456789012007E000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D137E + var a = jT808MessagePackReader.Reader.ToArray().ToHexString(); + Assert.Equal(jT808MessagePackReader.Reader.ToArray(), bytes1); + } + + [Fact] + public void ReadEncodeTest() + { + byte[] bytes = "7E 7D 02 7D 01 7D 02 7D 01 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(new byte[4096]); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(0x7E, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7D, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7E, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7D, jT808MessagePackReader.ReadByte()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + Assert.Equal(6, jT808MessagePackReader.ReaderCount); + } + + [Fact] + public void ReadEncodeTest1() + { + byte[] bytes = "7E 00 02 00 00 04 00 21 67 92 87 00 2B 7D 02 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + } + + [Fact] + public void ReadEncodeTest2() + { + byte[] bytes = "7E 00 02 00 00 04 00 21 67 92 87 00 2B 7D 02 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(); + Assert.Equal(0x7E, jT808MessagePackReader.CalculateCheckXorCode); + } + + + [Fact] + public void ReadDateTimeTest() + { + byte[] bytes = "7E 07 E3 06 19 23 23 23 00 7B 19 06 19 23 23 23 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(DateTime.Parse("2019-06-19"), jT808MessagePackReader.ReadDateTime4()); + Assert.Equal(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,23,23,23,123), jT808MessagePackReader.ReadDateTime5()); + Assert.Equal(DateTime.Parse("2019-06-19 23:23:23"), jT808MessagePackReader.ReadDateTime6()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Theory] + [InlineData("smallchi(Koike)")] + public void ReadStringTest(string str) + { + byte[] bytes = "7E736D616C6C636869284B6F696B65297E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(str, jT808MessagePackReader.ReadString(str.Length)); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Theory] + [InlineData("0000000000000000000000ABCDEF1234")] + public void ReadHexTest(string hexStr) + { + byte[] bytes = "7E0000000000000000000000ABCDEF12347E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + //0000000000000000000000ABCDEF1234 + Assert.Equal(hexStr, jT808MessagePackReader.ReadHex(16)); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadUTCDateTimeTest() + { + byte[] bytes = "000000005D0CF66B".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(DateTime.Parse("2019-06-21 23:23:23"), jT808MessagePackReader.ReadUTCDateTime()); + } + + [Fact] + public void ReadBCDTest1() + { + byte[] bytes = "7E 12 34 56 78 90 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal("1234567890", jT808MessagePackReader.ReadBCD(10)); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadBCDTest2() + { + byte[] bytes = "7E 12 34 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal("1234", jT808MessagePackReader.ReadBCD(5)); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadBCDTest3() + { + byte[] bytes = "7E 00 12 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal("12", jT808MessagePackReader.ReadBCD(5)); + //Assert.Equal("0012", jT808MessagePackReader.ReadBCD(5)); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadArrayTest() + { + byte[] bytes = "7E 01 02 03 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(new byte[] { 0x01, 0x02, 0x03 }, jT808MessagePackReader.ReadArray(3).ToArray()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadNumericalTest() + { + byte[] bytes = "7E 01 00 10 00 00 00 20 00 00 00 40 7E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(0x01, jT808MessagePackReader.ReadByte()); + Assert.Equal(16, jT808MessagePackReader.ReadUInt16()); + Assert.Equal(32, jT808MessagePackReader.ReadInt32()); + Assert.Equal((uint)64, jT808MessagePackReader.ReadUInt32()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Fact] + public void ReadUInt64Test() + { + byte[] bytes = "00 00 00 00 00 0F 63 E3".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal((ulong)1008611, jT808MessagePackReader.ReadUInt64()); + } + + [Theory] + [InlineData("123456789")] + public void ReadBigNumberTest(string numStr) + { + byte[] bytes = "0000000000075BCD15".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(numStr, jT808MessagePackReader.ReadBigNumber(numStr.Length)); + } + + [Fact] + public void ReadContentTest() + { + var bytes = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + JT808PackageFormatter jT808PackageFormatter = new JT808PackageFormatter(); + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.SkipCRCCode = true; + var package=jT808PackageFormatter.Deserialize(ref jT808MessagePackReader, jT808Config); + } + + [Theory] + [InlineData(100000)] + //[InlineData(1000000)] + //[InlineData(10000000)] + //[InlineData(100000000)] + public void ArrayPoolTest1(int count) + { + var arrayPool = ArrayPool.Create(); + while (count >= 0) + { + var buffer = arrayPool.Rent(4096); + byte[] bytes = "7E 7D 02 7D 01 7D 02 7D 01 7E".ToHexBytes(); + var jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(buffer); + try + { + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Equal(0x7E, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7D, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7E, jT808MessagePackReader.ReadByte()); + Assert.Equal(0x7D, jT808MessagePackReader.ReadByte()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + Assert.Equal(6, jT808MessagePackReader.ReaderCount); + } + catch (Exception) + { + + } + finally + { + arrayPool.Return(buffer); + count--; + } + } + } + } +} diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs new file mode 100644 index 0000000..4cd821e --- /dev/null +++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs @@ -0,0 +1,450 @@ +using JT808.Protocol.MessagePack; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using System.Buffers; + +namespace JT808.Protocol.Test.MessagePack +{ + public class JT808MessagePackWriterTest + { + [Fact] + public void WriteEncodeTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.WriteByte(0x7D); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.WriteByte(0x7D); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E 7E 7D 7E 7D 7E + //Encode + //7E 7D 02 7D 01 7D 02 7D 01 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 7E 7D 7E 7D 7E 7E 7D 02 7D 01 7D 02 7D 01 7E".Replace(" ", ""), realBytes); + } + + [Fact] + public void WriteEncodeTest1() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.WriteByte(0x7D); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.WriteByte(0x7D); + msgpackWriter.WriteFullEncode(); + //===========output========= + //Unencode: + //7E 7D 7E 7D + //Encode + //7D 02 7D 01 7D 02 7D 01 + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 7D 7E 7D 7D 02 7D 01 7D 02 7D 01".Replace(" ", ""), realBytes); + } + + [Fact] + public void WriteDateTimeTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteDateTime4(DateTime.Parse("2019-06-19 23:23:23")); + msgpackWriter.WriteDateTime5(DateTime.Parse("2019-06-19 23:23:23.123")); + msgpackWriter.WriteDateTime6(DateTime.Parse("2019-06-19 23:23:23")); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //WriteDateTime4=>YYYYMMDD=>07 E3 06 19 + //WriteDateTime5=>HH-mm-ss-fff|HH-mm-ss-msms=>23 23 23 00 7B + //WriteDateTime6=>yyMMddHHmmss=>19 23 23 23 + //Unencode: + //7E 07 E3 06 19 23 23 23 00 7B 19 06 19 23 23 23 7E + //Encode + //7E 07 E3 06 19 23 23 23 00 7B 19 06 19 23 23 23 7E + var encodeBytes = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("7E07E30619232323007B1906192323237E".Replace(" ", ""), encodeBytes); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E07E30619232323007B1906192323237E7E07E30619232323007B1906192323237E", realBytes); + } + + [Fact] + public void WriteUTCDateTimeTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteUTCDateTime(DateTime.Parse("2019-06-21 23:23:23")); + var encodeBytes = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("000000005D0CF66B", encodeBytes); + } + + [Fact] + public void WriteBCDTest1() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteBCD("1234567890", 10); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //7E 12 34 56 78 90 7E 7E 12 34 56 78 90 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 12 34 56 78 90 7E 7E 12 34 56 78 90 7E".Replace(" ", ""), realBytes); + } + + [Fact] + public void WriteBCDTest2() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteBCD("1234567890", 5); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //7E 12 34 7E 7E 12 34 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 12 34 7E 7E 12 34 7E".Replace(" ", ""), realBytes); + } + + [Fact] + public void WriteBCDTest3() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteBCD("123", 5); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //7E 00 12 7E 7E 00 12 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 00 12 7E 7E 00 12 7E".Replace(" ", ""), realBytes); + } + + [Theory] + [InlineData("smallchi(Koike)")] + public void WriteStringTest(string str) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteString(str); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + byte[] strBytes = JT808Constants.Encoding.GetBytes(str); + var strHex = strBytes.ToHexString(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + //7E736D616C6C636869284B6F696B65297E7E736D616C6C636869284B6F696B65297E + Assert.StartsWith(strHex, realBytes.Substring(2)); + Assert.Equal("7E736D616C6C636869284B6F696B65297E7E736D616C6C636869284B6F696B65297E", realBytes); + } + + [Theory] + [InlineData("ABCDEF1234")] + public void WriteHexTest(string hexStr) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteHex(hexStr, 16); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + //7E0000000000000000000000ABCDEF12347E7E0000000000000000000000ABCDEF12347E + Assert.StartsWith("0000000000000000000000ABCDEF1234", realBytes.Substring(2)); + Assert.Equal("7E0000000000000000000000ABCDEF12347E7E0000000000000000000000ABCDEF12347E", realBytes); + } + + [Theory] + [InlineData(new byte[] { 0x01, 0x02, 0x03 })] + public void WriteArrayTest(byte[] dara) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteArray(dara); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E 01 02 03 7E + //Encode + //7E 01 02 03 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 01 02 03 7E 7E 01 02 03 7E".Replace(" ",""), realBytes); + } + + [Fact] + public void WriteNumericalTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteByte(0x01); + msgpackWriter.WriteUInt16(16); + msgpackWriter.WriteInt32(32); + msgpackWriter.WriteUInt32(64); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E 01 00 10 00 00 00 20 00 00 00 40 7E + //Encode + //7E 01 00 10 00 00 00 20 00 00 00 40 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 01 00 10 00 00 00 20 00 00 00 40 7E 7E 01 00 10 00 00 00 20 00 00 00 40 7E".Replace(" ", ""), realBytes); + } + + [Theory] + [InlineData(5)] + public void SkipTest(int count) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.Skip(count, out int position); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E 00 00 00 00 00 7E + //Encode + //7E 00 00 00 00 00 7E + Assert.Equal(1, position); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 00 00 00 00 00 7E 7E 00 00 00 00 00 7E".Replace(" ",""), realBytes); + } + + [Theory] + [InlineData(5,0xFF)] + public void CustomSkipTest(int count,byte fullValue) + { + + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.Skip(count, out int position, fullValue); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E FF FF FF FF FF 7E + //Encode + //7E FF FF FF FF FF 7E + Assert.Equal(1, position); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E FF FF FF FF FF 7E 7E FF FF FF FF FF 7E".Replace(" ", ""), realBytes); + } + + [Fact] + public void NilTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.Nil(out int position); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + Assert.Equal(1, position); + //===========output========= + //Unencode: + //7E 00 7E + //Encode + //7E 00 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 00 7E 7E 00 7E".Replace(" ", ""), realBytes); + } + + [Theory] + [InlineData(1, 12)] + public void WriteXorTest1(int start,int end) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteArray("02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01".ToHexBytes()); + msgpackWriter.WriteXor(start, end); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.NotEqual("13", realBytes.Substring(realBytes.Length-4, 2)); + } + + [Theory] + [InlineData(12, 1)] + public void WriteXorTest2(int start, int end) + { + Assert.Throws(() => + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteXor(start, end); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + }); + } + + [Fact] + public void WriteXorTest3() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteArray("02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01".ToHexBytes()); + msgpackWriter.WriteXor(); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("13", realBytes.Substring(realBytes.Length - 4, 2)); + } + + [Theory] + [InlineData(1,0x02, + 2,8, + 4,9, + 6,"654321", + 3,new byte[] { 0x01,0x02,0x03})] + public void WriteReturnTest( + int skipbyte, byte writeNewByte, + int skipInt16, ushort writeNewInt16, + int skipInt32, int writeNewInt32, + int skipString, string writeNewString, + int skipArray3, byte[] writeNewArray) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.Skip(skipbyte, out var position1); + msgpackWriter.Skip(skipInt16, out var position2); + msgpackWriter.Skip(skipInt32, out var position3); + msgpackWriter.Skip(skipString, out var position4); + msgpackWriter.Skip(skipArray3, out var position5); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========skip output========= + //Unencode: + //7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E + //Encode + //7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E".Replace(" ", ""), realBytes); + msgpackWriter.WriteByteReturn(writeNewByte, position1); + msgpackWriter.WriteUInt16Return(writeNewInt16, position2); + msgpackWriter.WriteInt32Return(writeNewInt32, position3); + msgpackWriter.WriteBCDReturn(writeNewString, skipString, position4); + msgpackWriter.WriteArrayReturn(writeNewArray, position5); + //===========write return output========= + //7E 02 00 08 00 00 00 09 65 43 21 00 00 00 01 02 03 7E + var writeRealBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 02 00 08 00 00 00 09 65 43 21 00 00 00 01 02 03 7E 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7E".Replace(" ", ""), writeRealBytes); + } + + [Fact] + public void WriteUInt64Test() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteUInt64(1008611); + var hex = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + //00 00 00 00 00 0F 63 E3 + Assert.Equal("00 00 00 00 00 0F 63 E3".Replace(" ", ""), hex); + } + + [Theory] + [InlineData("123456789")] + public void WriteBigNumberTest(string numStr) + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteBigNumber(numStr, numStr.Length); + var hex = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("0000000000075BCD15", hex); + } + + [Theory] + [InlineData(100000)] + //[InlineData(1000000)] + //[InlineData(10000000)] + //[InlineData(100000000)] + public void ArrayPoolTest1(int count) + { + var arrayPool = ArrayPool.Create(); + while (count>=0) + { + var buffer = arrayPool.Rent(65535); + var msgpackWriter = new JT808MessagePackWriter(buffer); + try + { + msgpackWriter.WriteStart(); + msgpackWriter.WriteInt32(16); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 00 00 00 10 7E 7E 00 00 00 10 7E".Replace(" ", ""), realBytes); + } + catch (Exception) + { + + } + finally + { + arrayPool.Return(buffer); + count--; + } + } + } + + [Fact] + public void CompositeTest1() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteByte(0x01); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.WriteByte(0x7d); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + var encodeBytes = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("7E017D027D017E", encodeBytes); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E017E7D7E7E017D027D017E", realBytes); + } + + [Fact] + public void CompositeTest2() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteByte(0x01); + msgpackWriter.WriteByte(0x7E); + msgpackWriter.Nil(out int nilPosition); + Assert.Equal(3, nilPosition); + msgpackWriter.WriteByte(0x7d); + msgpackWriter.WriteBCD("123456789", 10); + msgpackWriter.Skip(5, out int skipPostion); + Assert.Equal(10, skipPostion); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //Unencode: + //7E 01 7E 00 7D 01 23 45 67 89 00 00 00 00 00 7E + //Encode + //7E 01 7D 02 00 7D 01 01 23 45 67 89 00 00 00 00 00 7E + //7E 01 7D 02 00 7D 01 01 00 23 00 45 00 00 00 00 00 7E + var encodeBytes = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("7E 01 7D 02 00 7D 01 01 23 45 67 89 00 00 00 00 00 7E".Replace(" ", ""), encodeBytes); + var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString(); + Assert.Equal("7E 01 7E 00 7D 01 23 45 67 89 00 00 00 00 00 7E 7E 01 7D 02 00 7D 01 01 23 45 67 89 00 00 00 00 00 7E".Replace(" ", ""), realBytes); + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo1.cs b/src/JT808.Protocol.Test/Simples/Demo1.cs new file mode 100644 index 0000000..8728b5c --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo1.cs @@ -0,0 +1,69 @@ +using JT808.Protocol.Interfaces; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo1 + { + public JT808Serializer JT808Serializer; + public Demo1() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + + [Fact] + public void Test1() + { + JT808Package jT808Package = new JT808Package(); + + jT808Package.Header = new JT808Header + { + MsgId = Enums.JT808MsgId.位置信息汇报.ToUInt16Value(), + MsgNum = 126, + TerminalPhoneNo = "123456789012" + }; + + JT808_0x0200 jT808_0x0200 = new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-10-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary() + }; + + jT808_0x0200.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x01, new JT808_0x0200_0x01 + { + Mileage = 100 + }); + + jT808_0x0200.JT808LocationAttachData.Add(JT808_0x0200_BodyBase.AttachId0x02, new JT808_0x0200_0x02 + { + Oil = 125 + }); + + jT808Package.Bodies = jT808_0x0200; + + byte[] data = JT808Serializer.Serialize(jT808Package); + + var hex = data.ToHexString(); + //"7E020000261234567890120001000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D016C7E" + Assert.Equal("7E02000026123456789012007D02000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D01137E", hex); + // 输出结果Hex: + // 7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo2.cs b/src/JT808.Protocol.Test/Simples/Demo2.cs new file mode 100644 index 0000000..9f5c416 --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo2.cs @@ -0,0 +1,59 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo2 + { + public JT808Serializer JT808Serializer; + public Demo2() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + + [Fact] + public void Test1() + { + //1.转成byte数组 + byte[] bytes = "7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E".ToHexBytes(); + + //2.将数组反序列化 + var jT808Package = JT808Serializer.Deserialize(bytes); + + //3.数据包头 + Assert.Equal(Enums.JT808MsgId.位置信息汇报.ToValue(), jT808Package.Header.MsgId); + Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength); + Assert.Equal(126, jT808Package.Header.MsgNum); + Assert.Equal("123456789012", jT808Package.Header.TerminalPhoneNo); + Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge); + Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackageIndex); + Assert.Equal(0, jT808Package.Header.MessageBodyProperty.PackgeCount); + Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt); + + //4.数据包体 + JT808_0x0200 jT808_0x0200 = (JT808_0x0200)jT808Package.Bodies; + Assert.Equal((uint)1, jT808_0x0200.AlarmFlag); + Assert.Equal((uint)40, jT808_0x0200.Altitude); + Assert.Equal(DateTime.Parse("2018-10-15 10:10:10"), jT808_0x0200.GPSTime); + Assert.Equal(12222222, jT808_0x0200.Lat); + Assert.Equal(132444444, jT808_0x0200.Lng); + Assert.Equal(60, jT808_0x0200.Speed); + Assert.Equal(0, jT808_0x0200.Direction); + Assert.Equal((uint)2, jT808_0x0200.StatusFlag); + //4.1.附加信息1 + Assert.Equal(100, ((JT808_0x0200_0x01)jT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x01]).Mileage); + //4.2.附加信息2 + Assert.Equal(125, ((JT808_0x0200_0x02)jT808_0x0200.JT808LocationAttachData[JT808_0x0200_BodyBase.AttachId0x02]).Oil); + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo3.cs b/src/JT808.Protocol.Test/Simples/Demo3.cs new file mode 100644 index 0000000..c12a109 --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo3.cs @@ -0,0 +1,53 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo3 + { + public JT808Serializer JT808Serializer; + public Demo3() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + + [Fact] + public void Test1() + { + JT808Package jT808Package = JT808MsgId.位置信息汇报.Create("123456789012", + new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-10-15 10:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808LocationAttachData = new Dictionary + { + { JT808_0x0200_BodyBase.AttachId0x01,new JT808_0x0200_0x01{Mileage = 100}}, + { JT808_0x0200_BodyBase.AttachId0x02,new JT808_0x0200_0x02{Oil = 125}} + } + }); + jT808Package.Header.MsgNum = 1; + byte[] data = JT808Serializer.Serialize(jT808Package); + var hex = data.ToHexString(); + //输出结果Hex: + //7E 02 00 00 26 12 34 56 78 90 12 00 01 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 6C 7E + //"7E020000261234567890120001000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D016C7E" + Assert.Equal("7E020000261234567890120001000000010000000200BA7F0E07E4F11C0028003C00001810151010100104000000640202007D016C7E", hex); + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo4.cs b/src/JT808.Protocol.Test/Simples/Demo4.cs new file mode 100644 index 0000000..97bd6ab --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo4.cs @@ -0,0 +1,355 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; +using JT808.Protocol.Formatters; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Attributes; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo4 + { + public JT808Serializer JT808Serializer; + public Demo4() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + } + private Dictionary cache = new Dictionary + { + { "123456789012",DeviceType.DT1 }, + { "123456789013",DeviceType.DT2 } + }; + /// + /// 处理多设备多协议附加信息Id冲突 + /// + [Fact] + public void Test1() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer demo5JT808Serializer = new JT808Serializer(jT808Config); + + JT808Package jT808Package = JT808MsgId.位置信息汇报.Create("123456789012", + new JT808_0x0200 + { + AlarmFlag = 1, + Altitude = 40, + GPSTime = DateTime.Parse("2018-12-20 20:10:10"), + Lat = 12222222, + Lng = 132444444, + Speed = 60, + Direction = 0, + StatusFlag = 2, + JT808CustomLocationAttachData = new Dictionary + { + {0x81,new JT808_0x0200_DT1_0x81 { + Age=15, + Gender=1, + UserName="smallchi" + } } + } + }); + + byte[] data = demo5JT808Serializer.Serialize(jT808Package); + var jT808PackageResult = demo5JT808Serializer.Deserialize(data); + JT808_0x0200 jT808_0X0200 = jT808PackageResult.Bodies as JT808_0x0200; + var attach = DeviceTypeFactory.Create(cache[jT808PackageResult.Header.TerminalPhoneNo], jT808_0X0200.JT808CustomLocationAttachOriginalData); + var extJson = attach.ExtData.Data.ToString(Formatting.None); + var attachinfo81 = (JT808_0x0200_DT1_0x81)attach.JT808CustomLocationAttachData[0x81]; + Assert.Equal((uint)15, attachinfo81.Age); + Assert.Equal(1, attachinfo81.Gender); + Assert.Equal("smallchi", attachinfo81.UserName); + } + } + + + public interface IExtData + { + JObject Data { get; set; } + } + + public interface IExtDataProcessor + { + void Processor(IExtData extData); + } + + public class JT808_0x0200_DT1_0x81_ExtDataProcessor : IExtDataProcessor + { + private JT808_0x0200_DT1_0x81 jT808_0X0200_DT1_0X81; + public JT808_0x0200_DT1_0x81_ExtDataProcessor(JT808_0x0200_DT1_0x81 jT808_0X0200_DT1_0X81) + { + this.jT808_0X0200_DT1_0X81 = jT808_0X0200_DT1_0X81; + } + public void Processor(IExtData extData) + { + extData.Data.Add(nameof(JT808_0x0200_DT1_0x81.Age), jT808_0X0200_DT1_0X81.Age); + extData.Data.Add(nameof(JT808_0x0200_DT1_0x81.UserName), jT808_0X0200_DT1_0X81.UserName); + extData.Data.Add(nameof(JT808_0x0200_DT1_0x81.Gender), jT808_0X0200_DT1_0X81.Gender); + } + } + + public class JT808_0x0200_DT1_0x82_ExtDataProcessor : IExtDataProcessor + { + private JT808_0x0200_DT1_0x82 jT808_0X0200_DT1_0X82; + public JT808_0x0200_DT1_0x82_ExtDataProcessor(JT808_0x0200_DT1_0x82 jT808_0X0200_DT1_0X82) + { + this.jT808_0X0200_DT1_0X82 = jT808_0X0200_DT1_0X82; + } + public void Processor(IExtData extData) + { + extData.Data.Add(nameof(JT808_0x0200_DT1_0x82.Gender1), jT808_0X0200_DT1_0X82.Gender1); + } + } + + public class JT808_0x0200_DT2_0x81_ExtDataProcessor : IExtDataProcessor + { + private JT808_0x0200_DT2_0x81 jT808_0X0200_DT2_0X81; + public JT808_0x0200_DT2_0x81_ExtDataProcessor(JT808_0x0200_DT2_0x81 jT808_0X0200_DT2_0X81) + { + this.jT808_0X0200_DT2_0X81 = jT808_0X0200_DT2_0X81; + } + public void Processor(IExtData extData) + { + extData.Data.Add(nameof(JT808_0x0200_DT2_0x81.Age), jT808_0X0200_DT2_0X81.Age); + extData.Data.Add(nameof(JT808_0x0200_DT2_0x81.Gender), jT808_0X0200_DT2_0X81.Gender); + } + } + + public class DeviceTypeFactory + { + public static DeviceTypeBase Create(DeviceType deviceType, Dictionary jT808CustomLocationAttachOriginalData) + { + switch (deviceType) + { + case DeviceType.DT1: + return new DeviceType1(jT808CustomLocationAttachOriginalData); + case DeviceType.DT2: + return new DeviceType2(jT808CustomLocationAttachOriginalData); + default: + return default; + } + } + } + + public enum DeviceType + { + DT1 = 1, + DT2 = 2 + } + + public abstract class DeviceTypeBase + { + protected JT808Serializer JT808Serializer; + protected class DefaultExtDataImpl : IExtData + { + public JObject Data { get; set; } = new JObject(); + } + public virtual IExtData ExtData { get; protected set; } = new DefaultExtDataImpl(); + public abstract Dictionary JT808CustomLocationAttachData { get; protected set; } + protected DeviceTypeBase(Dictionary jT808CustomLocationAttachOriginalData) + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + JT808Serializer = new JT808Serializer(jT808Config); + Execute(jT808CustomLocationAttachOriginalData); + } + protected abstract void Execute(Dictionary jT808CustomLocationAttachOriginalData); + } + + public class DeviceType1 : DeviceTypeBase + { + private const byte dt1_0x81 = 0x81; + private const byte dt1_0x82 = 0x82; + public DeviceType1(Dictionary jT808CustomLocationAttachOriginalData) : base(jT808CustomLocationAttachOriginalData) + { + } + public override Dictionary JT808CustomLocationAttachData { get; protected set; } + protected override void Execute(Dictionary jT808CustomLocationAttachOriginalData) + { + JT808CustomLocationAttachData = new Dictionary(); + foreach (var item in jT808CustomLocationAttachOriginalData) + { + try + { + switch (item.Key) + { + case dt1_0x81: + var info81 = JT808Serializer.Deserialize(item.Value); + if (info81 != null) + { + IExtDataProcessor extDataProcessor = new JT808_0x0200_DT1_0x81_ExtDataProcessor(info81); + extDataProcessor.Processor(ExtData); + JT808CustomLocationAttachData.Add(dt1_0x81, info81); + } + break; + case dt1_0x82: + var info82 = JT808Serializer.Deserialize(item.Value); + if (info82 != null) + { + IExtDataProcessor extDataProcessor = new JT808_0x0200_DT1_0x82_ExtDataProcessor(info82); + extDataProcessor.Processor(ExtData); + JT808CustomLocationAttachData.Add(dt1_0x82, info82); + } + break; + } + } + catch (Exception ex) + { + + } + } + } + } + + public class DeviceType2 : DeviceTypeBase + { + public DeviceType2(Dictionary jT808CustomLocationAttachOriginalData) : base(jT808CustomLocationAttachOriginalData) + { + } + public override Dictionary JT808CustomLocationAttachData { get; protected set; } + + private const byte dt2_0x81 = 0x81; + protected override void Execute(Dictionary jT808CustomLocationAttachOriginalData) + { + JT808CustomLocationAttachData = new Dictionary(); + foreach (var item in jT808CustomLocationAttachOriginalData) + { + try + { + switch (item.Key) + { + case dt2_0x81: + var info81 = JT808Serializer.Deserialize(item.Value); + if (info81 != null) + { + IExtDataProcessor extDataProcessor = new JT808_0x0200_DT2_0x81_ExtDataProcessor(info81); + extDataProcessor.Processor(ExtData); + JT808CustomLocationAttachData.Add(dt2_0x81, info81); + } + break; + } + } + catch (Exception) + { + + } + } + } + } + + /// + /// 设备类型1-对应消息协议0x81 + /// + [JT808Formatter(typeof(JT808_0x0200_DT1_0x81Formatter))] + public class JT808_0x0200_DT1_0x81 : JT808_0x0200_CustomBodyBase + { + public override byte AttachInfoId { get; set; } = 0x81; + public override byte AttachInfoLength { get; set; } = 13; + public uint Age { get; set; } + public byte Gender { get; set; } + public string UserName { get; set; } + } + /// + /// 设备类型1-对应消息协议0x82 + /// + [JT808Formatter(typeof(JT808_0x0200_DT1_0x82Formatter))] + public class JT808_0x0200_DT1_0x82 : JT808_0x0200_CustomBodyBase + { + public override byte AttachInfoId { get; set; } = 0x82; + public override byte AttachInfoLength { get; set; } = 1; + public byte Gender1 { get; set; } + } + /// + /// 设备类型2-对应消息协议0x81 + /// + [JT808Formatter(typeof(JT808_0x0200_DT2_0x81Formatter))] + public class JT808_0x0200_DT2_0x81 : JT808_0x0200_CustomBodyBase + { + public override byte AttachInfoId { get; set; } = 0x81; + public override byte AttachInfoLength { get; set; } = 7; + public uint Age { get; set; } + public byte Gender { get; set; } + public ushort MsgNum { get; set; } + } + /// + /// 设备类型1-对应消息协议序列化器 0x81 + /// + public class JT808_0x0200_DT1_0x81Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_DT1_0x81 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_DT1_0x81 jT808_0X0200_DT1_0X81 = new JT808_0x0200_DT1_0x81(); + jT808_0X0200_DT1_0X81.AttachInfoId = reader.ReadByte(); + jT808_0X0200_DT1_0X81.AttachInfoLength = reader.ReadByte(); + jT808_0X0200_DT1_0X81.Age = reader.ReadUInt32(); + jT808_0X0200_DT1_0X81.Gender = reader.ReadByte(); + jT808_0X0200_DT1_0X81.UserName = reader.ReadRemainStringContent(); + return jT808_0X0200_DT1_0X81; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_DT1_0x81 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteUInt32(value.Age); + writer.WriteByte(value.Gender); + writer.WriteString(value.UserName); + } + } + /// + /// 设备类型1-对应消息协议序列化器 0x82 + /// + public class JT808_0x0200_DT1_0x82Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_DT1_0x82 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_DT1_0x82 jT808_0X0200_DT1_0X82 = new JT808_0x0200_DT1_0x82(); + jT808_0X0200_DT1_0X82.AttachInfoId = reader.ReadByte(); + jT808_0X0200_DT1_0X82.AttachInfoLength = reader.ReadByte(); + jT808_0X0200_DT1_0X82.Gender1 = reader.ReadByte(); + return jT808_0X0200_DT1_0X82; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_DT1_0x82 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteByte(value.Gender1); + } + } + /// + /// 设备类型2-对应消息协议序列化器 0x81 + /// + public class JT808_0x0200_DT2_0x81Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_DT2_0x81 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_DT2_0x81 jT808_0X0200_DT2_0X81 = new JT808_0x0200_DT2_0x81(); + jT808_0X0200_DT2_0X81.AttachInfoId = reader.ReadByte(); + jT808_0X0200_DT2_0X81.AttachInfoLength = reader.ReadByte(); + jT808_0X0200_DT2_0X81.Age = reader.ReadUInt32(); + jT808_0X0200_DT2_0X81.Gender = reader.ReadByte(); + jT808_0X0200_DT2_0X81.MsgNum = reader.ReadUInt16(); + return jT808_0X0200_DT2_0X81; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_DT2_0x81 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteUInt32(value.Age); + writer.WriteByte(value.Gender); + writer.WriteUInt16(value.MsgNum); + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo5.cs b/src/JT808.Protocol.Test/Simples/Demo5.cs new file mode 100644 index 0000000..b21d927 --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo5.cs @@ -0,0 +1,96 @@ +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; +using System.Reflection; +using Xunit; +using System.Linq; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo5 + { + public JT808Serializer JT808Serializer; + public Demo5() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + jT808Config.SkipCRCCode = true; + JT808Serializer = new JT808Serializer(jT808Config); + } + + /// + /// 处理多媒体数据上传分包处理方式 + /// + [Fact] + public void Test1() + { + + //1.首先了解行业的分包策略 + //一般行业分包是按256的整数倍,太多不行,太少也不行,必须刚刚好 + //例:这边以256的3倍进行处理 + var quotient = 6935 / (256 * 3); + var remainder = 6935 % (256 * 3); + if (remainder != 0) + { + quotient = quotient + 1; + } + Assert.Equal(23, remainder); + Assert.Equal(10, quotient); + //得到有10包的数据 + + //2.根据以上信息,来解分包数据 + //第一包 有具体信息+多媒体 + //第二包 多媒体数据 + //... + //最N包 多媒体数据 + byte[] bytes1 = "7e080123240138123456782031000a00010000271d0000010100000000000c200301d2400a063296a501e100000000190104092952ffd8ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232fffe000b4750456e636f646572ffdb0043000d090a0b0a080d0b0a0b0e0e0d0f13201513121213271c1e17202e2931302e292d2c333a4a3e333646372c2d405741464c4e525352323e5a615a50604a51524fffdb0043010e0e0e131113261515264f352d354f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4fffc000110800f0014003012100021101031101ffc4001f000001050101010101010000000000000000010203041c7e".ToHexBytes(); + byte[] bytes2 = "7e080123000138123456782032000a000205060708090a0bffc400b5100002010303020403050504040000017d0101020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffdd00040000ffda000c03010002110311003f006c6a2a755ce299a5c942e0f35281c5004aa72314a54e38a07b8841ef4840a0673de21b4ff498ee402038dade991fe7f4acc110f4a0cd8ef2f1405cd01d45f2e9360a062edc5745616a6dad511861cfccff0053499512e056cf1460e3348a0ed4b8e338fc2819cb5edbfd9ee648b18556f97fdd3d3f4aafb4d332ea433a6573e9550d3131d18c9c558031c0a4083a503039a60c42c2984e4f4a06260d370690098ef4751400c615132d021868a621431a33480ef235e05595403eb54cbb0b8e7069dc0e3a9a41b12a024f4a9d40f4a18c5651e951c88179268194ee614b989a2719461ffea35cfdcda4b6b2ed71c1e55874345c96ba91819a704c50217613db349b39031c9e945c66a69ba794713cebf30fb8be9ee6b540c1e948a48760e3a526d2dc77a0a144471d297cb623a71484646bb685234b81d01d8e7d018f43f9ff003ac16386c552225b8300c2a84c8c8c4ed247b502616cc0517e".ToHexBytes(); + byte[] bytes3 = "7e080123000138123456782033000a0003b104558fe2c0a0561a4a2fde603ea69a67887f10fca80b8c33a960aa0b13d001d6a4f2e73d2d2e3f189a906e42653fdd23eb40dec3229dc7b91bc855b19e69c8dbc7d29081bad308a2e0308a6e281094b4c0efd41152a83815459623518c9a4000391f852192ad4c89923340131031c5579327822a4645e5f534bf6649c794f109037f0e33f8fb530226f0a1621a39bca1dc30dd4f8fc2d1a91be791cfb1007f2a9bb15916a3f0f59a0cb4793ebb98ff005a6369f6d6f70c6285548c60e327a5090f4e82f94b8e050235eb8cd3192000f6a76063a0a62b8840e83ad3447d02f487723b8b549edde09092b229527fad70d3c4e8ed1b7d01e462a7ea0e0d344b05538a8a7520676d0495611fbd1907a54ea3e623de80335d8b4849eb46334124d6937d019aee19b3808e0b7d013a1fd09aebc001871d0e2933481c83fdf6efc9fe75620c6de693d89452bb189734d82508ff0037434c4f72c821864546d4c08c9a4ed4084cd25203d284240e68db8e2acb628cf4a72825b9a2c05855e47bd4c1690c5ee39fca8f2c1393d2900151c8c0ad2b1882401f1f31efed43d81ec583498f6a424348acd9c66773ef8a10c6600c534af3c530142f7c52ede2818a073cd21a4034d739e21b411dca5c8185986d6f671fe23f9500f63194e1b069d20057a5324a9b3f7a1881c53e4555607d0168119772bb6e5fd09c8fc69b412275eb5d468f78b736b1c6cdfbd880571dc81d1bfcf7a4ca8bb330580dc40f53fcea488606293d86ad733e6ddb8ef3920d474c82cdbb020a9fc2a465c8a0688186293b5021292803d594074e7f0a89a160724552346089baa558c861c67f0a6c0777e94aa0e79a901ebef4fe31400a3a678ad4b7188231fecd0c4c7d01252101acc941f31ffde3fce84086e3bd2ed0062994252f14009c629b814804e38f5aaf7d016ab79672db9382c32a4f661d0d0338a91086391b4824303d88ea29c872281113a60f34c7e573e94c452d413947f6c5550322826c1814a32ac1d58ab0e841c11f8d0200cc3bd289a453f2b63f006931a644e4b1249e6a3a043a27dae0d5cc823340d0d2aa7ad3590638a632e77e".ToHexBytes(); + byte[] bytes4 = "7e080123000138123456782035000a00041208ed499f6a449ead03f1524846474abb1a0232820e29dc1e7ad20184e7a52a939a180f3c1a073dc502141c02066b5e2ff5298fee8a4c18b4b484277acb392324fbd34026de393d280a31c0a0a178f4a3ad001f8521a402714868039bf1159ecb85b940764dc37b3fff005c7f235891b6d6c1a043a5191915120c8c1a68457ba42d6ad9c165e7fc6b3874a04c3bd5ab3837923ece66661951e66deffafe74304421148ce08cfbd396dc367d026c52b82d4ad2aec62b9ce38a84d0480abb6bf347f8d0344a5451b01a650d31835198850267a4c6c78c54c32464d51403f3a777ce39fa5001c8e9d68f28c992cdc7a6290c9428005017b81400e00107e95ad19fdd27fba293131b24b1c632ed8cfe755daf3fb8871eadfe148446d7331fe20bf4150e6a876179c507ebcd2013bd2f7d02b40c303bd2607ad201300f4a69c77a01115ddba5d5bbc127dd71d7fba7b1fceb89ba824b79de39542ba1c30f5f71ed4d0d8d07726291461a8246b2fcecad92a47d029d0d63152ae55ba8e0d02618abb6ccb04f6f234ea132a5846fc8ee411498968439c28fa5393279ed40d22adcae253ef55cd0896255bb161b8a9eb8c8a016e5a75a68e0505aee148453623d063391565785e6ada180fa714ea401d3a5381cf7a00909e3af3429f97d01a900efa035a687f769fee8fe552c199ef966663f7893d699c81540213f4a33400bc91ed41ebd28181e7bd02900beb49c039a004e868c7ad218d3d39ac9d774ff00b4422e625ccb18c3003efaff0088ff001f6a019cc018e54e41a53c72699224bfc2c2b2af976cf9ecdcd026419ab576e860b4db22bb2c655b6f6e8403ef834988801cf34fdc7a0a0115e62c4fcc7245407ad026253a362ac18751c8a048d546124418742298460f34cd3a077a4228b08f404ed8a9d73deb41920507a52e30290213b50bd793480939a7a807f1a403fa0eb5a31f31a7a6d1fca930651907ccdfef1fe74dc647340119ebc11477a602f34bc628003d29052016909a0043cfad21e281a003e5e691b83c1a451ce6b3a68819aea15fdcb1f9947f013dfe9fcab16746d9f2119a09636305f17e".ToHexBytes(); + byte[] bytes5 = "7e080123000138123456782036000a0005e0d87395e39aa77d02bbe049076feb4c9281276123ae2b5756b69223120c1853708f1db2727f1e83f0a4dd848cec1cfd29caac4f14011dcc4ea4b31041f4aaadd681356128140917ac64f98c4ddf95feb53bafcd4ee5a0e945219e8082a55ad009948c0a0f5e690098e694601e68043875229c0f6348078208c55813b9558e24e40029010bee048239cf34c24fe1400879e86933c530173c71450028e68e7b5200cf1cd1d28189cf7a6f7a0033e941a431ac0104100823041ef5ce6a7a5b5bee96005adfa95ef1ff0088a00c644f2dfe5fba6a3963dc92463b8247f9fad3259931a6f9163e9bc85fcf8aeb6f915ecae5994102372323b80706a5847a9cb370dc5390f4e69b12dc5bbe62ace6a5109ee349a01a64122b302194e083915a88e254571d08fca8452131cd25319e82bd29ea735a0c91781c714b4807720d1d4d20141ff38a7fe14980e19c702b4605558548ee326a58156e062673ea47f21509071c53431a69b4c42f238a5140071d28a402fd68ebcd0310b718a414001e3ad44cf8e00cd21d803315191cd009c66819caf8996dec6680c3195926dc59411b703b8f7c9e9d2b145d6eb80a5782700e7f2a086ecc86e54db5d4770abb9438703d483922b7deee0bad3259607d01ca40057bae481823f1a182dce6dc0dec3d09a68386cd0224b878cc240910923b106b3de9209319494c81c2ae58cbb4b467a1e47d017bd0868b8453282cf425c60669c0815a88703e94e1f5a4317a914b9a005079a729f7a404d1f4e6b42123c95e73c5430655bac79bf85454c6842335191838a10064668ce7b531052e6818123346714804c8cf14848cd16018fcf5a3e5ce33cd2283349cd202b5e5a5ade2aa5ddba4a14e5438e95c8788eca1b3d563682210c32c61f0a30b9048381db803f3a052d88595590c728f620f5154e4b22afba07cfe383f9d321a20659d3ef231f7c66a32f92322810e7784a711b06c7d021fceaab74a1098ca4a04396a48d5f70d80ee078a011aad8e7151e683447a103c5387bd6a214714e07b5218eed49cd210b5228cd0c68915702afdb7302fe3fcea58d8c9e2df8651cd46b17e".ToHexBytes(); + byte[] bytes6 = "7e080123000138123456782037000a00062d98fde200fce95c02689121cae4b64724d553d734d0098a2988075e29739a061c75a43d6900a00f7cd21a010d23351f92a4e49a4324031c0a42300fafa503216697236c6847bb91fd2b03c636cd2e9b0cdb483149b49073856183fa85a2e26b42e2edbdd3ade5b8b433bcb023332ed0725413825811595aa69d0c16ed730a5cc2c1954233232f240f527f5a416b984d75872acac307069a6ef9fbb914c812496129cc0c0b742c8067f1aa0d4098ca4a091d19c383ef5a8846060505445249ed4d39c5051e8601ed4a2b5174179a72d201e791d680290583daa44f7340d130e956ed8feeb1e86a18c968a40417471171d73548903ad5201327a51d45301474a43d78a041d283f5a062134bee6800ed4dcd21a133c51d4521dc43ef54758b6375a45dc001666889503a961cafea0520650f0ccab2e816e158b142e873dbe6240fc88a678924f2ec2200f0f3a839f4dac7f9814093d0e36521a6761ce5891f9d307d01ea642dcd28119e103cc700f1818ac871c9a888e6b44454559980abf6d306f948e719a0a44ae48a8c927bd0ca3d21474a76dad405ed4a05210a4d00fbd0028fcaa44cd26324c9c60d5ab5276107d6a58c9ba5213807daa40a72c85db3dbb66a02393d7156803b51da80141a0d00379cd19e6980734a6a404cfe2293ad030cf3d69290087ad267041f439a0673de1b516a752d3c2b0fb3dc92a4f752303f44cfe351f8ad87d8201d499f3f9237f88a5d457f74e489e4d20eb4cccd4b63fba0738ac89861d87bd4c772e7b101a43546402acdb1fde7e140e25966cd309a451e96b8c53b391c56cc032334b9ed4ba007229473400e5f5ef5203498c783ed566d8f2c3f1a96327c8f4aad7126ef917a0eb490105348f6a60373da81f4aa00e334669083a77d02b49939a00075a318340c3f4a0e290c4ef487af1486235337608c73cd0c673da0e9c63b896f9aefce626481814e490e0649cfa2838c77aafe2e3f2d90c9c7ef4ffe81fe34913f64e58f5a55049e29999ab021f2c2e39ac8b9c79cf8e066a22f52e7b15cd2559900a9adff00d60a06b72e374a61a459e97818a33c735b517e".ToHexBytes(); + byte[] bytes7 = "7e080123000138123456782039000a0007083753860d0201eb474249a431c0e3be69e0feb40c78e9cd4f6ee164e4f0c3152c09e57f2d38fbc7a553e49e7a9a48628cd205c0ed400df6a4ebc835420a3a74a0043463b5201067d453bad0310d2521852646290c6139a6e307e94018fa080a9a8afa6a330ffd06b27c5b213776f1e785889c7d015bff00b1fd2844bd8e74d2ae148dd43211785f4318eacc7fd95ff1ace9dc492b3818c92706a522e72bab101a61aa320152c270e28045eea29bde91a1e900e40ce29df4ad84181fe34bdb148017a7ad29191c1e28004523bfeb52af4a0687678a5cf03fc6900fdc4f2c72693d719a40814f34ee3191487718c78f534cfa55210527d2900528a6301d68ed4803eb49f5a43427e34879a430f6a6b71de90185a54d1c17fa9d9cce893bde3cc8acc01757c118f5e954f58b34bef10c56f2dca5b462d4349230e803bf41dc9240fc68b93ba33aef4db479c47a79b928bd65b8651bbaf450338fa9cfb53e3b3d3e1426e2de795c63ef30c1fa053fce84db1596e4332d938262b344278c3123f406b1e7016420631ed4214add080d34d32029e870c0d008be0fca28a469d0f46538a767dab6b08307ae452e79a02c3c0f6a5e280157834ef6a43428a5079e2900e5a53de90c4ce0d283400d61f5a667d29a00e293340833cd3a90013471c7340c4a3ad218d079a53eff00a5201a698719e681952fac6d2f902dd4092606031e187d0108e4571da9eed3b549618a5790441510ca7710a541c7b637629589969b14cea175962b22ae7fba8bf9722a169e763969a4fc188a6436205790e0b649fef1a8e58cc6d8241fa52b85b42134ca64853875a00bf09cc629c691a743d1507a53803bab7247f51487afad20147b529a060bc53b3f4a40283c734e1dbd6818e1c1a71a402639a00f5a0071195a85bae69218ccf3d697b5310718a39ec2801d9a09e290c4cf3d68ef498c4cf3f4a42690210f4a6e05031ae462b83f104825d5ee88c7126dff00be542ffecb40a5b1979a51419a244201a8e76dcf483a15cf5a6d3244a506802edb1fddd48c78a562d6c7a42e78152003ad6c21718a61ebc503140e79a0f5c57e".ToHexBytes(); + byte[] bytes8 = "7e08012300013812345678203a000a0008e050003d69c39148078a75030073cd2e49a402819a4ce38a100ecf1cd31c11490c8f1ef4d2714c419e697340200d9e28c8cd0302e0537713d2900b839a711523108f6a61e940d0c6e481d2bcef527126a172ebd1a7908ffbecd3265b1529b9a4412c43229938c3500f62b93494122502802dda9e08a9cfa522d6c7a4af4a7027b56cc07751cd37239a003349df02801ca29e01cd201e07ad35b9c8eded4863870296800fc6900e7d01e818ece3a8e29924c8382d4ac0425d4f3918fcf346e07bfe54c41de940e280414c7ce06290d0880f7a9028a40380e48a5268631b8ebe9519e3a5201bbb69dc7a0e4d798e7f7683fd914132129941058807cb51dce7752ea37b158d253244a050059b53f362ad1eb525ad8f4843c52b673c56e02eee314dcf6a40380cf6a728e78a02c380a7724d0324c7151b019ef48031c7b8a51db8c9a00701bbd2823029019f7b3b2f0a08acc6f3a46ea49f6a4d945eb585f6fef2ae2a63914d09ee3b1487a5315c074a303bd200e94a39a063b9141e9d290d0c272714d3d7a74a4329ea6e63d32f1c1c15b79083efb4e2bcea4c6ec0e8381411313b532820b76e3e5a86ec7cf496e53d8aa69299025140135b9c3d5c26917167a5a8c2d2119e6b604369ebc9a043a9573e940c701eb4ec60648a43149fca8efcd201a41fafd2973d38a00907e82931da9011490abff0d462dd57955c51618e031d051f8d3105250c04c668c7a50160fc29d8e3b5218a38a3ad218d34da00cbf11b32e857454e090a99f666507f426b8173f3923d6826436900e69106a4501f211d57aa838aa179feb2a22f53492b22a9eb4dab3210d1401243f7c55ea0a47a59e94bdb9ad46263238a700062801ddf9a075a063874e3a0a5038a4027d290668121738a51d7148a2651c507bfa5480da461ef4c061fc2986a84250460520003bf5cfa526da005007526979a06264fad2e38a4034e477a692690cc3f16c853485453feb27453f400b7f3515c4b0e68225b801c53e38c33804f7a4248d9b71b620a3a0e0565ea8a05c123bd4477349af74cf34dab310c5262801f1fdf15a1fc2291713d29e17e".ToHexBytes(); + byte[] bytes9 = "7e08012300013812345678203b000a000979e3a53f19c56e00571401c83e94807751477a062f7a334806939a51400ee714e51ce6900fcf6a5c8c62a4634900e05464f38a6806f4149926a8570fc281f4a00300f5147514804cf38ef4a46690d09c62973e94980c6e05373c734586735e309084b3887d01d66773f50001ff00a11ae5475a4449ea3a917a8a03a9b96e331afd05656abff1f1f854477349fc2671a6d5988525021cbf785690c14071499713d1d6a5e715b80b8a41c5031e3d7a51838a9005ce6822801b8c7ffaa9caa3a8a00514f0063ae6a406938e9c500d3189c93d29ac0d0210d3698801e334eea3fa50301411405841cd21a430f6a09348686923bd37a0c0a40723e2d918ea11467d02ea4008fab31cff00e822b0145043dc5229557914811b36ff00eac7d2b2b533998d4477349ec67914d356602514000eb5a28dfbb1499513d2e300549c56c317391d29b8a009171dea4c6471c5263136e39a69eb4806d2e71da980139e3934a091ee29580060d03b71de900a00fad35a980d6a691d85001e94a05300ed49ef4009c75c51d690c404678a2a410c6a6ee3eb40d1c4788df76b574339d9b147e083fa9359a9410c76053d00dc2902352318502b2750e6723d2a62692d8a2d4d35460211498a003bd5f888f2c50ca47a62364022a4072335b0c55c9a5c67b5218a3838e69eadf4a403b3c534f348031c51b7d2800dbcf4a52bdfad201b4ee9cd00216fad464f3c9cfd280140e39cd3714c050b498e7ad0027b671450c2e21e4534d0019f6a439a43434f4e69a4f6148a380d4dfccd46e9f76eccefce7a80c40fd00aacb4198a4e29eae030c52046ba8205635f9ff486a989a4f6291eb486a8c46d250201d6ae43f7052291e8f6d28c0c9e2ae2e36e715b8c701de9c0fd6a405e0f14a3e940c3bd2e38a4029e3147005200f4a427b50027f5a4ddda9821a7149804d031c41e9498f4033ed400e031d69ac31d29086f5a4fd6a806fe94948000a53d3148a18c31e86a3670877b7217938f41480f36e91203fdd1403c506605b1525b61a6553d09a4f61adcdf8903b2a138cfa75c77ac1d54a7db64f2d76a6e3b46738fc6b38b6b7e".ToHexBytes(); + byte[] bytes10 = "7e08012017013812345678203c000a000ad4dea2f72e50269b5a1ca251400a2ad427e5a4ca47ffd9d17e".ToHexBytes(); + + JT808Package jT808_0X0801_1 = JT808Serializer.Deserialize(bytes1); + JT808Package jT808_0X0801_2 = JT808Serializer.Deserialize(bytes2); + JT808Package jT808_0X0801_3 = JT808Serializer.Deserialize(bytes3); + JT808Package jT808_0X0801_4 = JT808Serializer.Deserialize(bytes4); + JT808Package jT808_0X0801_5 = JT808Serializer.Deserialize(bytes5); + JT808Package jT808_0X0801_6 = JT808Serializer.Deserialize(bytes6); + JT808Package jT808_0X0801_7 = JT808Serializer.Deserialize(bytes7); + JT808Package jT808_0X0801_8 = JT808Serializer.Deserialize(bytes8); + JT808Package jT808_0X0801_9 = JT808Serializer.Deserialize(bytes9); + JT808Package jT808_0X0801_10 = JT808Serializer.Deserialize(bytes10); + + var jT808_0X0801_body_1 = jT808_0X0801_1.Bodies as JT808_0x0801; + var jT808_0X0801_body_2 = jT808_0X0801_2.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_3 = jT808_0X0801_3.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_4 = jT808_0X0801_4.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_5 = jT808_0X0801_5.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_6 = jT808_0X0801_6.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_7 = jT808_0X0801_7.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_8 = jT808_0X0801_8.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_9 = jT808_0X0801_9.Bodies as JT808SplitPackageBodies; + var jT808_0X0801_body_10 = jT808_0X0801_10.Bodies as JT808SplitPackageBodies; + var imageBytes = jT808_0X0801_body_1.MultimediaDataPackage + .Concat(jT808_0X0801_body_2.Data) + .Concat(jT808_0X0801_body_3.Data) + .Concat(jT808_0X0801_body_4.Data) + .Concat(jT808_0X0801_body_5.Data) + .Concat(jT808_0X0801_body_6.Data) + .Concat(jT808_0X0801_body_7.Data) + .Concat(jT808_0X0801_body_8.Data) + .Concat(jT808_0X0801_body_9.Data) + .Concat(jT808_0X0801_body_10.Data).ToArray(); + //using (MemoryStream ms = new MemoryStream(imageBytes)) + //{ + // Image image = Image.FromStream(ms); + // image.Save("test.jpeg"); + //} + } + } +} diff --git a/src/JT808.Protocol.Test/Simples/Demo6.cs b/src/JT808.Protocol.Test/Simples/Demo6.cs new file mode 100644 index 0000000..3f8f8b3 --- /dev/null +++ b/src/JT808.Protocol.Test/Simples/Demo6.cs @@ -0,0 +1,132 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; +using JT808.Protocol.Formatters; +using JT808.Protocol.MessagePack; +using JT808.Protocol.Attributes; +using JT808.Protocol.Internal; + +namespace JT808.Protocol.Test.Simples +{ + public class Demo6 + { + public JT808Serializer JT808Serializer; + public Demo6() + { + IJT808Config jT808Config = new DefaultGlobalConfig(); + jT808Config.Register(Assembly.GetExecutingAssembly()); + //根据不同的设备终端号,添加自定义消息Id + jT808Config.MsgIdFactory.CustomSetMap(0x91, "1234567891"); + jT808Config.MsgIdFactory.CustomSetMap(0x91, "1234567892"); + JT808Serializer = new JT808Serializer(jT808Config); + } + + /// + /// 处理多设备多协议消息Id冲突 + /// + [Fact] + public void Test1() + { + JT808Package dt1Package = new JT808Package(); + dt1Package.Header = new JT808Header + { + MsgId = 0x91, + MsgNum = 126, + TerminalPhoneNo = "1234567891" + }; + DT1Demo6 dT1Demo6 = new DT1Demo6(); + dT1Demo6.Age1 = 18; + dT1Demo6.Sex1 = 2; + dt1Package.Bodies = dT1Demo6; + + JT808Package dt2Package = new JT808Package(); + dt2Package.Header = new JT808Header + { + MsgId = 0x91, + MsgNum = 126, + TerminalPhoneNo = "1234567892" + }; + DT2Demo6 dT2Demo6 = new DT2Demo6(); + dT2Demo6.Age2 = 18; + dT2Demo6.Sex2 = 2; + dt2Package.Bodies = dT2Demo6; + byte[] dt1Data = JT808Serializer.Serialize(dt1Package); + var dt1Hex = dt1Data.ToHexString(); + //7E00910003001234567891007D02020012657E + byte[] dt2Data = JT808Serializer.Serialize(dt2Package); + var dt2Hex = dt2Data.ToHexString(); + //7E00910003001234567892007D02020012667E + Assert.Equal("7E00910003001234567891007D02020012657E", dt1Hex); + Assert.Equal("7E00910003001234567892007D02020012667E", dt2Hex); + + JT808Package dt1Package1 = JT808Serializer.Deserialize(dt1Data); + Assert.Equal(0x91, dt1Package1.Header.MsgId); + Assert.Equal(126, dt1Package1.Header.MsgNum); + Assert.Equal("1234567891", dt1Package1.Header.TerminalPhoneNo); + DT1Demo6 dt1Bodies = (DT1Demo6)dt1Package1.Bodies; + Assert.Equal((ushort)18, dt1Bodies.Age1); + Assert.Equal(2, dt1Bodies.Sex1); + + JT808Package dt2Package1 = JT808Serializer.Deserialize(dt2Data); + Assert.Equal(0x91, dt2Package1.Header.MsgId); + Assert.Equal(126, dt2Package1.Header.MsgNum); + Assert.Equal("1234567892", dt2Package1.Header.TerminalPhoneNo); + DT2Demo6 dt2Bodies = (DT2Demo6)dt2Package1.Bodies; + Assert.Equal((ushort)18, dt2Bodies.Age2); + Assert.Equal(2, dt2Bodies.Sex2); + } + } + + [JT808Formatter(typeof(DT1Demo6_Formatter))] + public class DT1Demo6 : JT808Bodies + { + public byte Sex1 { get; set; } + + public ushort Age1 { get; set; } + } + [JT808Formatter(typeof(DT2Demo6_Formatter))] + public class DT2Demo6 : JT808Bodies + { + public byte Sex2 { get; set; } + + public ushort Age2 { get; set; } + } + public class DT1Demo6_Formatter : IJT808MessagePackFormatter + { + public DT1Demo6 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + DT1Demo6 dT1Demo6 = new DT1Demo6(); + dT1Demo6.Sex1 = reader.ReadByte(); + dT1Demo6.Age1 = reader.ReadUInt16(); + return dT1Demo6; + } + + public void Serialize(ref JT808MessagePackWriter writer, DT1Demo6 value, IJT808Config config) + { + writer.WriteByte(value.Sex1); + writer.WriteUInt16(value.Age1); + } + } + public class DT2Demo6_Formatter : IJT808MessagePackFormatter + { + public DT2Demo6 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + DT2Demo6 dT2Demo6 = new DT2Demo6(); + dT2Demo6.Sex2 = reader.ReadByte(); + dT2Demo6.Age2 = reader.ReadUInt16(); + return dT2Demo6; + } + + public void Serialize(ref JT808MessagePackWriter writer, DT2Demo6 value, IJT808Config config) + { + writer.WriteByte(value.Sex2); + writer.WriteUInt16(value.Age2); + } + } +} diff --git a/src/JT808.Protocol.Test/SplitPackageStrategyTest.cs b/src/JT808.Protocol.Test/SplitPackageStrategyTest.cs new file mode 100644 index 0000000..d959108 --- /dev/null +++ b/src/JT808.Protocol.Test/SplitPackageStrategyTest.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using System; +using System.IO; +using Xunit; + +namespace JT808.Protocol.Test +{ + public class SplitPackageStrategyTest + { + [Fact] + public void Test1() + { + IJT808SplitPackageStrategy splitPackageStrategy = new DefaultSplitPackageStrategyImpl(); + byte[] data; + using (FileStream input = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", "test.txt"))) + { + data = new byte[input.Length]; + input.Read(data, 0, (int)input.Length); + } + var result = splitPackageStrategy.Processor(data); + } + } +} diff --git a/src/JT808.Protocol.sln b/src/JT808.Protocol.sln new file mode 100644 index 0000000..e0964df --- /dev/null +++ b/src/JT808.Protocol.sln @@ -0,0 +1,55 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.352 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol", "JT808.Protocol\JT808.Protocol.csproj", "{6259F511-97FF-4E8D-99EB-C5BB6F2B1069}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Test", "JT808.Protocol.Test\JT808.Protocol.Test.csproj", "{51E98B6A-E350-4E2C-A9C5-78C8B400DA72}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E6296ADE-B239-4A4B-ACDA-B80C0A61399B}" + ProjectSection(SolutionItems) = preProject + ..\.travis.yml = ..\.travis.yml + ..\README.md = ..\README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Benchmark", "JT808.Protocol.Benchmark\JT808.Protocol.Benchmark.csproj", "{04966672-8FC4-42F2-BF0F-9E367A8FC5AF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Extensions.DependencyInjection", "JT808.Protocol.Extensions.DependencyInjection\JT808.Protocol.Extensions.DependencyInjection.csproj", "{B5F627C8-D3EF-4DE2-B2F0-249595D170E1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol.Extensions.DependencyInjection.Test", "JT808.Protocol.Extensions.DependencyInjection.Test\JT808.Protocol.Extensions.DependencyInjection.Test.csproj", "{B5B337C9-5C40-4DFD-BC8D-B0EA7F2F2F15}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6259F511-97FF-4E8D-99EB-C5BB6F2B1069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6259F511-97FF-4E8D-99EB-C5BB6F2B1069}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6259F511-97FF-4E8D-99EB-C5BB6F2B1069}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6259F511-97FF-4E8D-99EB-C5BB6F2B1069}.Release|Any CPU.Build.0 = Release|Any CPU + {51E98B6A-E350-4E2C-A9C5-78C8B400DA72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51E98B6A-E350-4E2C-A9C5-78C8B400DA72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51E98B6A-E350-4E2C-A9C5-78C8B400DA72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51E98B6A-E350-4E2C-A9C5-78C8B400DA72}.Release|Any CPU.Build.0 = Release|Any CPU + {04966672-8FC4-42F2-BF0F-9E367A8FC5AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04966672-8FC4-42F2-BF0F-9E367A8FC5AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04966672-8FC4-42F2-BF0F-9E367A8FC5AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04966672-8FC4-42F2-BF0F-9E367A8FC5AF}.Release|Any CPU.Build.0 = Release|Any CPU + {B5F627C8-D3EF-4DE2-B2F0-249595D170E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F627C8-D3EF-4DE2-B2F0-249595D170E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5F627C8-D3EF-4DE2-B2F0-249595D170E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5F627C8-D3EF-4DE2-B2F0-249595D170E1}.Release|Any CPU.Build.0 = Release|Any CPU + {B5B337C9-5C40-4DFD-BC8D-B0EA7F2F2F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5B337C9-5C40-4DFD-BC8D-B0EA7F2F2F15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5B337C9-5C40-4DFD-BC8D-B0EA7F2F2F15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5B337C9-5C40-4DFD-BC8D-B0EA7F2F2F15}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D58CCAA8-ED94-4048-A6DE-55A84814DF17} + EndGlobalSection +EndGlobal diff --git a/src/JT808.Protocol/Attributes/JT808BodiesTypeAttribute.cs b/src/JT808.Protocol/Attributes/JT808BodiesTypeAttribute.cs new file mode 100644 index 0000000..0c286d6 --- /dev/null +++ b/src/JT808.Protocol/Attributes/JT808BodiesTypeAttribute.cs @@ -0,0 +1,14 @@ +using System; + +namespace JT808.Protocol.Attributes +{ + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class JT808BodiesTypeAttribute : Attribute + { + public JT808BodiesTypeAttribute(Type jT808BodiesType) + { + JT808BodiesType = jT808BodiesType; + } + public Type JT808BodiesType { get; } + } +} diff --git a/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs b/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs new file mode 100644 index 0000000..18cf8cc --- /dev/null +++ b/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Attributes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] + public sealed class JT808FormatterAttribute : Attribute + { + public Type FormatterType { get; private set; } + + public JT808FormatterAttribute(Type formatterType) + { + this.FormatterType = formatterType; + } + } +} diff --git a/src/JT808.Protocol/Attributes/JT808MsgIdDescriptionAttribute.cs b/src/JT808.Protocol/Attributes/JT808MsgIdDescriptionAttribute.cs new file mode 100644 index 0000000..e89d027 --- /dev/null +++ b/src/JT808.Protocol/Attributes/JT808MsgIdDescriptionAttribute.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Attributes +{ + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class JT808MsgIdDescriptionAttribute : Attribute + { + public string Code { get; set; } + + public string Name { get; set; } + + public JT808MsgIdDescriptionAttribute(string code, string name) + { + Code = code; + Name = name; + } + } +} diff --git a/src/JT808.Protocol/Buffers/JT808BufferWriter.cs b/src/JT808.Protocol/Buffers/JT808BufferWriter.cs new file mode 100644 index 0000000..536e04a --- /dev/null +++ b/src/JT808.Protocol/Buffers/JT808BufferWriter.cs @@ -0,0 +1,29 @@ +using System; + +namespace JT808.Protocol.Buffers +{ + /// + /// + /// + ref partial struct JT808BufferWriter + { + private Span _buffer; + public JT808BufferWriter(Span buffer) + { + _buffer = buffer; + WrittenCount = 0; + BeforeCodingWrittenPosition = 0; + } + public Span Free => _buffer.Slice(WrittenCount); + public Span Written => _buffer.Slice(0, WrittenCount); + /// + /// 编码之前的写入位置 + /// + public int BeforeCodingWrittenPosition { get;internal set; } + public int WrittenCount { get; private set; } + public void Advance(int count) + { + WrittenCount += count; + } + } +} diff --git a/src/JT808.Protocol/Enums/JT808Alarm.cs b/src/JT808.Protocol/Enums/JT808Alarm.cs new file mode 100644 index 0000000..33bc2e3 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808Alarm.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Enums +{ + /// + /// 报警标志 + /// + [Flags] + public enum JT808Alarm : uint + { + /// + /// 紧急报警_触动报警开关后触发 + /// 收到应答后清零 + /// + 紧急报警_触动报警开关后触发 = 1, + /// + /// 超速报警 + /// 标志维持至报警条件解除 + /// + 超速报警 = 2, + /// + /// 标志维持至报警条件解除 + /// 疲劳驾驶 + /// + 疲劳驾驶 = 4, + /// + /// 危险预警 + /// 收到应答后清零 + /// + 危险预警 = 8, + /// + /// GNSS模块发生故障 + /// 标志维持至报警条件解除 + /// + GNSS模块发生故障 = 16, + /// + /// GNSS天线未接或被剪断 + /// 标志维持至报警条件解除 + /// + GNSS天线未接或被剪断 = 32, + /// + /// GNSS天线短路 + /// 标志维持至报警条件解除 + /// + GNSS天线短路 = 64, + /// + /// 终端主电源欠压 + /// 标志维持至报警条件解除 + /// + 终端主电源欠压 = 128, + /// + /// 终端主电源掉电 + /// 标志维持至报警条件解除 + /// + 终端主电源掉电 = 256, + /// + /// 终端LCD或显示器故障 + /// 标志维持至报警条件解除 + /// + 终端LCD或显示器故障 = 512, + /// + /// TTS模块故障 + /// 标志维持至报警条件解除 + /// + TTS模块故障 = 1024, + /// + /// 摄像头故障 + /// 标志维持至报警条件解除 + /// + 摄像头故障 = 2048, + /// + /// 道路运输证IC卡模块故障 + /// 标志维持至报警条件解除 + /// + 道路运输证IC卡模块故障 = 4096, + /// + /// 超速预警 + /// 标志维持至报警条件解除 + /// + 超速预警 = 8192, + /// + /// 疲劳驾驶预警 + /// 标志维持至报警条件解除 + /// + 疲劳驾驶预警 = 16384, + 保留1 = 32768, + 保留2 = 65536, + 保留3 = 131072, + /// + /// 当天累计驾驶超时 + /// 标志维持至报警条件解除 + /// + 当天累计驾驶超时 = 262144, + /// + /// 超时停车 + /// 标志维持至报警条件解除 + /// + 超时停车 = 524288, + /// + /// 进出区域 + /// 收到应答后清零 + /// + 进出区域 = 1048576, + /// + /// 进出路线 + /// 收到应答后清零 + /// + 进出路线 = 2097152, + /// + /// 路段行驶时间不足或过长 + /// 收到应答后清零 + /// + 路段行驶时间不足或过长 = 4194304, + /// + /// 路线偏离报警 + /// 标志维持至报警条件解除 + /// + 路线偏离报警 = 8388608, + /// + /// 车辆VSS故障 + /// 标志维持至报警条件解除 + /// + 车辆VSS故障 = 16777216, + /// + /// 车辆油量异常 + /// 标志维持至报警条件解除 + /// + 车辆油量异常 = 33554432, + /// + /// 车辆被盗通过车辆防盗器 + /// 标志维持至报警条件解除 + /// + 车辆被盗 = 67108864, + /// + /// 车辆非法点火 + /// + 车辆非法点火 = 134217728, + /// + /// 车辆非法位移 + /// 收到应答后清零 + /// + 车辆非法位移 = 268435456, + /// + /// 碰撞预警 + /// 标志维持至报警条件解除 + /// + 碰撞预警 = 536870912, + /// + /// 侧翻预警 + /// 标志维持至报警条件解除 + /// + 侧翻预警 = 1073741824, + /// + /// 非法开门报警 + /// (终端未设置区域时,不判断非法开门) + /// 收到应答后清零 + /// + 非法开门报警 = 2147483648 + } +} diff --git a/src/JT808.Protocol/Enums/JT808CallBackType.cs b/src/JT808.Protocol/Enums/JT808CallBackType.cs new file mode 100644 index 0000000..53c3151 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808CallBackType.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 电话回拨类型 + /// + public enum JT808CallBackType : byte + { + 普通通话 = 0, + 监听 = 1 + } +} diff --git a/src/JT808.Protocol/Enums/JT808DirectionType.cs b/src/JT808.Protocol/Enums/JT808DirectionType.cs new file mode 100644 index 0000000..7982773 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808DirectionType.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 方向类型 + /// + public enum JT808DirectionType : byte + { + 进 = 0, + 出 = 1 + } +} diff --git a/src/JT808.Protocol/Enums/JT808DrivenRouteType.cs b/src/JT808.Protocol/Enums/JT808DrivenRouteType.cs new file mode 100644 index 0000000..33a3024 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808DrivenRouteType.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 路线行驶返回结果 + /// + public enum JT808DrivenRouteType + { + 不足 = 0, + 过长 = 1 + } +} diff --git a/src/JT808.Protocol/Enums/JT808EncryptMethod.cs b/src/JT808.Protocol/Enums/JT808EncryptMethod.cs new file mode 100644 index 0000000..aaf53c4 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808EncryptMethod.cs @@ -0,0 +1,8 @@ +namespace JT808.Protocol.Enums +{ + public enum JT808EncryptMethod + { + None, + RSA + } +} diff --git a/src/JT808.Protocol/Enums/JT808ErrorCode.cs b/src/JT808.Protocol/Enums/JT808ErrorCode.cs new file mode 100644 index 0000000..f36d2fe --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808ErrorCode.cs @@ -0,0 +1,37 @@ +namespace JT808.Protocol.Enums +{ + public enum JT808ErrorCode + { + /// + /// 校验和不相等 + /// + CheckCodeNotEqual = 1001, + /// + /// 没有标记 + /// + /// + GetFormatterAttributeError = 1002, + /// + /// 消息头解析错误 + /// + HeaderParseError = 1003, + /// + /// 消息体解析错误 + /// + BodiesParseError = 1004, + GetAttributeError = 1005, + /// + /// 没有实现对应的类型 + /// + NotImplType = 1006, + /// + /// 长度不够 + /// + NotEnoughLength = 1007, + /// + /// 没有全局注册格式化器 + /// + /// + NotGlobalRegisterFormatterAssembly = 1008 + } +} diff --git a/src/JT808.Protocol/Enums/JT808EventItemCoding.cs b/src/JT808.Protocol/Enums/JT808EventItemCoding.cs new file mode 100644 index 0000000..be3f626 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808EventItemCoding.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 事件项编码 + /// + public enum JT808EventItemCoding : byte + { + 平台下发指令 = 0x00, + 定时动作 = 0x01, + 抢劫报警触发 = 0x02, + 碰撞侧翻报警触发 = 0x03 + } +} diff --git a/src/JT808.Protocol/Enums/JT808EventSettingType.cs b/src/JT808.Protocol/Enums/JT808EventSettingType.cs new file mode 100644 index 0000000..c3317fb --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808EventSettingType.cs @@ -0,0 +1,29 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 事件设置类型 + /// + public enum JT808EventSettingType : byte + { + /// + /// 删除终端现有所有事件_该命令后不带后继字节 + /// + 删除终端现有所有事件_该命令后不带后继字节 = 0x00, + /// + /// 更新事件 + /// + 更新事件 = 0x01, + /// + /// 追加事件 + /// + 追加事件 = 0x02, + /// + /// 修改事件 + /// + 修改事件 = 0x03, + /// + /// 删除特定几项事件,之后事件项中无需带事件内容 + /// + 删除特定几项事件_之后事件项中无需带事件内容 = 0x04 + } +} diff --git a/src/JT808.Protocol/Enums/JT808ICCardReadResult.cs b/src/JT808.Protocol/Enums/JT808ICCardReadResult.cs new file mode 100644 index 0000000..afe9010 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808ICCardReadResult.cs @@ -0,0 +1,14 @@ +namespace JT808.Protocol.Enums +{ + /// + /// IC 卡读取结果 + /// + public enum JT808ICCardReadResult : byte + { + IC卡读卡成功 = 0x00, + 读卡失败_原因为卡片密钥认证未通过 = 0x01, + 读卡失败_原因为卡片已被锁定 = 0x02, + 读卡失败_原因为卡片被拔出 = 0x03, + 读卡失败_原因为数据校验错误 = 0x04, + } +} diff --git a/src/JT808.Protocol/Enums/JT808ICCardStatus.cs b/src/JT808.Protocol/Enums/JT808ICCardStatus.cs new file mode 100644 index 0000000..9b246d3 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808ICCardStatus.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 插拔状态 + /// + public enum JT808ICCardStatus : byte + { + 从业资格证IC卡插入_驾驶员上班 = 0x01, + 从业资格证IC卡拔出_驾驶员下班 = 0x02 + } +} diff --git a/src/JT808.Protocol/Enums/JT808InformationSettingType.cs b/src/JT808.Protocol/Enums/JT808InformationSettingType.cs new file mode 100644 index 0000000..8c6c6d4 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808InformationSettingType.cs @@ -0,0 +1,25 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 信息设置类型 + /// + public enum JT808InformationSettingType : byte + { + /// + /// 删除终端全部信息项 + /// + 删除终端全部信息项 = 0x00, + /// + /// 更新菜单 + /// + 更新菜单 = 0x01, + /// + /// 追加菜单 + /// + 追加菜单 = 0x02, + /// + /// 修改菜单 + /// + 修改菜单 = 0x03 + } +} diff --git a/src/JT808.Protocol/Enums/JT808MsgId.cs b/src/JT808.Protocol/Enums/JT808MsgId.cs new file mode 100644 index 0000000..68d7b57 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808MsgId.cs @@ -0,0 +1,461 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Enums +{ + /// + /// JT808消息 + /// + public enum JT808MsgId : ushort + { + /// + /// 终端通用应答 + /// 0x0001 + /// + [JT808BodiesType(typeof(JT808_0x0001))] + [JT808MsgIdDescription("0x0001", "终端通用应答")] + 终端通用应答 = 0x0001, + /// + /// 平台通用应答 + /// 0x8001 + /// + [JT808BodiesType(typeof(JT808_0x8001))] + [JT808MsgIdDescription("0x8001", "平台通用应答")] + 平台通用应答 = 0x8001, + /// + /// 终端心跳 + /// 0x0002 + /// + [JT808BodiesType(typeof(JT808_0x0002))] + [JT808MsgIdDescription("0x0002", "终端心跳")] + 终端心跳 = 0x0002, + /// + /// 补传分包请求 + /// 0x8003 + /// + [JT808BodiesType(typeof(JT808_0x8003))] + [JT808MsgIdDescription("0x8003", "补传分包请求")] + 补传分包请求 = 0x8003, + /// + /// 终端注册 + /// 0x0100 + /// + [JT808BodiesType(typeof(JT808_0x0100))] + [JT808MsgIdDescription("0x0100", "终端注册")] + 终端注册 = 0x0100, + /// + /// 终端注册应答 + /// 0x8100 + /// + [JT808BodiesType(typeof(JT808_0x8100))] + [JT808MsgIdDescription("0x8100", "终端注册应答")] + 终端注册应答 = 0x8100, + /// + /// 终端注销 + /// 0x0003 + /// + [JT808BodiesType(typeof(JT808_0x0003))] + [JT808MsgIdDescription("0x0003", "终端注销")] + 终端注销 = 0x0003, + /// + /// 终端鉴权 + /// 0x0102 + /// + [JT808BodiesType(typeof(JT808_0x0102))] + [JT808MsgIdDescription("0x0102", "终端鉴权")] + 终端鉴权 = 0x0102, + /// + /// 设置终端参数 + /// 0x8103 + /// + [JT808BodiesType(typeof(JT808_0x8103))] + [JT808MsgIdDescription("0x8103", "设置终端参数")] + 设置终端参数 = 0x8103, + /// + /// 查询终端参数 + /// 0x8104 + /// + [JT808BodiesType(typeof(JT808_0x8104))] + [JT808MsgIdDescription("0x8104", "查询终端参数")] + 查询终端参数 = 0x8104, + /// + /// 查询终端参数应答 + /// 0x0104 + /// + [JT808BodiesType(typeof(JT808_0x0104))] + [JT808MsgIdDescription("0x0104", "查询终端参数应答")] + 查询终端参数应答 = 0x0104, + /// + /// 终端控制 + /// 0x8105 + /// + [JT808BodiesType(typeof(JT808_0x8105))] + [JT808MsgIdDescription("0x8105", "终端控制")] + 终端控制 = 0x8105, + /// + /// 查询指定终端参数 + /// 0x8106 + /// + [JT808BodiesType(typeof(JT808_0x8106))] + [JT808MsgIdDescription("0x8106", "查询指定终端参数")] + 查询指定终端参数 = 0x8106, + /// + /// 查询终端属性 + /// 0x8107 + /// + [JT808BodiesType(typeof(JT808_0x8107))] + [JT808MsgIdDescription("0x8107", "查询终端属性")] + 查询终端属性 = 0x8107, + /// + /// 查询终端属性应答 + /// 0x0107 + /// + [JT808BodiesType(typeof(JT808_0x0107))] + [JT808MsgIdDescription("0x0107", "查询终端属性应答")] + 查询终端属性应答 = 0x0107, + /// + /// 下发终端升级包 + /// 0x8108 + /// + [JT808BodiesType(typeof(JT808_0x8108))] + [JT808MsgIdDescription("0x8108", "下发终端升级包")] + 下发终端升级包 = 0x8108, + /// + /// 终端升级结果通知 + /// 0x0108 + /// + [JT808BodiesType(typeof(JT808_0x0108))] + [JT808MsgIdDescription("0x0108", "终端升级结果通知")] + 终端升级结果通知 = 0x0108, + /// + /// 位置信息汇报 + /// 0x0200 + /// + [JT808BodiesType(typeof(JT808_0x0200))] + [JT808MsgIdDescription("0x0200", "位置信息汇报")] + 位置信息汇报 = 0x0200, + /// + /// 位置信息查询 + /// 0x8201 + /// + [JT808BodiesType(typeof(JT808_0x8201))] + [JT808MsgIdDescription("0x8201", "位置信息查询")] + 位置信息查询 = 0x8201, + /// + /// 位置信息查询应答 + /// 0x0201 + /// + [JT808BodiesType(typeof(JT808_0x0201))] + [JT808MsgIdDescription("0x0201", "位置信息查询应答")] + 位置信息查询应答 = 0x0201, + /// + /// 临时位置跟踪控制 + /// 0x8202 + /// + [JT808BodiesType(typeof(JT808_0x8202))] + [JT808MsgIdDescription("0x8202", "临时位置跟踪控制")] + 临时位置跟踪控制 = 0x8202, + /// + /// 人工确认报警消息 + /// 0x8203 + /// + [JT808BodiesType(typeof(JT808_0x8203))] + [JT808MsgIdDescription("0x8203", "人工确认报警消息")] + 人工确认报警消息 = 0x8203, + /// + /// 文本信息下发 + /// 0x8300 + /// + [JT808BodiesType(typeof(JT808_0x8300))] + [JT808MsgIdDescription("0x8300", "文本信息下发")] + 文本信息下发 = 0x8300, + /// + /// 事件设置 + /// 0x8301 + /// + [JT808BodiesType(typeof(JT808_0x8301))] + [JT808MsgIdDescription("0x8301", "事件设置")] + 事件设置 = 0x8301, + /// + /// 事件报告 + /// 0x0301 + /// + [JT808BodiesType(typeof(JT808_0x0301))] + [JT808MsgIdDescription("0x0301", "事件报告")] + 事件报告 = 0x0301, + /// + /// 提问下发 + /// 0x8302 + /// + [JT808BodiesType(typeof(JT808_0x8302))] + [JT808MsgIdDescription("0x8302", "提问下发")] + 提问下发 = 0x8302, + /// + /// 提问应答 + /// 0x0302 + /// + [JT808BodiesType(typeof(JT808_0x0302))] + [JT808MsgIdDescription("0x8302", "提问应答")] + 提问应答 = 0x0302, + /// + /// 信息点播菜单设置 + /// 0x8303 + /// + [JT808BodiesType(typeof(JT808_0x8303))] + [JT808MsgIdDescription("0x8303", "信息点播菜单设置")] + 信息点播菜单设置 = 0x8303, + /// + /// 信息点播/取消 + /// 0x0303 + /// + [JT808BodiesType(typeof(JT808_0x0303))] + [JT808MsgIdDescription("0x0303", "信息点播或取消")] + 信息点播_取消 = 0x0303, + /// + /// 信息服务 + /// 0x8304 + /// + [JT808BodiesType(typeof(JT808_0x8304))] + [JT808MsgIdDescription("0x8304", "信息服务")] + 信息服务 = 0x8304, + /// + /// 电话回拨 + /// 0x8400 + /// + [JT808BodiesType(typeof(JT808_0x8400))] + [JT808MsgIdDescription("0x8400", "电话回拨")] + 电话回拨 = 0x8400, + /// + /// 设置电话本 + /// 0x8401 + /// + [JT808BodiesType(typeof(JT808_0x8401))] + [JT808MsgIdDescription("0x8401", "设置电话本")] + 设置电话本 = 0x8401, + /// + /// 车辆控制 + /// 0x8500 + /// + [JT808BodiesType(typeof(JT808_0x8500))] + [JT808MsgIdDescription("0x8500", "车辆控制")] + 车辆控制 = 0x8500, + /// + /// 车辆控制应答 + /// 0x0500 + /// + [JT808BodiesType(typeof(JT808_0x0500))] + [JT808MsgIdDescription("0x0500", "车辆控制应答")] + 车辆控制应答 = 0x0500, + /// + /// 设置圆形区域 + /// 0x8600 + /// + [JT808BodiesType(typeof(JT808_0x8600))] + [JT808MsgIdDescription("0x8600", "设置圆形区域")] + 设置圆形区域 = 0x8600, + /// + /// 删除圆形区域 + /// 0x8601 + /// + [JT808BodiesType(typeof(JT808_0x8601))] + [JT808MsgIdDescription("0x8601", "删除圆形区域")] + 删除圆形区域 = 0x8601, + /// + /// 设置矩形区域 + /// 0x8602 + /// + [JT808BodiesType(typeof(JT808_0x8602))] + [JT808MsgIdDescription("0x8602", "设置矩形区域")] + 设置矩形区域 = 0x8602, + /// + /// 删除矩形区域 + /// 0x8603 + /// + [JT808BodiesType(typeof(JT808_0x8603))] + [JT808MsgIdDescription("0x8603", "删除矩形区域")] + 删除矩形区域 = 0x8603, + /// + /// 设置多边形区域 + /// 0x8604 + /// + [JT808BodiesType(typeof(JT808_0x8604))] + [JT808MsgIdDescription("0x8604", "设置多边形区域")] + 设置多边形区域 = 0x8604, + /// + /// 删除多边形区域 + /// 0x8605 + /// + [JT808BodiesType(typeof(JT808_0x8605))] + [JT808MsgIdDescription("0x8605", "删除多边形区域")] + 删除多边形区域 = 0x8605, + /// + /// 设置路线 + /// 0x8606 + /// + [JT808BodiesType(typeof(JT808_0x8606))] + [JT808MsgIdDescription("0x8606", "设置路线")] + 设置路线 = 0x8606, + /// + /// 删除路线 + /// 0x8607 + /// + [JT808BodiesType(typeof(JT808_0x8607))] + [JT808MsgIdDescription("0x8607", "删除路线")] + 删除路线 = 0x8607, + + ///// + ///// 行驶记录仪数据采集命令 + ///// 0x8700 + ///// + //[JT808BodiesType(typeof(JT808_0x8700))] + //[JT808MsgIdDescription("0x8700", "行驶记录仪数据采集命令")] + //行驶记录仪数据采集命令 = 0x8700, + ///// + ///// 行驶记录仪数据上传 + ///// 0x0700 + ///// + //[JT808BodiesType(typeof(JT808_0x0700))] + //[JT808MsgIdDescription("0x0700", "行驶记录仪数据上传")] + //行驶记录仪数据上传 = 0x0700, + ///// + ///// 行驶记录仪参数下传命令 + ///// 0x8701 + ///// + //[JT808BodiesType(typeof(JT808_0x8701))] + //[JT808MsgIdDescription("0x8701", "行驶记录仪参数下传命令")] + //行驶记录仪参数下传命令 = 0x8701, + /// + /// 电子运单上报 + /// 0x0701 + /// + [JT808BodiesType(typeof(JT808_0x0701))] + [JT808MsgIdDescription("0x0701", "电子运单上报")] + 电子运单上报 = 0x0701, + /// + /// 驾驶员身份信息采集上报 + /// 0x0702 + /// + [JT808BodiesType(typeof(JT808_0x0702))] + [JT808MsgIdDescription("0x0702", "驾驶员身份信息采集上报")] + 驾驶员身份信息采集上报 = 0x0702, + /// + /// 上报驾驶员身份信息请求 + /// 0x8702 + /// + [JT808BodiesType(typeof(JT808_0x8702))] + [JT808MsgIdDescription("0x8702", "上报驾驶员身份信息请求")] + 上报驾驶员身份信息请求 = 0x8702, + /// + /// 定位数据批量上传 + /// 0x0704 + /// + [JT808BodiesType(typeof(JT808_0x0704))] + [JT808MsgIdDescription("0x0704", "定位数据批量上传")] + 定位数据批量上传 = 0x0704, + /// + /// CAN总线数据上传 + /// 0x0705 + /// + [JT808BodiesType(typeof(JT808_0x0705))] + [JT808MsgIdDescription("0x0705", "CAN总线数据上传")] + CAN总线数据上传 = 0x0705, + /// + /// 多媒体事件信息上传 + /// 0x0800 + /// + [JT808BodiesType(typeof(JT808_0x0800))] + [JT808MsgIdDescription("0x0800", "多媒体事件信息上传")] + 多媒体事件信息上传 = 0x0800, + /// + /// 多媒体数据上传 + /// 0x0801 + /// + [JT808BodiesType(typeof(JT808_0x0801))] + [JT808MsgIdDescription("0x0801", "多媒体数据上传")] + 多媒体数据上传 = 0x0801, + /// + /// 多媒体数据上传应答 + /// 0x8800 + /// + [JT808BodiesType(typeof(JT808_0x8800))] + [JT808MsgIdDescription("0x8800", "多媒体数据上传应答")] + 多媒体数据上传应答 = 0x8800, + /// + /// 摄像头立即拍摄命令 + /// 0x8801 + /// + [JT808BodiesType(typeof(JT808_0x8801))] + [JT808MsgIdDescription("0x8801", "摄像头立即拍摄命令")] + 摄像头立即拍摄命令 = 0x8801, + /// + /// 摄像头立即拍摄命令应答 + /// 0x0805 + /// + [JT808BodiesType(typeof(JT808_0x0805))] + [JT808MsgIdDescription("0x0805", "摄像头立即拍摄命令应答")] + 摄像头立即拍摄命令应答 = 0x0805, + /// + /// 存储多媒体数据检索 + /// 0x8802 + /// + [JT808BodiesType(typeof(JT808_0x8802))] + [JT808MsgIdDescription("0x8802", "存储多媒体数据检索")] + 存储多媒体数据检索 = 0x8802, + /// + /// 存储多媒体数据上传 + /// 0x8803 + /// + [JT808BodiesType(typeof(JT808_0x8803))] + [JT808MsgIdDescription("0x8803", "存储多媒体数据上传")] + 存储多媒体数据上传 = 0x8803, + /// + /// 录音开始命令 + /// 0x8804 + /// + [JT808BodiesType(typeof(JT808_0x8804))] + [JT808MsgIdDescription("0x8804", "录音开始命令")] + 录音开始命令 = 0x8804, + /// + /// 单条存储多媒体数据检索上传命令 + /// 0x8805 + /// + [JT808BodiesType(typeof(JT808_0x8805))] + [JT808MsgIdDescription("0x8804", "单条存储多媒体数据检索上传命令")] + 单条存储多媒体数据检索上传命令 = 0x8805, + /// + /// 数据下行透传 + /// 0x8900 + /// + [JT808BodiesType(typeof(JT808_0x8900))] + [JT808MsgIdDescription("0x8900", "数据下行透传")] + 数据下行透传 = 0x8900, + /// + /// 数据上行透传 + /// 0x0900 + /// + [JT808BodiesType(typeof(JT808_0x0900))] + [JT808MsgIdDescription("0x0900", "数据上行透传")] + 数据上行透传 = 0x0900, + /// + /// 数据压缩上报 + /// 0x0901 + /// + [JT808BodiesType(typeof(JT808_0x0901))] + [JT808MsgIdDescription("0x0901", "数据压缩上报")] + 数据压缩上报 = 0x0901, + /// + /// 平台RSA公钥 + /// 0x8A00 + /// + [JT808BodiesType(typeof(JT808_0x8A00))] + [JT808MsgIdDescription("0x8A00", "平台RSA公钥")] + 平台RSA公钥 = 0x8A00, + /// + /// 终端RSA公钥 + /// 0x0A00 + /// + [JT808BodiesType(typeof(JT808_0x0A00))] + [JT808MsgIdDescription("0x0A00", "终端RSA公钥")] + 终端RSA公钥 = 0x0A00, + } +} diff --git a/src/JT808.Protocol/Enums/JT808MultimediaCodingFormat.cs b/src/JT808.Protocol/Enums/JT808MultimediaCodingFormat.cs new file mode 100644 index 0000000..1d27d6e --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808MultimediaCodingFormat.cs @@ -0,0 +1,14 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 多媒体格式编码 + /// + public enum JT808MultimediaCodingFormat : byte + { + JPEG = 0x00, + TIF = 0x01, + MP3 = 0x02, + WAV = 0x03, + WMV = 0x04 + } +} diff --git a/src/JT808.Protocol/Enums/JT808MultimediaDeleted.cs b/src/JT808.Protocol/Enums/JT808MultimediaDeleted.cs new file mode 100644 index 0000000..a350ca6 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808MultimediaDeleted.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 删除标志 + /// 单条存储多媒体数据检索上传命令 + /// + public enum JT808MultimediaDeleted : byte + { + 保留 = 0, + 删除 = 1 + } +} diff --git a/src/JT808.Protocol/Enums/JT808MultimediaType.cs b/src/JT808.Protocol/Enums/JT808MultimediaType.cs new file mode 100644 index 0000000..9bd9959 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808MultimediaType.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 多媒体类型 + /// + public enum JT808MultimediaType : byte + { + 图像 = 0x00, + 音频 = 0x01, + 视频 = 0x02 + } +} diff --git a/src/JT808.Protocol/Enums/JT808PhoneNumberType.cs b/src/JT808.Protocol/Enums/JT808PhoneNumberType.cs new file mode 100644 index 0000000..4f2bb9d --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808PhoneNumberType.cs @@ -0,0 +1,18 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 大陆11位 补0 + /// 香港8位 区号:852 补0 + /// 澳门8位 区号:853 补0 + /// 台湾的是10位 区号:886 + /// 台湾手机号码有10码,例如0912345678不过前面那个0是我们自己在台湾打的, + /// 假如是其他地方打来要改成打 +886912345678 + /// + public enum JT808PhoneNumberType + { + 大陆 = 11, + 香港 = 8, + 澳门 = 8, + 台湾 = 10 + } +} diff --git a/src/JT808.Protocol/Enums/JT808PlatformResult.cs b/src/JT808.Protocol/Enums/JT808PlatformResult.cs new file mode 100644 index 0000000..32a12e1 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808PlatformResult.cs @@ -0,0 +1,26 @@ +namespace JT808.Protocol.Enums +{ + public enum JT808PlatformResult : byte + { + /// + /// 成功/确认 + /// + 成功 = 0x00, + /// + /// 失败 + /// + 失败 = 0x01, + /// + /// 消息有误 + /// + 消息有误 = 0x02, + /// + /// 不支持 + /// + 不支持 = 0x03, + /// + /// 报警处理确认 + /// + 报警处理确认 = 0x04 + } +} diff --git a/src/JT808.Protocol/Enums/JT808PositionType.cs b/src/JT808.Protocol/Enums/JT808PositionType.cs new file mode 100644 index 0000000..6cac532 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808PositionType.cs @@ -0,0 +1,14 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 位置类型 + /// + public enum JT808PositionType : byte + { + 无特定位置 = 0x00, + 圆形区域 = 0x01, + 矩形区域 = 0x02, + 多边形区域 = 0x03, + 路段 = 0x04 + } +} diff --git a/src/JT808.Protocol/Enums/JT808RecordCmd.cs b/src/JT808.Protocol/Enums/JT808RecordCmd.cs new file mode 100644 index 0000000..689a3f4 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808RecordCmd.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 录音命令 + /// + public enum JT808RecordCmd : byte + { + 停止录音 = 0x00, + 开始录音 = 0x01 + } +} diff --git a/src/JT808.Protocol/Enums/JT808RecordSave.cs b/src/JT808.Protocol/Enums/JT808RecordSave.cs new file mode 100644 index 0000000..1b7cdfa --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808RecordSave.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 保存标志 + /// + public enum JT808RecordSave : byte + { + 实时上传 = 0, + 保存 = 1 + } +} diff --git a/src/JT808.Protocol/Enums/JT808SettingProperty.cs b/src/JT808.Protocol/Enums/JT808SettingProperty.cs new file mode 100644 index 0000000..4c7a39c --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808SettingProperty.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 设置属性 + /// + public enum JT808SettingProperty : byte + { + 更新区域 = 0x00, + 追加区域 = 0x01, + 修改区域 = 0x02 + } +} diff --git a/src/JT808.Protocol/Enums/JT808SettingTelephoneBook.cs b/src/JT808.Protocol/Enums/JT808SettingTelephoneBook.cs new file mode 100644 index 0000000..22fadea --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808SettingTelephoneBook.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 设置电话本 设置类型 + /// + public enum JT808SettingTelephoneBook : byte + { + 删除终端上所有存储的联系人 = 0, + 更新电话本_删除终端中已有全部联系人并追加消息中的联系人 = 1, + 追加电话本 = 2, + 修改电话本_以联系人为索引 = 3 + } +} diff --git a/src/JT808.Protocol/Enums/JT808Status.cs b/src/JT808.Protocol/Enums/JT808Status.cs new file mode 100644 index 0000000..ce6cf47 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808Status.cs @@ -0,0 +1,32 @@ +using System; + +namespace JT808.Protocol.Enums +{ + [Flags] + public enum JT808Status : uint + { + ACC开 = 1, + 定位 = 2, + 南纬 = 4, + 西经 = 8, + 停运状态 = 16, + 经纬度已经保密插件加密 = 32, + //保留 = 64, + //保留 = 128, + 半载 = 256, + //保留 = 512, + 满载 = 768, + 车辆油路断开 = 1024, + 车辆电路断开 = 2048, + 车门加锁 = 4096, + 前门开 = 8192, + 中门开 = 16384, + 后门开 = 32768, + 驾驶席门开 = 65536, + 自定义 = 131072, + 使用GPS卫星进行定位 = 262144, + 使用北斗卫星进行定位 = 524288, + 使用GLONASS卫星进行定位 = 1048576, + 使用Galileo卫星进行定位 = 2097152 + } +} diff --git a/src/JT808.Protocol/Enums/JT808TelephoneBookContactType.cs b/src/JT808.Protocol/Enums/JT808TelephoneBookContactType.cs new file mode 100644 index 0000000..b091082 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808TelephoneBookContactType.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 电话本联系人标志 + /// + public enum JT808TelephoneBookContactType : byte + { + 呼入 = 1, + 呼出 = 2, + 呼入_呼出 = 3 + } +} diff --git a/src/JT808.Protocol/Enums/JT808TerminalRegisterResult.cs b/src/JT808.Protocol/Enums/JT808TerminalRegisterResult.cs new file mode 100644 index 0000000..8cd5ea3 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808TerminalRegisterResult.cs @@ -0,0 +1,11 @@ +namespace JT808.Protocol.Enums +{ + public enum JT808TerminalRegisterResult : byte + { + 成功 = 0x00, + 车辆已被注册 = 0x01, + 数据库中无该车辆 = 0x02, + 终端已被注册 = 0x03, + 数据库中无该终端 = 0x04 + } +} diff --git a/src/JT808.Protocol/Enums/JT808TerminalResult.cs b/src/JT808.Protocol/Enums/JT808TerminalResult.cs new file mode 100644 index 0000000..e777c30 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808TerminalResult.cs @@ -0,0 +1,22 @@ +namespace JT808.Protocol.Enums +{ + public enum JT808TerminalResult : byte + { + /// + /// 成功/确认 + /// + Success = 0x00, + /// + /// 失败 + /// + Fail = 0x01, + /// + /// 消息有误 + /// + MessageError = 0x02, + /// + /// 不支持 + /// + NotSupport = 0x03 + } +} diff --git a/src/JT808.Protocol/Enums/JT808UpgradeResult.cs b/src/JT808.Protocol/Enums/JT808UpgradeResult.cs new file mode 100644 index 0000000..d5272c8 --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808UpgradeResult.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 升级结果 + /// + public enum JT808UpgradeResult : byte + { + 成功 = 0, + 失败 = 1, + 取消 = 2, + } +} diff --git a/src/JT808.Protocol/Enums/JT808UpgradeType.cs b/src/JT808.Protocol/Enums/JT808UpgradeType.cs new file mode 100644 index 0000000..ec95f9e --- /dev/null +++ b/src/JT808.Protocol/Enums/JT808UpgradeType.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Enums +{ + /// + /// 升级类型 + /// + public enum JT808UpgradeType : byte + { + 终端 = 0, + 道路运输证IC卡读卡器 = 12, + 北斗卫星定位模块 = 52, + } +} diff --git a/src/JT808.Protocol/Exceptions/JT808Exception.cs b/src/JT808.Protocol/Exceptions/JT808Exception.cs new file mode 100644 index 0000000..ac5b680 --- /dev/null +++ b/src/JT808.Protocol/Exceptions/JT808Exception.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Enums; +using System; + +namespace JT808.Protocol.Exceptions +{ + [Serializable] + public class JT808Exception : Exception + { + public JT808Exception(JT808ErrorCode errorCode) : base(errorCode.ToString()) + { + ErrorCode = errorCode; + } + + public JT808Exception(JT808ErrorCode errorCode, string message) : base(message) + { + ErrorCode = errorCode; + } + + public JT808Exception(JT808ErrorCode errorCode, Exception ex) : base(ex.Message, ex) + { + ErrorCode = errorCode; + } + + public JT808Exception(JT808ErrorCode errorCode, string message, Exception ex) : base(ex.Message, ex) + { + ErrorCode = errorCode; + } + + public JT808ErrorCode ErrorCode { get; } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808ConfigExtensions.cs b/src/JT808.Protocol/Extensions/JT808ConfigExtensions.cs new file mode 100644 index 0000000..26b8751 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808ConfigExtensions.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Exceptions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Extensions +{ + public static class JT808ConfigExtensions + { + private readonly static ConcurrentDictionary jT808SerializerDict = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + public static object GetMessagePackFormatterByType(this IJT808Config jT808Config,Type type) + { + if (!jT808Config.FormatterFactory.FormatterDict.TryGetValue(type.GUID, out var formatter)) + { + throw new JT808Exception(JT808ErrorCode.NotGlobalRegisterFormatterAssembly, type.FullName); + } + return formatter; + } + public static IJT808MessagePackFormatter GetMessagePackFormatter(this IJT808Config jT808Config) + { + return (IJT808MessagePackFormatter)GetMessagePackFormatterByType(jT808Config,typeof(T)); + } + public static JT808Serializer GetSerializer(this IJT808Config jT808Config) + { + if(!jT808SerializerDict.TryGetValue(jT808Config.ConfigId,out var serializer)) + { + serializer = new JT808Serializer(jT808Config); + jT808SerializerDict.TryAdd(jT808Config.ConfigId, serializer); + } + return serializer; + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808EnumExtensions.cs b/src/JT808.Protocol/Extensions/JT808EnumExtensions.cs new file mode 100644 index 0000000..f2492d8 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808EnumExtensions.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; + +namespace JT808.Protocol.Extensions +{ + /// + /// 枚举扩展 + /// + public static class JT808EnumExtensions + { + /// + /// 转为整型 + /// + /// + /// + /// + public static int ToValue(this T t) where T : struct + { + return Convert.ToInt32(t); + } + + /// + /// 转为 u16 整型 + /// + /// + /// + /// + public static ushort ToUInt16Value(this T t) where T : struct + { + return Convert.ToUInt16(t); + } + + /// + /// 转为Byte + /// + /// + /// + /// + public static byte ToByteValue(this T t) where T : struct + { + return Convert.ToByte(t); + } + + /// + /// 转为整型 + /// + /// + /// + /// + public static string ToValueString(this T t) where T : struct + { + return Convert.ToInt32(t).ToString(); + } + + /// + /// 字符转枚举 + /// + /// + /// + /// + public static T ToEnum(this string value) where T : struct + { + return (T)Enum.Parse(typeof(T), value); + } + + /// + /// 获取枚举字符串 + /// + /// + public static string GetName(this Enum valueEnum) + { + return valueEnum.ToString(); + } + + /// + /// 获取DescriptionAttribute特性枚举值的描述 + /// + /// + /// + public static string GetDescription(this Enum value) + { + var attribute = value.GetAttribute(); + return attribute == null ? value.ToString() : attribute.Description; + } + + /// + /// 验证是否是枚举类型 + /// + /// + /// + /// + public static bool IsEnumValid(this int enumValue) + { + return Enum.IsDefined(typeof(TEnum), enumValue); + } + + /// + /// 获取DescriptionAttribute特性枚举及描述 + /// + /// + /// + public static Dictionary GetDescriptionAttributeDictionary(this Enum value) + { + Dictionary dictionary = new Dictionary(); + var fields = value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (var fi in fields) + { + DescriptionAttribute attr = Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute), false) as DescriptionAttribute; + dictionary.Add(fi.Name, attr != null ? attr.Description : ""); + } + return dictionary; + } + + /// + /// 获取DisplayNameAttribute特性枚举值的描述 + /// + /// 枚举值 + /// + public static string GetDisplayName(this Enum value) + { + var attribute = value.GetAttribute(); + return attribute == null ? value.ToString() : attribute.DisplayName; + } + + /// + /// 获取DisplayNameAttribute特性枚举及描述 + /// + /// + /// + public static Dictionary GetDisplayNameAttributeDictionary(this Enum value) + { + Dictionary dictionary = new Dictionary(); + var fields = value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (var fi in fields) + { + DisplayNameAttribute attr = Attribute.GetCustomAttribute(fi, typeof(DisplayNameAttribute), false) as DisplayNameAttribute; + dictionary.Add(fi.Name, attr != null ? attr.DisplayName : ""); + } + return dictionary; + } + + /// + /// 获取枚举对应特性 + /// + /// + /// + /// + public static T GetAttribute(this Enum value) where T : Attribute + { + try + { + var type = value.GetType(); + var memberInfo = type.GetMember(value.ToString()); + var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false); + return (T)attributes[0]; + } + catch + { + return default; + } + } + + /// + /// 根据值获取对应枚举类型集合 + /// + /// 具体枚举类型 + /// 枚举值 + /// 位数(8,16,32) + /// 是否忽略未知数据 + /// + public static IEnumerable GetEnumTypes(this int value, int digit, bool ignoreUnknown = false) where T : Enum + { + List values = new List(); + for (int i = 0; i < digit; i++) + { + if (Math.Pow(2, i) <= value) continue; + values.Add((T)Enum.ToObject(typeof(T), (int)Math.Pow(2, i - 1))); + value = value - (int)Math.Pow(2, i - 1); + i = 0; + if (value <= 0) break; + } + if (ignoreUnknown) + { + List results = new List(); + foreach (var item in values) + { + foreach (string itemChild in Enum.GetNames(typeof(T))) + { + if (item.ToString() == itemChild) + { + results.Add(item); + break; + } + } + } + return results; + } + else + { + return values; + } + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808FormatterExtensions.cs b/src/JT808.Protocol/Extensions/JT808FormatterExtensions.cs new file mode 100644 index 0000000..38927d6 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808FormatterExtensions.cs @@ -0,0 +1,35 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Exceptions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Reflection; + +namespace JT808.Protocol.Extensions +{ + [Obsolete("使用JT808ConfigExtensions")] + public static class JT808FormatterExtensions + { + public static IJT808Formatter GetFormatter(IJT808Config jT808Config) + { + return (IJT808Formatter)GetFormatter(typeof(T), jT808Config); + } + + public static IJT808MessagePackFormatter GetMessagePackFormatter(IJT808Config jT808Config) + { + return (IJT808MessagePackFormatter)GetFormatter(typeof(T), jT808Config); + } + + public static object GetFormatter(Type type,IJT808Config jT808Config) + { + if (!jT808Config.FormatterFactory.FormatterDict.TryGetValue(type.GUID, out var formatter)) + { + throw new JT808Exception(JT808ErrorCode.NotGlobalRegisterFormatterAssembly, type.FullName); + } + return formatter; + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808FormatterResolverExtensions.cs b/src/JT808.Protocol/Extensions/JT808FormatterResolverExtensions.cs new file mode 100644 index 0000000..4aaf9e2 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808FormatterResolverExtensions.cs @@ -0,0 +1,159 @@ +using JT808.Protocol.Formatters; +using System; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Reflection; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Extensions +{ + /// + /// + /// ref http://adamsitnik.com/Span/#span-must-not-be-a-generic-type-argument + /// ref http://adamsitnik.com/Span/ + /// ref:MessagePack.Formatters.DynamicObjectTypeFallbackFormatter + /// + [Obsolete("使用JT808MessagePackFormatterResolverExtensions")] + public static class JT808FormatterResolverExtensions + { + delegate int JT808SerializeMethod(object dynamicFormatter, ref byte[] bytes, int offset, object value, IJT808Config config); + + delegate dynamic JT808DeserializeMethod(object dynamicFormatter, ReadOnlySpan bytes, out int readSize, IJT808Config config); + + static readonly ConcurrentDictionary jT808Serializers = new ConcurrentDictionary(); + + static readonly ConcurrentDictionary jT808Deserializes = new ConcurrentDictionary(); + + public static int JT808DynamicSerialize(object objFormatter, ref byte[] bytes, int offset, dynamic value, IJT808Config config) + { + Type type = value.GetType(); + var ti = type.GetTypeInfo(); + (object Value, JT808SerializeMethod SerializeMethod) formatterAndDelegate; + if (!jT808Serializers.TryGetValue(type, out formatterAndDelegate)) + { + var t = type; + { + var formatterType = typeof(IJT808Formatter<>).MakeGenericType(t); + var param0 = Expression.Parameter(typeof(object), "formatter"); + var param1 = Expression.Parameter(typeof(byte[]).MakeByRefType(), "bytes"); + var param2 = Expression.Parameter(typeof(int), "offset"); + var param3 = Expression.Parameter(typeof(object), "value"); + var param4 = Expression.Parameter(typeof(IJT808Config),"config"); + var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(byte[]).MakeByRefType(), typeof(int), t, typeof(IJT808Config) }); + var body = Expression.Call( + Expression.Convert(param0, formatterType), + serializeMethodInfo, + param1, + param2, + ti.IsValueType ? Expression.Unbox(param3, t) : Expression.Convert(param3, t), + param4); + var lambda = Expression.Lambda(body, param0, param1, param2, param3, param4).Compile(); + formatterAndDelegate = (objFormatter, lambda); + } + jT808Serializers.TryAdd(t, formatterAndDelegate); + } + return formatterAndDelegate.SerializeMethod(formatterAndDelegate.Value, ref bytes, offset, value, config); + } + + public static dynamic JT808DynamicDeserialize(object objFormatter, ReadOnlySpan bytes, out int readSize, IJT808Config config) + { + var type = objFormatter.GetType(); + (object Value, JT808DeserializeMethod DeserializeMethod) formatterAndDelegate; + if (!jT808Deserializes.TryGetValue(type, out formatterAndDelegate)) + { + var t = type; + { + var formatterType = typeof(IJT808Formatter<>).MakeGenericType(t); + ParameterExpression param0 = Expression.Parameter(typeof(object), "formatter"); + ParameterExpression param1 = Expression.Parameter(typeof(ReadOnlySpan), "bytes"); + ParameterExpression param2 = Expression.Parameter(typeof(int).MakeByRefType(), "readSize"); + ParameterExpression param3 = Expression.Parameter(typeof(IJT808Config), "config"); + var deserializeMethodInfo = type.GetRuntimeMethod("Deserialize", new[] { typeof(ReadOnlySpan), typeof(int).MakeByRefType() , typeof(IJT808Config) }); + var body = Expression.Call( + Expression.Convert(param0, type), + deserializeMethodInfo, + param1, + param2, + param3 + ); + var lambda = Expression.Lambda(body, param0, param1, param2, param3).Compile(); + formatterAndDelegate = (objFormatter, lambda); + } + jT808Deserializes.TryAdd(t, formatterAndDelegate); + } + return formatterAndDelegate.DeserializeMethod(formatterAndDelegate.Value, bytes, out readSize, config); + } + } + + /// + /// + /// ref http://adamsitnik.com/Span/#span-must-not-be-a-generic-type-argument + /// ref http://adamsitnik.com/Span/ + /// ref:MessagePack.Formatters.DynamicObjectTypeFallbackFormatter + /// + public static class JT808MessagePackFormatterResolverExtensions + { + delegate void JT808SerializeMethod(object dynamicFormatter, ref JT808MessagePackWriter writer,object value, IJT808Config config); + + delegate dynamic JT808DeserializeMethod(object dynamicFormatter, ref JT808MessagePackReader reader, IJT808Config config); + + static readonly ConcurrentDictionary jT808Serializers = new ConcurrentDictionary(); + + static readonly ConcurrentDictionary jT808Deserializes = new ConcurrentDictionary(); + public static void JT808DynamicSerialize(object objFormatter, ref JT808MessagePackWriter writer, object value, IJT808Config config) + { + Type type = value.GetType(); + var ti = type.GetTypeInfo(); + (object Value, JT808SerializeMethod SerializeMethod) formatterAndDelegate; + if (!jT808Serializers.TryGetValue(type, out formatterAndDelegate)) + { + var t = type; + { + var formatterType = typeof(IJT808MessagePackFormatter<>).MakeGenericType(t); + var param0 = Expression.Parameter(typeof(object), "formatter"); + var param1 = Expression.Parameter(typeof(JT808MessagePackWriter).MakeByRefType(), "writer"); + var param2 = Expression.Parameter(typeof(object), "value"); + var param3 = Expression.Parameter(typeof(IJT808Config), "config"); + var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(JT808MessagePackWriter).MakeByRefType(), t, typeof(IJT808Config) }); + var body = Expression.Call( + Expression.Convert(param0, formatterType), + serializeMethodInfo, + param1, + ti.IsValueType ? Expression.Unbox(param2, t) : Expression.Convert(param2, t), + param3); + var lambda = Expression.Lambda(body, param0, param1, param2, param3).Compile(); + formatterAndDelegate = (objFormatter, lambda); + } + jT808Serializers.TryAdd(t, formatterAndDelegate); + } + formatterAndDelegate.SerializeMethod(formatterAndDelegate.Value, ref writer, value, config); + } + public static dynamic JT808DynamicDeserialize(object objFormatter, ref JT808MessagePackReader reader, IJT808Config config) + { + var type = objFormatter.GetType(); + (object Value, JT808DeserializeMethod DeserializeMethod) formatterAndDelegate; + if (!jT808Deserializes.TryGetValue(type, out formatterAndDelegate)) + { + var t = type; + { + var formatterType = typeof(IJT808MessagePackFormatter<>).MakeGenericType(t); + ParameterExpression param0 = Expression.Parameter(typeof(object), "formatter"); + ParameterExpression param1 = Expression.Parameter(typeof(JT808MessagePackReader).MakeByRefType(), "reader"); + ParameterExpression param2 = Expression.Parameter(typeof(IJT808Config), "config"); + var deserializeMethodInfo = type.GetRuntimeMethod("Deserialize", new[] { typeof(JT808MessagePackReader).MakeByRefType(), typeof(IJT808Config) }); + var body = Expression.Call( + Expression.Convert(param0, type), + deserializeMethodInfo, + param1, + param2 + ); + var lambda = Expression.Lambda(body, param0, param1, param2).Compile(); + formatterAndDelegate = (objFormatter, lambda); + } + jT808Deserializes.TryAdd(t, formatterAndDelegate); + } + return formatterAndDelegate.DeserializeMethod(formatterAndDelegate.Value,ref reader, config); + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808HexExtensions.cs b/src/JT808.Protocol/Extensions/JT808HexExtensions.cs new file mode 100644 index 0000000..8248bd5 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808HexExtensions.cs @@ -0,0 +1,129 @@ +using System; + +namespace JT808.Protocol.Extensions +{ + /// + /// + /// ref:"www.codeproject.com/tips/447938/high-performance-csharp-byte-array-to-hex-string-t" + /// + public static partial class JT808BinaryExtensions + { + public static string ToHexString(this byte[] source) + { + return HexUtil.DoHexDump(source, 0, source.Length).ToUpper(); + } + + public static int WriteHexStringLittle(byte[] bytes, int offset, string data, int len) + { + if (data == null) data = ""; + data = data.Replace(" ", ""); + int startIndex = 0; + if (data.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) + { + startIndex = 2; + } + int length = len; + if (length == -1) + { + length = (data.Length - startIndex) / 2; + } + int noOfZero = length * 2 + startIndex - data.Length; + if (noOfZero > 0) + { + data = data.Insert(startIndex, new string('0', noOfZero)); + } + int byteIndex = 0; + while (startIndex < data.Length && byteIndex < length) + { + bytes[offset + byteIndex] = Convert.ToByte(data.Substring(startIndex, 2), 16); + startIndex += 2; + byteIndex++; + } + return length; + } + + /// + /// 16进制字符串转16进制数组 + /// + /// + /// + /// + public static byte[] ToHexBytes(this string hexString) + { + hexString = hexString.Replace(" ", ""); + byte[] buf = new byte[hexString.Length / 2]; + ReadOnlySpan readOnlySpan = hexString.AsSpan(); + for (int i = 0; i < hexString.Length; i++) + { + if (i % 2 == 0) + { + buf[i / 2] = Convert.ToByte(readOnlySpan.Slice(i, 2).ToString(), 16); + } + } + return buf; + } + + public static string ReadHexStringLittle(ReadOnlySpan read, ref int offset, int len) + { + ReadOnlySpan source = read.Slice(offset, len); + string hex = HexUtil.DoHexDump(read, offset, len); + offset += len; + return hex; + } + + /// + /// Copyright (c) Microsoft. All rights reserved. + /// Licensed under the MIT license. See LICENSE file in the project root for full license information. + /// + /// + + } + + public static class HexUtil + { + static readonly char[] HexdumpTable = new char[256 * 4]; + static HexUtil() + { + char[] digits = "0123456789ABCDEF".ToCharArray(); + for (int i = 0; i < 256; i++) + { + HexdumpTable[i << 1] = digits[(int)((uint)i >> 4 & 0x0F)]; + HexdumpTable[(i << 1) + 1] = digits[i & 0x0F]; + } + } + + public static string DoHexDump(ReadOnlySpan buffer, int fromIndex, int length) + { + if (length == 0) + { + return ""; + } + int endIndex = fromIndex + length; + var buf = new char[length << 1]; + int srcIdx = fromIndex; + int dstIdx = 0; + for (; srcIdx < endIndex; srcIdx++, dstIdx += 2) + { + Array.Copy(HexdumpTable, buffer[srcIdx] << 1, buf, dstIdx, 2); + } + return new string(buf); + } + + public static string DoHexDump(byte[] array, int fromIndex, int length) + { + if (length == 0) + { + return ""; + } + int endIndex = fromIndex + length; + var buf = new char[length << 1]; + int srcIdx = fromIndex; + int dstIdx = 0; + for (; srcIdx < endIndex; srcIdx++, dstIdx += 2) + { + Array.Copy(HexdumpTable, (array[srcIdx] & 0xFF) << 1, buf, dstIdx, 2); + } + return new string(buf); + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808PackageExtensions.cs b/src/JT808.Protocol/Extensions/JT808PackageExtensions.cs new file mode 100644 index 0000000..9c5f515 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808PackageExtensions.cs @@ -0,0 +1,63 @@ +using JT808.Protocol.Enums; + +namespace JT808.Protocol.Extensions +{ + public static partial class JT808PackageExtensions + { + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo, TJT808Bodies bodies) + where TJT808Bodies : JT808Bodies + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = (ushort)msgId, + TerminalPhoneNo = terminalPhoneNo + }, + Bodies = bodies + }; + return jT808Package; + } + + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo) + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = (ushort)msgId, + TerminalPhoneNo = terminalPhoneNo + } + }; + return jT808Package; + } + + public static JT808Package CreateCustomMsgId(this ushort msgId, string terminalPhoneNo, TJT808Bodies bodies) + where TJT808Bodies : JT808Bodies + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = msgId, + TerminalPhoneNo = terminalPhoneNo + }, + Bodies = bodies + }; + return jT808Package; + } + + public static JT808Package CreateCustomMsgId(this ushort msgId, string terminalPhoneNo) + { + JT808Package jT808Package = new JT808Package + { + Header = new JT808Header + { + MsgId = msgId, + TerminalPhoneNo = terminalPhoneNo + } + }; + return jT808Package; + } + } +} diff --git a/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.cs b/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.cs new file mode 100644 index 0000000..0c79e71 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.cs @@ -0,0 +1,1045 @@ +using JT808.Protocol.Enums; + +namespace JT808.Protocol.Extensions +{ + public static partial class JT808PackageExtensions + { + /// + /// 0x0001 - 终端通用应答 + /// auto-generated + /// + public static JT808Package Create_终端通用应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0001 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0001 - 终端通用应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0001 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0002 - 终端心跳 + /// auto-generated + /// + public static JT808Package Create_终端心跳(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0002 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0002 - 终端心跳 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0002 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0003 - 终端注销 + /// auto-generated + /// + public static JT808Package Create_终端注销(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0003 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0003 - 终端注销 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0003 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0100 - 终端注册 + /// auto-generated + /// + public static JT808Package Create_终端注册(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0100 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0100 - 终端注册 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0100 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0102 - 终端鉴权 + /// auto-generated + /// + public static JT808Package Create_终端鉴权(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0102 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0102 - 终端鉴权 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0102 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0104 - 查询终端参数应答 + /// auto-generated + /// + public static JT808Package Create_查询终端参数应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0104 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0104 - 查询终端参数应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0104 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0107 - 查询终端属性应答 + /// auto-generated + /// + public static JT808Package Create_查询终端属性应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0107 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0107 - 查询终端属性应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0107 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0108 - 终端升级结果通知 + /// auto-generated + /// + public static JT808Package Create_终端升级结果通知(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0108 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0108 - 终端升级结果通知 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0108 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0200 - 位置信息汇报 + /// auto-generated + /// + public static JT808Package Create_位置信息汇报(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0200 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0200 - 位置信息汇报 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0200 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0201 - 位置信息查询应答 + /// auto-generated + /// + public static JT808Package Create_位置信息查询应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0201 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0201 - 位置信息查询应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0201 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0301 - 事件报告 + /// auto-generated + /// + public static JT808Package Create_事件报告(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0301 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0301 - 事件报告 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0301 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8302 - 提问应答 + /// auto-generated + /// + public static JT808Package Create_提问应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0302 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8302 - 提问应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0302 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0303 - 信息点播或取消 + /// auto-generated + /// + public static JT808Package Create_信息点播或取消(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0303 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0303 - 信息点播或取消 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0303 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0500 - 车辆控制应答 + /// auto-generated + /// + public static JT808Package Create_车辆控制应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0500 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0500 - 车辆控制应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0500 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0701 - 电子运单上报 + /// auto-generated + /// + public static JT808Package Create_电子运单上报(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0701 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0701 - 电子运单上报 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0701 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0702 - 驾驶员身份信息采集上报 + /// auto-generated + /// + public static JT808Package Create_驾驶员身份信息采集上报(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0702 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0702 - 驾驶员身份信息采集上报 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0702 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0704 - 定位数据批量上传 + /// auto-generated + /// + public static JT808Package Create_定位数据批量上传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0704 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0704 - 定位数据批量上传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0704 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0705 - CAN总线数据上传 + /// auto-generated + /// + public static JT808Package Create_CAN总线数据上传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0705 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0705 - CAN总线数据上传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0705 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0800 - 多媒体事件信息上传 + /// auto-generated + /// + public static JT808Package Create_多媒体事件信息上传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0800 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0800 - 多媒体事件信息上传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0800 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0801 - 多媒体数据上传 + /// auto-generated + /// + public static JT808Package Create_多媒体数据上传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0801 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0801 - 多媒体数据上传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0801 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0805 - 摄像头立即拍摄命令应答 + /// auto-generated + /// + public static JT808Package Create_摄像头立即拍摄命令应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0805 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0805 - 摄像头立即拍摄命令应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0805 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0900 - 数据上行透传 + /// auto-generated + /// + public static JT808Package Create_数据上行透传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0900 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0900 - 数据上行透传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0900 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0901 - 数据压缩上报 + /// auto-generated + /// + public static JT808Package Create_数据压缩上报(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0901 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0901 - 数据压缩上报 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0901 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x0A00 - 终端RSA公钥 + /// auto-generated + /// + public static JT808Package Create_终端RSA公钥(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0A00 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x0A00 - 终端RSA公钥 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x0A00 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8001 - 平台通用应答 + /// auto-generated + /// + public static JT808Package Create_平台通用应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8001 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8001 - 平台通用应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8001 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8003 - 补传分包请求 + /// auto-generated + /// + public static JT808Package Create_补传分包请求(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8003 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8003 - 补传分包请求 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8003 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8100 - 终端注册应答 + /// auto-generated + /// + public static JT808Package Create_终端注册应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8100 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8100 - 终端注册应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8100 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8103 - 设置终端参数 + /// auto-generated + /// + public static JT808Package Create_设置终端参数(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8103 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8103 - 设置终端参数 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8103 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8104 - 查询终端参数 + /// auto-generated + /// + public static JT808Package Create_查询终端参数(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8104 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8104 - 查询终端参数 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8104 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8105 - 终端控制 + /// auto-generated + /// + public static JT808Package Create_终端控制(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8105 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8105 - 终端控制 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8105 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8106 - 查询指定终端参数 + /// auto-generated + /// + public static JT808Package Create_查询指定终端参数(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8106 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8106 - 查询指定终端参数 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8106 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8107 - 查询终端属性 + /// auto-generated + /// + public static JT808Package Create_查询终端属性(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8107 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8107 - 查询终端属性 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8107 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8108 - 下发终端升级包 + /// auto-generated + /// + public static JT808Package Create_下发终端升级包(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8108 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8108 - 下发终端升级包 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8108 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8201 - 位置信息查询 + /// auto-generated + /// + public static JT808Package Create_位置信息查询(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8201 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8201 - 位置信息查询 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8201 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8202 - 临时位置跟踪控制 + /// auto-generated + /// + public static JT808Package Create_临时位置跟踪控制(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8202 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8202 - 临时位置跟踪控制 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8202 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8203 - 人工确认报警消息 + /// auto-generated + /// + public static JT808Package Create_人工确认报警消息(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8203 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8203 - 人工确认报警消息 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8203 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8300 - 文本信息下发 + /// auto-generated + /// + public static JT808Package Create_文本信息下发(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8300 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8300 - 文本信息下发 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8300 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8301 - 事件设置 + /// auto-generated + /// + public static JT808Package Create_事件设置(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8301 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8301 - 事件设置 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8301 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8302 - 提问下发 + /// auto-generated + /// + public static JT808Package Create_提问下发(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8302 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8302 - 提问下发 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8302 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8303 - 信息点播菜单设置 + /// auto-generated + /// + public static JT808Package Create_信息点播菜单设置(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8303 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8303 - 信息点播菜单设置 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8303 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8304 - 信息服务 + /// auto-generated + /// + public static JT808Package Create_信息服务(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8304 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8304 - 信息服务 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8304 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8400 - 电话回拨 + /// auto-generated + /// + public static JT808Package Create_电话回拨(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8400 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8400 - 电话回拨 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8400 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8401 - 设置电话本 + /// auto-generated + /// + public static JT808Package Create_设置电话本(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8401 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8401 - 设置电话本 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8401 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8500 - 车辆控制 + /// auto-generated + /// + public static JT808Package Create_车辆控制(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8500 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8500 - 车辆控制 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8500 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8600 - 设置圆形区域 + /// auto-generated + /// + public static JT808Package Create_设置圆形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8600 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8600 - 设置圆形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8600 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8601 - 删除圆形区域 + /// auto-generated + /// + public static JT808Package Create_删除圆形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8601 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8601 - 删除圆形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8601 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8602 - 设置矩形区域 + /// auto-generated + /// + public static JT808Package Create_设置矩形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8602 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8602 - 设置矩形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8602 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8603 - 删除矩形区域 + /// auto-generated + /// + public static JT808Package Create_删除矩形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8603 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8603 - 删除矩形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8603 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8604 - 设置多边形区域 + /// auto-generated + /// + public static JT808Package Create_设置多边形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8604 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8604 - 设置多边形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8604 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8605 - 删除多边形区域 + /// auto-generated + /// + public static JT808Package Create_删除多边形区域(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8605 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8605 - 删除多边形区域 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8605 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8606 - 设置路线 + /// auto-generated + /// + public static JT808Package Create_设置路线(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8606 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8606 - 设置路线 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8606 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8607 - 删除路线 + /// auto-generated + /// + public static JT808Package Create_删除路线(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8607 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8607 - 删除路线 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8607 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8702 - 上报驾驶员身份信息请求 + /// auto-generated + /// + public static JT808Package Create_上报驾驶员身份信息请求(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8702 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8702 - 上报驾驶员身份信息请求 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8702 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8800 - 多媒体数据上传应答 + /// auto-generated + /// + public static JT808Package Create_多媒体数据上传应答(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8800 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8800 - 多媒体数据上传应答 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8800 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8801 - 摄像头立即拍摄命令 + /// auto-generated + /// + public static JT808Package Create_摄像头立即拍摄命令(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8801 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8801 - 摄像头立即拍摄命令 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8801 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8802 - 存储多媒体数据检索 + /// auto-generated + /// + public static JT808Package Create_存储多媒体数据检索(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8802 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8802 - 存储多媒体数据检索 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8802 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8803 - 存储多媒体数据上传 + /// auto-generated + /// + public static JT808Package Create_存储多媒体数据上传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8803 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8803 - 存储多媒体数据上传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8803 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8804 - 录音开始命令 + /// auto-generated + /// + public static JT808Package Create_录音开始命令(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8804 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8804 - 录音开始命令 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8804 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8804 - 单条存储多媒体数据检索上传命令 + /// auto-generated + /// + public static JT808Package Create_单条存储多媒体数据检索上传命令(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8805 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8804 - 单条存储多媒体数据检索上传命令 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8805 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8900 - 数据下行透传 + /// auto-generated + /// + public static JT808Package Create_数据下行透传(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8900 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8900 - 数据下行透传 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8900 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + /// + /// 0x8A00 - 平台RSA公钥 + /// auto-generated + /// + public static JT808Package Create_平台RSA公钥(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8A00 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + + /// + /// 0x8A00 - 平台RSA公钥 + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,JT808.Protocol.MessageBody.JT808_0x8A00 bodies) + { + return Create(msgId,terminalPhoneNo,bodies); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.tt b/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.tt new file mode 100644 index 0000000..5927ec9 --- /dev/null +++ b/src/JT808.Protocol/Extensions/JT808PackageExtensionsTemplate.tt @@ -0,0 +1,53 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="netstandard" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System" #> +<#@ assembly name="$(TargetPath)" #> +<#@ import namespace="JT808.Protocol" #> +<#@ import namespace="JT808.Protocol.Enums" #> +<#@ import namespace="JT808.Protocol.Extensions" #> +<#@ import namespace="JT808.Protocol.Attributes" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Reflection" #> +<#@ output extension=".cs" #> +<# + var types=Enum.GetNames(typeof(JT808MsgId)); +#> +using JT808.Protocol.Enums; + +namespace JT808.Protocol.Extensions +{ + public static partial class JT808PackageExtensions + { +<# + foreach (var item in types) + { + JT808MsgId msgId = item.ToEnum(); + JT808BodiesTypeAttribute jT808BodiesTypeAttribute = msgId.GetAttribute(); + JT808MsgIdDescriptionAttribute jT808MsgIdDescriptionAttribute = msgId.GetAttribute(); + +#> + /// + /// <#= jT808MsgIdDescriptionAttribute.Code #> - <#= jT808MsgIdDescriptionAttribute.Name #> + /// auto-generated + /// + public static JT808Package Create_<#= jT808MsgIdDescriptionAttribute.Name #>(this JT808MsgId msgId, string terminalPhoneNo,<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName #> bodies) + { + return Create<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); + } + + /// + /// <#= jT808MsgIdDescriptionAttribute.Code #> - <#= jT808MsgIdDescriptionAttribute.Name #> + /// auto-generated + /// + public static JT808Package Create(this JT808MsgId msgId, string terminalPhoneNo,<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName #> bodies) + { + return Create<<#= jT808BodiesTypeAttribute.JT808BodiesType.FullName#>>(msgId,terminalPhoneNo,bodies); + } +<# + } +#> + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/IJT808FormatterFactory.cs b/src/JT808.Protocol/Formatters/IJT808FormatterFactory.cs new file mode 100644 index 0000000..b1fc0e3 --- /dev/null +++ b/src/JT808.Protocol/Formatters/IJT808FormatterFactory.cs @@ -0,0 +1,15 @@ +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Formatters +{ + public interface IJT808FormatterFactory: IJT808ExternalRegister + { + Dictionary FormatterDict { get;} + IJT808FormatterFactory SetMap() + where TJT808Bodies : JT808Bodies; + } +} diff --git a/src/JT808.Protocol/Formatters/IJT808FormatterOfT.cs b/src/JT808.Protocol/Formatters/IJT808FormatterOfT.cs new file mode 100644 index 0000000..f8e3e7d --- /dev/null +++ b/src/JT808.Protocol/Formatters/IJT808FormatterOfT.cs @@ -0,0 +1,25 @@ +using System; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters +{ + [Obsolete("使用IJT808MessagePackFormatter")] + public interface IJT808Formatter: IJT808Formatter + { + T Deserialize(ReadOnlySpan bytes, out int readSize, IJT808Config config); + + int Serialize(ref byte[] bytes, int offset, T value, IJT808Config config); + } + + public interface IJT808MessagePackFormatter : IJT808Formatter + { + void Serialize(ref JT808MessagePackWriter writer, T value, IJT808Config config); + T Deserialize(ref JT808MessagePackReader reader, IJT808Config config); + } + + public interface IJT808Formatter + { + + } +} diff --git a/src/JT808.Protocol/Formatters/JT808HeaderFormatter.cs b/src/JT808.Protocol/Formatters/JT808HeaderFormatter.cs new file mode 100644 index 0000000..d28749c --- /dev/null +++ b/src/JT808.Protocol/Formatters/JT808HeaderFormatter.cs @@ -0,0 +1,40 @@ +using JT808.Protocol.Extensions; +using System; +using System.Buffers.Binary; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters +{ + /// + /// JT808头部序列化器 + /// + public class JT808HeaderFormatter : IJT808MessagePackFormatter + { + public static readonly JT808HeaderFormatter Instance = new JT808HeaderFormatter(); + public JT808Header Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808Header jT808Header = new JT808Header(); + // 1.消息ID + jT808Header.MsgId = reader.ReadUInt16(); + // 2.消息体属性 + jT808Header.MessageBodyProperty = JT808HeaderMessageBodyPropertyFormatter.Instance.Deserialize(ref reader, config); + // 3.终端手机号 + jT808Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); + jT808Header.MsgNum = reader.ReadUInt16(); + return jT808Header; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808Header value, IJT808Config config) + { + // 1.消息ID + writer.WriteUInt16(value.MsgId); + // 2.消息体属性 + JT808HeaderMessageBodyPropertyFormatter.Instance.Serialize(ref writer,value.MessageBodyProperty, config); + // 3.终端手机号 + writer.WriteBCD(value.TerminalPhoneNo, config.TerminalPhoneNoLength); + // 4.消息流水号 + writer.WriteUInt16(value.MsgNum); + } + } +} diff --git a/src/JT808.Protocol/Formatters/JT808HeaderMessageBodyPropertyFormatter.cs b/src/JT808.Protocol/Formatters/JT808HeaderMessageBodyPropertyFormatter.cs new file mode 100644 index 0000000..cbe9827 --- /dev/null +++ b/src/JT808.Protocol/Formatters/JT808HeaderMessageBodyPropertyFormatter.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters +{ + /// + /// 头部消息体属性的格式化器 + /// + public class JT808HeaderMessageBodyPropertyFormatter : IJT808MessagePackFormatter + { + public static readonly JT808HeaderMessageBodyPropertyFormatter Instance = new JT808HeaderMessageBodyPropertyFormatter(); + public JT808HeaderMessageBodyProperty Deserialize(ref JT808MessagePackReader writer, IJT808Config config) + { + JT808HeaderMessageBodyProperty messageBodyProperty = new JT808HeaderMessageBodyProperty(); + messageBodyProperty.Unwrap(writer.ReadUInt16(), config); + if (messageBodyProperty.IsPackge) + { + messageBodyProperty.PackgeCount = writer.ReadUInt16(); + messageBodyProperty.PackageIndex = writer.ReadUInt16(); + } + return messageBodyProperty; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808HeaderMessageBodyProperty value, IJT808Config config) + { + writer.WriteUInt16(value.Wrap(config)); + } + } +} diff --git a/src/JT808.Protocol/Formatters/JT808HeaderPackageFormatter.cs b/src/JT808.Protocol/Formatters/JT808HeaderPackageFormatter.cs new file mode 100644 index 0000000..0143181 --- /dev/null +++ b/src/JT808.Protocol/Formatters/JT808HeaderPackageFormatter.cs @@ -0,0 +1,66 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Exceptions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters +{ + public class JT808HeaderPackageFormatter : IJT808MessagePackFormatter + { + public static readonly JT808HeaderPackageFormatter Instance = new JT808HeaderPackageFormatter(); + public JT808HeaderPackage Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + // 1. 验证校验和 + if (!config.SkipCRCCode) + { + if (reader.CheckXorCodeVali) + { + throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}"); + } + } + JT808HeaderPackage jT808Package = new JT808HeaderPackage(); + // ---------------开始解包-------------- + // 2.读取起始位置 + jT808Package.Begin = reader.ReadStart(); + // 3.读取头部信息 + jT808Package.Header = new JT808Header(); + // 3.1.读取消息Id + jT808Package.Header.MsgId = reader.ReadUInt16(); + // 3.2.读取消息体属性 + jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(); + ushort messageBodyPropertyValue = reader.ReadUInt16(); + // 3.2.1.解包消息体属性 + jT808Package.Header.MessageBodyProperty.Unwrap(messageBodyPropertyValue, config); + // 3.3.读取终端手机号 + jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); + // 3.4.读取消息流水号 + jT808Package.Header.MsgNum = reader.ReadUInt16(); + // 3.5.判断有无分包 + if (jT808Package.Header.MessageBodyProperty.IsPackge) + { + //3.5.1.读取消息包总数 + jT808Package.Header.MessageBodyProperty.PackgeCount = reader.ReadUInt16(); + //3.5.2.读取消息包序号 + jT808Package.Header.MessageBodyProperty.PackageIndex = reader.ReadUInt16(); + } + // 4.处理数据体 + // 4.1.判断有无数据体 + if (jT808Package.Header.MessageBodyProperty.DataLength > 0) + { + jT808Package.Bodies = reader.ReadContent().ToArray(); + } + // 5.读取校验码 + jT808Package.CheckCode = reader.ReadByte(); + // 6.读取终止位置 + jT808Package.End = reader.ReadEnd(); + // ---------------解包完成-------------- + return jT808Package; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808HeaderPackage value, IJT808Config config) + { + throw new NotImplementedException("只适用反序列化"); + } + } +} diff --git a/src/JT808.Protocol/Formatters/JT808PackageFormatter.cs b/src/JT808.Protocol/Formatters/JT808PackageFormatter.cs new file mode 100644 index 0000000..05bb6ea --- /dev/null +++ b/src/JT808.Protocol/Formatters/JT808PackageFormatter.cs @@ -0,0 +1,160 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Exceptions; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters +{ + /// + /// JT808包序列化器 + /// + public class JT808PackageFormatter : IJT808MessagePackFormatter + { + public static readonly JT808PackageFormatter Instance = new JT808PackageFormatter(); + public JT808Package Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + // 1. 验证校验和 + if (!config.SkipCRCCode) + { + if (!reader.CheckXorCodeVali) + { + throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}"); + } + } + JT808Package jT808Package = new JT808Package(); + // ---------------开始解包-------------- + // 2.读取起始位置 + jT808Package.Begin = reader.ReadStart(); + // 3.读取头部信息 + jT808Package.Header = new JT808Header(); + // 3.1.读取消息Id + jT808Package.Header.MsgId = reader.ReadUInt16(); + // 3.2.读取消息体属性 + jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(); + ushort messageBodyPropertyValue= reader.ReadUInt16(); + // 3.2.1.解包消息体属性 + jT808Package.Header.MessageBodyProperty.Unwrap(messageBodyPropertyValue, config); + // 3.3.读取终端手机号 + jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength); + // 3.4.读取消息流水号 + jT808Package.Header.MsgNum= reader.ReadUInt16(); + // 3.5.判断有无分包 + if (jT808Package.Header.MessageBodyProperty.IsPackge) + { + //3.5.1.读取消息包总数 + jT808Package.Header.MessageBodyProperty.PackgeCount = reader.ReadUInt16(); + //3.5.2.读取消息包序号 + jT808Package.Header.MessageBodyProperty.PackageIndex = reader.ReadUInt16(); + } + // 4.处理数据体 + // 4.1.判断有无数据体 + if (jT808Package.Header.MessageBodyProperty.DataLength > 0) + { + Type jT808BodiesImplType = config.MsgIdFactory.GetBodiesImplTypeByMsgId(jT808Package.Header.MsgId, jT808Package.Header.TerminalPhoneNo); + if (jT808BodiesImplType != null) + { + if (jT808Package.Header.MessageBodyProperty.IsPackge) + { + if (jT808Package.Header.MessageBodyProperty.PackageIndex > 1) + { + try + { + //4.2处理第二包之后的分包数据消息体 + jT808Package.Bodies = JT808SplitPackageBodiesFormatter.Instance.Deserialize(ref reader, config); + } + catch (Exception ex) + { + throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); + } + } + else + { + try + { + //4.2.处理消息体 + jT808Package.Bodies = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize( + config.GetMessagePackFormatterByType(jT808BodiesImplType), + ref reader, config); + } + catch (Exception ex) + { + throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); + } + } + } + else + { + try + { + //4.2.处理消息体 + jT808Package.Bodies = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize( + config.GetMessagePackFormatterByType(jT808BodiesImplType), + ref reader, config); + } + catch (Exception ex) + { + throw new JT808Exception(JT808ErrorCode.BodiesParseError, ex); + } + } + } + } + // 5.读取校验码 + jT808Package.CheckCode = reader.ReadByte(); + // 6.读取终止位置 + jT808Package.End = reader.ReadEnd(); + // ---------------解包完成-------------- + return jT808Package; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808Package value, IJT808Config config) + { + // ---------------开始组包-------------- + // 1.起始符 + writer.WriteStart(); + // 2.写入头部 //部分有带数据体的长度,那么先跳过写入头部部分 + // 2.1.消息ID + writer.WriteUInt16(value.Header.MsgId); + // 2.2.消息体属性(包含消息体长度所以先跳过) + writer.Skip(2,out int msgBodiesPropertyPosition); + // 2.3.终端手机号 (写死大陆手机号码) + writer.WriteBCD(value.Header.TerminalPhoneNo, config.TerminalPhoneNoLength); + value.Header.MsgNum = value.Header.MsgNum > 0 ? value.Header.MsgNum : config.MsgSNDistributed.Increment(); + // 2.4.消息流水号 + writer.WriteUInt16(value.Header.MsgNum); + // 2.5.判断是否分包 + if (value.Header.MessageBodyProperty.IsPackge) + { + // 2.5.1.消息包总数 + writer.WriteUInt16(value.Header.MessageBodyProperty.PackgeCount); + // 2.5.2.消息包序号 + writer.WriteUInt16(value.Header.MessageBodyProperty.PackageIndex); + } + int headerLength = writer.GetCurrentPosition(); + // 3.处理数据体部分 + if (value.Bodies != null) + { + if (!value.Bodies.SkipSerialization) + { + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize( + config.GetMessagePackFormatterByType(value.Bodies.GetType()), + ref writer, value.Bodies, + config); + } + } + // 3.1.处理数据体长度 + value.Header.MessageBodyProperty.DataLength = writer.GetCurrentPosition() - headerLength; + ushort msgBodiesPropertyValue = value.Header.MessageBodyProperty.Wrap(config); + // 2.2.回写消息体属性 + writer.WriteUInt16Return(msgBodiesPropertyValue, msgBodiesPropertyPosition); + // 4.校验码 + writer.WriteXor(); + // 5.终止符 + writer.WriteEnd(); + // 6.编码 + writer.WriteEncode(); + // ---------------组包结束-------------- + } + } +} diff --git a/src/JT808.Protocol/Formatters/JT808SplitPackageBodiesFormatter.cs b/src/JT808.Protocol/Formatters/JT808SplitPackageBodiesFormatter.cs new file mode 100644 index 0000000..8796b40 --- /dev/null +++ b/src/JT808.Protocol/Formatters/JT808SplitPackageBodiesFormatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using System; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters +{ + public class JT808SplitPackageBodiesFormatter : IJT808MessagePackFormatter + { + public static readonly JT808SplitPackageBodiesFormatter Instance = new JT808SplitPackageBodiesFormatter(); + public JT808SplitPackageBodies Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808SplitPackageBodies jT808SplitPackageBodies = new JT808SplitPackageBodies + { + Data = reader.ReadContent().ToArray() + }; + return jT808SplitPackageBodies; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808SplitPackageBodies value, IJT808Config config) + { + writer.WriteArray(value.Data); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0001_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0001_Formatter.cs new file mode 100644 index 0000000..f8b5f0b --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0001_Formatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0001_Formatter :IJT808MessagePackFormatter + { + public JT808_0x0001 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0001 jT808_0X0001 = new JT808_0x0001(); + jT808_0X0001.MsgNum = reader.ReadUInt16(); + jT808_0X0001.MsgId = reader.ReadUInt16(); + jT808_0X0001.JT808TerminalResult = (JT808TerminalResult)reader.ReadByte(); + return jT808_0X0001; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0001 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteUInt16(value.MsgId); + writer.WriteByte((byte)value.JT808TerminalResult); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0100_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0100_Formatter.cs new file mode 100644 index 0000000..86c46e9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0100_Formatter.cs @@ -0,0 +1,35 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0100_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0100 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0100 jT808_0X0100 = new JT808_0x0100(); + jT808_0X0100.AreaID = reader.ReadUInt16(); + jT808_0X0100.CityOrCountyId = reader.ReadUInt16(); + jT808_0X0100.MakerId = reader.ReadString(5); + jT808_0X0100.TerminalModel = reader.ReadString(20); + jT808_0X0100.TerminalId = reader.ReadString(7); + jT808_0X0100.PlateColor = reader.ReadByte(); + jT808_0X0100.PlateNo = reader.ReadRemainStringContent(); + return jT808_0X0100; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0100 value, IJT808Config config) + { + writer.WriteUInt16(value.AreaID); + writer.WriteUInt16(value.CityOrCountyId); + writer.WriteString(value.MakerId.PadRight(5, '0')); + writer.WriteString(value.TerminalModel.PadRight(20, '0')); + writer.WriteString(value.TerminalId.PadRight(7, '0')); + writer.WriteByte(value.PlateColor); + writer.WriteString(value.PlateNo); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0102_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0102_Formatter.cs new file mode 100644 index 0000000..6912a06 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0102_Formatter.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0102_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0102 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0102 jT808_0X0102 = new JT808_0x0102(); + jT808_0X0102.Code = reader.ReadRemainStringContent(); + return jT808_0X0102; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0102 value, IJT808Config config) + { + writer.WriteString(value.Code); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0104_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0104_Formatter.cs new file mode 100644 index 0000000..83c31f6 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0104_Formatter.cs @@ -0,0 +1,48 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0104_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0104 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0104 jT808_0x0104 = new JT808_0x0104(); + jT808_0x0104.MsgNum = reader.ReadUInt16(); + jT808_0x0104.AnswerParamsCount = reader.ReadByte(); + for (int i = 0; i < jT808_0x0104.AnswerParamsCount; i++) + { + var paramId = reader.ReadVirtualUInt32();//参数ID + if (JT808_0x8103_BodyBase.JT808_0x8103Method.TryGetValue(paramId, out Type type)) + { + if (jT808_0x0104.ParamList != null) + { + jT808_0x0104.ParamList.Add(JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize( + config.GetMessagePackFormatterByType(type), ref reader, config)); + } + else + { + jT808_0x0104.ParamList = new List { JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize( + config.GetMessagePackFormatterByType(type), ref reader, config) }; + } + } + } + return jT808_0x0104; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0104 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteByte(value.AnswerParamsCount); + foreach (var item in value.ParamList) + { + object obj = config.GetMessagePackFormatterByType(item.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(obj, ref writer,item, config); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0107_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0107_Formatter.cs new file mode 100644 index 0000000..e13cc06 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0107_Formatter.cs @@ -0,0 +1,43 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0107_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0107 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0107 jT808_0X0107 = new JT808_0x0107(); + jT808_0X0107.TerminalType = reader.ReadUInt16(); + jT808_0X0107.MakerId = reader.ReadString(5); + jT808_0X0107.TerminalModel = reader.ReadString(20); + jT808_0X0107.TerminalId = reader.ReadString(7); + jT808_0X0107.Terminal_SIM_ICCID = reader.ReadBCD(10); + jT808_0X0107.Terminal_Hardware_Version_Length = reader.ReadByte(); + jT808_0X0107.Terminal_Hardware_Version_Num = reader.ReadString(jT808_0X0107.Terminal_Hardware_Version_Length); + jT808_0X0107.Terminal_Firmware_Version_Length = reader.ReadByte(); + jT808_0X0107.Terminal_Firmware_Version_Num = reader.ReadString(jT808_0X0107.Terminal_Firmware_Version_Length); + jT808_0X0107.GNSSModule = reader.ReadByte(); + jT808_0X0107.CommunicationModule = reader.ReadByte(); + return jT808_0X0107; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0107 value, IJT808Config config) + { + writer.WriteUInt16(value.TerminalType); + writer.WriteString(value.MakerId.PadRight(5, '0')); + writer.WriteString(value.TerminalModel.PadRight(20, '0')); + writer.WriteString(value.TerminalId.PadRight(7, '0')); + writer.WriteBCD(value.Terminal_SIM_ICCID, 10); + writer.WriteByte((byte)value.Terminal_Hardware_Version_Num.Length); + writer.WriteString(value.Terminal_Hardware_Version_Num); + writer.WriteByte((byte)value.Terminal_Firmware_Version_Num.Length); + writer.WriteString(value.Terminal_Firmware_Version_Num); + writer.WriteByte(value.GNSSModule); + writer.WriteByte(value.CommunicationModule); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0108_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0108_Formatter.cs new file mode 100644 index 0000000..ff4affc --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0108_Formatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0108_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0108 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0108 jT808_0X0108 = new JT808_0x0108(); + jT808_0X0108.UpgradeType = (JT808UpgradeType)reader.ReadByte(); + jT808_0X0108.UpgradeResult = (JT808UpgradeResult)reader.ReadByte(); + return jT808_0X0108; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0108 value, IJT808Config config) + { + writer.WriteByte((byte)value.UpgradeType); + writer.WriteByte((byte)value.UpgradeResult); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x01_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x01_Formatter.cs new file mode 100644 index 0000000..bdcf59a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x01_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x01_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x01 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x01 jT808LocationAttachImpl0X01 = new JT808_0x0200_0x01(); + jT808LocationAttachImpl0X01.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0X01.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0X01.Mileage = reader.ReadInt32(); + return jT808LocationAttachImpl0X01; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x01 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteInt32(value.Mileage); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x02_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x02_Formatter.cs new file mode 100644 index 0000000..b4e8f36 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x02_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x02_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x02 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x02 jT808LocationAttachImpl0X02 = new JT808_0x0200_0x02(); + jT808LocationAttachImpl0X02.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0X02.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0X02.Oil = reader.ReadUInt16(); + return jT808LocationAttachImpl0X02; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x02 value, IJT808Config config) + { + writer.WriteByte( value.AttachInfoId); + writer.WriteByte( value.AttachInfoLength); + writer.WriteUInt16( value.Oil); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x03_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x03_Formatter.cs new file mode 100644 index 0000000..33cadf4 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x03_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x03_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x03 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x03 jT808LocationAttachImpl0x03 = new JT808_0x0200_0x03(); + jT808LocationAttachImpl0x03.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x03.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x03.Speed = reader.ReadUInt16(); + return jT808LocationAttachImpl0x03; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x03 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteUInt16(value.Speed); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x04_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x04_Formatter.cs new file mode 100644 index 0000000..d4d237c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x04_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x04_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x04 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x04 jT808LocationAttachImpl0x04 = new JT808_0x0200_0x04(); + jT808LocationAttachImpl0x04.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x04.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x04.EventId = reader.ReadUInt16(); + return jT808LocationAttachImpl0x04; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x04 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteUInt16(value.EventId); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x11_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x11_Formatter.cs new file mode 100644 index 0000000..38de2e0 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x11_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x11_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x11 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x11 jT808LocationAttachImpl0x11 = new JT808_0x0200_0x11(); + jT808LocationAttachImpl0x11.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x11.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x11.JT808PositionType = (JT808PositionType)reader.ReadByte(); + if(jT808LocationAttachImpl0x11.JT808PositionType != JT808PositionType.无特定位置) + { + jT808LocationAttachImpl0x11.AreaId = reader.ReadInt32(); + } + return jT808LocationAttachImpl0x11; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x11 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteByte((byte)value.JT808PositionType); + if (value.JT808PositionType != JT808PositionType.无特定位置) + { + writer.WriteInt32(value.AreaId); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x12_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x12_Formatter.cs new file mode 100644 index 0000000..5a95f31 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x12_Formatter.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x12_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x12 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x12 jT808LocationAttachImpl0x12 = new JT808_0x0200_0x12(); + jT808LocationAttachImpl0x12.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x12.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x12.JT808PositionType = (JT808PositionType)reader.ReadByte(); + jT808LocationAttachImpl0x12.AreaId = reader.ReadInt32(); + jT808LocationAttachImpl0x12.Direction = (JT808DirectionType)reader.ReadByte(); + return jT808LocationAttachImpl0x12; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x12 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteByte((byte)value.JT808PositionType); + writer.WriteInt32(value.AreaId); + writer.WriteByte((byte)value.Direction); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x13_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x13_Formatter.cs new file mode 100644 index 0000000..fcfc7a4 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x13_Formatter.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x13_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x13 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x13 jT808LocationAttachImpl0x13 = new JT808_0x0200_0x13(); + jT808LocationAttachImpl0x13.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x13.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x13.DrivenRouteId = reader.ReadInt32(); + jT808LocationAttachImpl0x13.Time = reader.ReadUInt16(); + jT808LocationAttachImpl0x13.DrivenRoute = (JT808DrivenRouteType)reader.ReadByte(); + return jT808LocationAttachImpl0x13; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x13 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteInt32(value.DrivenRouteId); + writer.WriteUInt16(value.Time); + writer.WriteByte((byte)value.DrivenRoute); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x25_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x25_Formatter.cs new file mode 100644 index 0000000..93a4f1e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x25_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x25_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x25 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x25 jT808LocationAttachImpl0x13 = new JT808_0x0200_0x25(); + jT808LocationAttachImpl0x13.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x13.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x13.CarSignalStatus = reader.ReadInt32(); + return jT808LocationAttachImpl0x13; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x25 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteInt32(value.CarSignalStatus); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2A_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2A_Formatter.cs new file mode 100644 index 0000000..92e5fc9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2A_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x2A_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x2A Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x2A jT808LocationAttachImpl0X2A = new JT808_0x0200_0x2A(); + jT808LocationAttachImpl0X2A.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0X2A.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0X2A.IOStatus = reader.ReadUInt16(); + return jT808LocationAttachImpl0X2A; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x2A value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteUInt16(value.IOStatus); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2B_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2B_Formatter.cs new file mode 100644 index 0000000..cb3ec82 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x2B_Formatter.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x2B_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x2B Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x2B jT808LocationAttachImpl0x2B = new JT808_0x0200_0x2B(); + jT808LocationAttachImpl0x2B.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x2B.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x2B.Analog = reader.ReadInt32(); + return jT808LocationAttachImpl0x2B; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x2B value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteInt32(value.Analog); + } + } +} + diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x30_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x30_Formatter.cs new file mode 100644 index 0000000..e93ff17 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x30_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x30_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x30 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x30 jT808LocationAttachImpl0x30 = new JT808_0x0200_0x30(); + jT808LocationAttachImpl0x30.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x30.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x30.WiFiSignalStrength = reader.ReadByte(); + return jT808LocationAttachImpl0x30; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x30 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteByte(value.WiFiSignalStrength); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x31_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x31_Formatter.cs new file mode 100644 index 0000000..9739626 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_0x31_Formatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_0x31_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200_0x31 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200_0x31 jT808LocationAttachImpl0x31 = new JT808_0x0200_0x31(); + jT808LocationAttachImpl0x31.AttachInfoId = reader.ReadByte(); + jT808LocationAttachImpl0x31.AttachInfoLength = reader.ReadByte(); + jT808LocationAttachImpl0x31.GNSSCount = reader.ReadByte(); + return jT808LocationAttachImpl0x31; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200_0x31 value, IJT808Config config) + { + writer.WriteByte(value.AttachInfoId); + writer.WriteByte(value.AttachInfoLength); + writer.WriteByte(value.GNSSCount); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_Formatter.cs new file mode 100644 index 0000000..2889e59 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0200_Formatter.cs @@ -0,0 +1,116 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0200_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0200 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0200 jT808_0X0200 = new JT808_0x0200(); + jT808_0X0200.AlarmFlag = reader.ReadUInt32(); + jT808_0X0200.StatusFlag = reader.ReadUInt32(); + jT808_0X0200.Lat = reader.ReadInt32(); + jT808_0X0200.Lng = reader.ReadInt32(); + JT808StatusProperty jT808StatusProperty = new JT808StatusProperty(Convert.ToString(jT808_0X0200.StatusFlag, 2).PadLeft(32, '0')); + if (jT808StatusProperty.Bit28 == '1')//西经 + { + jT808_0X0200.Lng = -jT808_0X0200.Lng; + } + if (jT808StatusProperty.Bit29 == '1')//南纬 + { + jT808_0X0200.Lat = -jT808_0X0200.Lat; + } + jT808_0X0200.Altitude = reader.ReadUInt16(); + jT808_0X0200.Speed = reader.ReadUInt16(); + jT808_0X0200.Direction = reader.ReadUInt16(); + jT808_0X0200.GPSTime = reader.ReadDateTime6(); + // 位置附加信息 + jT808_0X0200.JT808LocationAttachData = new Dictionary(); + jT808_0X0200.JT808CustomLocationAttachOriginalData = new Dictionary(); + jT808_0X0200.JT808UnknownLocationAttachOriginalData = new Dictionary(); + while (reader.ReadCurrentRemainContentLength()>0) + { + try + { + ReadOnlySpan attachSpan= reader.GetVirtualReadOnlySpan(2); + byte attachId = attachSpan[0]; + byte attachLen = attachSpan[1]; + if (JT808_0x0200_BodyBase.JT808LocationAttachMethod.TryGetValue(attachId, out Type jT808LocationAttachType)) + { + object attachImplObj = config.GetMessagePackFormatterByType(jT808LocationAttachType); + dynamic attachImpl = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize(attachImplObj,ref reader, config); + jT808_0X0200.JT808LocationAttachData.Add(attachImpl.AttachInfoId, attachImpl); + } + else if (config.JT808_0X0200_Custom_Factory.AttachIds.Contains(attachId)) + { + reader.Skip(2); + jT808_0X0200.JT808CustomLocationAttachOriginalData.Add(attachId, reader.ReadArray(reader.ReaderCount-2, attachLen+2).ToArray()); + reader.Skip(attachLen); + } + else + { + reader.Skip(2); + jT808_0X0200.JT808UnknownLocationAttachOriginalData.Add(attachId, reader.ReadArray(reader.ReaderCount-2, attachLen+2).ToArray()); + reader.Skip(attachLen); + } + } + catch + { + try + { + byte attachId = reader.ReadByte(); + byte attachLen = reader.ReadByte(); + jT808_0X0200.JT808UnknownLocationAttachOriginalData.Add(attachId, reader.ReadArray(reader.ReaderCount - 2, attachLen+2).ToArray()); + reader.Skip(attachLen); + } + catch (Exception ex) + { + throw; + } + } + } + return jT808_0X0200; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0200 value, IJT808Config config) + { + writer.WriteUInt32(value.AlarmFlag); + writer.WriteUInt32(value.StatusFlag); + writer.WriteInt32(value.Lat); + writer.WriteInt32(value.Lng); + writer.WriteUInt16(value.Altitude); + writer.WriteUInt16(value.Speed); + writer.WriteUInt16(value.Direction); + writer.WriteDateTime6(value.GPSTime); + if (value.JT808LocationAttachData != null && value.JT808LocationAttachData.Count > 0) + { + foreach (var item in value.JT808LocationAttachData) + { + try + { + object attachImplObj = config.GetMessagePackFormatterByType(item.Value.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(attachImplObj, ref writer,item.Value, config); + } + catch + { + + } + } + } + if (value.JT808CustomLocationAttachData != null && value.JT808CustomLocationAttachData.Count > 0) + { + foreach (var item in value.JT808CustomLocationAttachData) + { + object attachImplObj = config.GetMessagePackFormatterByType(item.Value.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(attachImplObj, ref writer, item.Value, config); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0201_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0201_Formatter.cs new file mode 100644 index 0000000..b5baf15 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0201_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0201_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0201 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0201 jT808_0X0201 = new JT808_0x0201(); + jT808_0X0201.MsgNum = reader.ReadUInt16(); + jT808_0X0201.Position = config.GetMessagePackFormatter().Deserialize(ref reader, config); + return jT808_0X0201; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0201 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + config.GetMessagePackFormatter().Serialize(ref writer,value.Position, config); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0301_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0301_Formatter.cs new file mode 100644 index 0000000..84dd00c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0301_Formatter.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0301_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0301 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0301 jT808_0X0301 = new JT808_0x0301(); + jT808_0X0301.EventId = reader.ReadByte(); + return jT808_0X0301; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0301 value, IJT808Config config) + { + writer.WriteByte(value.EventId); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0302_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0302_Formatter.cs new file mode 100644 index 0000000..ea1f2cd --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0302_Formatter.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0302_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0302 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0302 jT808_0X0302 = new JT808_0x0302(); + jT808_0X0302.ReplySNo = reader.ReadUInt16(); + jT808_0X0302.AnswerId = reader.ReadByte(); + return jT808_0X0302; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0302 value, IJT808Config config) + { + writer.WriteUInt16(value.ReplySNo); + writer.WriteByte(value.AnswerId); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0303_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0303_Formatter.cs new file mode 100644 index 0000000..9355fcf --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0303_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0303_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0303 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0303 jT808_0X0303 = new JT808_0x0303(); + jT808_0X0303.InformationType = reader.ReadByte(); + jT808_0X0303.Flag = reader.ReadByte(); + return jT808_0X0303; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0303 value, IJT808Config config) + { + writer.WriteByte(value.InformationType); + writer.WriteByte(value.Flag); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0500_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0500_Formatter.cs new file mode 100644 index 0000000..0681db1 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0500_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0500_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0500 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0500 jT808_0X0500 = new JT808_0x0500(); + jT808_0X0500.MsgNum = reader.ReadUInt16(); + jT808_0X0500.JT808_0x0200 = config.GetMessagePackFormatter().Deserialize(ref reader, config); + return jT808_0X0500; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0500 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + config.GetMessagePackFormatter().Serialize(ref writer, value.JT808_0x0200, config); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0701_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0701_Formatter.cs new file mode 100644 index 0000000..52cd25a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0701_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0701_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0701 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0701 jT808_0X0701 = new JT808_0x0701(); + jT808_0X0701.ElectronicWaybillLength = reader.ReadUInt32(); + jT808_0X0701.ElectronicContent = reader.ReadArray((int)jT808_0X0701.ElectronicWaybillLength).ToArray(); + return jT808_0X0701; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0701 value, IJT808Config config) + { + writer.Skip(4, out int skipPosition); + object obj = config.GetMessagePackFormatterByType(value.ElectronicContentObj.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(obj, ref writer, value.ElectronicContentObj, config); + int contentLength=writer.GetCurrentPosition()- skipPosition-4; + writer.WriteInt32Return(contentLength, skipPosition); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0702_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0702_Formatter.cs new file mode 100644 index 0000000..8185964 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0702_Formatter.cs @@ -0,0 +1,52 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0702_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0702 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0702 jT808_0X0702 = new JT808_0x0702(); + jT808_0X0702.IC_Card_Status = (JT808ICCardStatus)reader.ReadByte(); + jT808_0X0702.IC_Card_PlugDateTime = reader.ReadDateTime6(); + if (jT808_0X0702.IC_Card_Status == JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班) + { + jT808_0X0702.IC_Card_ReadResult = (JT808ICCardReadResult)reader.ReadByte(); + if (jT808_0X0702.IC_Card_ReadResult == JT808ICCardReadResult.IC卡读卡成功) + { + jT808_0X0702.DriverUserNameLength = reader.ReadByte(); + jT808_0X0702.DriverUserName = reader.ReadString( jT808_0X0702.DriverUserNameLength); + jT808_0X0702.QualificationCode = reader.ReadString(20); + jT808_0X0702.LicenseIssuingLength = reader.ReadByte(); + jT808_0X0702.LicenseIssuing = reader.ReadString(jT808_0X0702.LicenseIssuingLength); + jT808_0X0702.CertificateExpiresDate = reader.ReadDateTime4(); + } + } + return jT808_0X0702; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0702 value, IJT808Config config) + { + writer.WriteByte((byte)value.IC_Card_Status); + writer.WriteDateTime6(value.IC_Card_PlugDateTime); + if (value.IC_Card_Status == JT808ICCardStatus.从业资格证IC卡插入_驾驶员上班) + { + writer.WriteByte((byte)value.IC_Card_ReadResult); + if (value.IC_Card_ReadResult == JT808ICCardReadResult.IC卡读卡成功) + { + writer.WriteByte((byte)value.DriverUserName.Length); + writer.WriteString(value.DriverUserName); + writer.WriteString( value.QualificationCode.PadRight(20, '0')); + writer.WriteByte((byte)value.LicenseIssuing.Length); + writer.WriteString(value.LicenseIssuing); + writer.WriteDateTime4(value.CertificateExpiresDate); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0704_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0704_Formatter.cs new file mode 100644 index 0000000..33f9578 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0704_Formatter.cs @@ -0,0 +1,56 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0704_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0704 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0704 jT808_0X0704 = new JT808_0x0704(); + jT808_0X0704.Count = reader.ReadUInt16(); + jT808_0X0704.LocationType = (JT808_0x0704.BatchLocationType)reader.ReadByte(); + List jT808_0X0200s = new List(); + for (int i = 0; i < jT808_0X0704.Count; i++) + { + int buflen = reader.ReadUInt16(); + try + { + JT808MessagePackReader tmpReader = new JT808MessagePackReader(reader.ReadArray(buflen)); + JT808_0x0200 jT808_0X0200 = config.GetMessagePackFormatter().Deserialize(ref tmpReader, config); + jT808_0X0200s.Add(jT808_0X0200); + } + catch (Exception) + { + + } + } + jT808_0X0704.Positions = jT808_0X0200s; + return jT808_0X0704; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0704 value, IJT808Config config) + { + writer.WriteUInt16(value.Count); + writer.WriteByte((byte)value.LocationType); + foreach (var item in value?.Positions) + { + try + { + writer.Skip(2, out int position); + config.GetMessagePackFormatter().Serialize(ref writer, item, config); + ushort length = (ushort)(writer.GetCurrentPosition() - position - 2); + writer.WriteUInt16Return(length, position); + } + catch (Exception) + { + + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0705_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0705_Formatter.cs new file mode 100644 index 0000000..a95cbe1 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0705_Formatter.cs @@ -0,0 +1,60 @@ +using JT808.Protocol.Exceptions; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Metadata; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0705_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0705 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0705 jT808_0X0705 = new JT808_0x0705(); + jT808_0X0705.CanItemCount = reader.ReadUInt16(); + jT808_0X0705.FirstCanReceiveTime = reader.ReadDateTime5(); + jT808_0X0705.CanItems = new List(); + for (var i = 0; i < jT808_0X0705.CanItemCount; i++) + { + JT808CanProperty jT808CanProperty = new JT808CanProperty(); + jT808CanProperty.CanId = reader.ReadArray(4).ToArray(); + if (jT808CanProperty.CanId.Length != 4) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(jT808CanProperty.CanId)}->4"); + } + jT808CanProperty.CanData = reader.ReadArray(8).ToArray(); + if (jT808CanProperty.CanData.Length != 8) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(jT808CanProperty.CanData)}->8"); + } + jT808_0X0705.CanItems.Add(jT808CanProperty); + } + return jT808_0X0705; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0705 value, IJT808Config config) + { + if (value.CanItems != null && value.CanItems.Count > 0) + { + writer.WriteUInt16((ushort)value.CanItems.Count); + writer.WriteDateTime5(value.FirstCanReceiveTime); + foreach (var item in value.CanItems) + { + if (item.CanId.Length != 4) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(item.CanId)}->4"); + } + writer.WriteArray(item.CanId); + if (item.CanData.Length != 8) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(item.CanData)}->8"); + } + writer.WriteArray(item.CanData); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0800_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0800_Formatter.cs new file mode 100644 index 0000000..0e2356e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0800_Formatter.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0800_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0800 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0800 jT808_0X0800 = new JT808_0x0800(); + jT808_0X0800.MultimediaId = reader.ReadUInt32(); + jT808_0X0800.MultimediaType = reader.ReadByte(); + jT808_0X0800.MultimediaCodingFormat = reader.ReadByte(); + jT808_0X0800.EventItemCoding = reader.ReadByte(); + jT808_0X0800.ChannelId = reader.ReadByte(); + return jT808_0X0800; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0800 value, IJT808Config config) + { + writer.WriteUInt32(value.MultimediaId); + writer.WriteByte(value.MultimediaType); + writer.WriteByte(value.MultimediaCodingFormat); + writer.WriteByte(value.EventItemCoding); + writer.WriteByte(value.ChannelId); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0801_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0801_Formatter.cs new file mode 100644 index 0000000..e3e7088 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0801_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0801_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0801 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0801 jT808_0X0801 = new JT808_0x0801(); + jT808_0X0801.MultimediaId = reader.ReadUInt32(); + jT808_0X0801.MultimediaType = reader.ReadByte(); + jT808_0X0801.MultimediaCodingFormat = reader.ReadByte(); + jT808_0X0801.EventItemCoding = reader.ReadByte(); + jT808_0X0801.ChannelId = reader.ReadByte(); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + jT808_0X0801.Position = config.GetMessagePackFormatter().Deserialize(ref positionReader, config); + jT808_0X0801.MultimediaDataPackage = reader.ReadContent().ToArray(); + return jT808_0X0801; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0801 value, IJT808Config config) + { + writer.WriteUInt32(value.MultimediaId); + writer.WriteByte(value.MultimediaType); + writer.WriteByte(value.MultimediaCodingFormat); + writer.WriteByte(value.EventItemCoding); + writer.WriteByte(value.ChannelId); + config.GetMessagePackFormatter().Serialize(ref writer, value.Position, config); + writer.WriteArray(value.MultimediaDataPackage); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0802_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0802_Formatter.cs new file mode 100644 index 0000000..38f91fe --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0802_Formatter.cs @@ -0,0 +1,47 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0802_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0802 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0802 JT808_0x0802 = new JT808_0x0802(); + JT808_0x0802.MsgNum = reader.ReadUInt16(); + JT808_0x0802.MultimediaItemCount = reader.ReadUInt16(); + JT808_0x0802.MultimediaSearchItems = new List(); + for (var i = 0; i < JT808_0x0802.MultimediaItemCount; i++) + { + JT808MultimediaSearchProperty jT808MultimediaSearchProperty = new JT808MultimediaSearchProperty(); + jT808MultimediaSearchProperty.MultimediaId = reader.ReadUInt32(); + jT808MultimediaSearchProperty.MultimediaType = reader.ReadByte(); + jT808MultimediaSearchProperty.ChannelId = reader.ReadByte(); + jT808MultimediaSearchProperty.EventItemCoding = reader.ReadByte(); + JT808MessagePackReader positionReader = new JT808MessagePackReader(reader.ReadArray(28)); + jT808MultimediaSearchProperty.Position = config.GetMessagePackFormatter().Deserialize(ref positionReader, config); + JT808_0x0802.MultimediaSearchItems.Add(jT808MultimediaSearchProperty); + } + return JT808_0x0802; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0802 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteUInt16((ushort)value.MultimediaSearchItems.Count); + foreach (var item in value.MultimediaSearchItems) + { + writer.WriteUInt32(item.MultimediaId); + writer.WriteByte(item.MultimediaType); + writer.WriteByte(item.ChannelId); + writer.WriteByte(item.EventItemCoding); + config.GetMessagePackFormatter().Serialize(ref writer,item.Position, config); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0805_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0805_Formatter.cs new file mode 100644 index 0000000..80d1bc8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0805_Formatter.cs @@ -0,0 +1,38 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0805_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0805 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0805 jT808_0X0805 = new JT808_0x0805(); + jT808_0X0805.MsgNum = reader.ReadUInt16(); + jT808_0X0805.Result = reader.ReadByte(); + jT808_0X0805.MultimediaIdCount = reader.ReadUInt16(); + jT808_0X0805.MultimediaIds = new List(); + for (var i = 0; i < jT808_0X0805.MultimediaIdCount; i++) + { + uint id = reader.ReadUInt32(); + jT808_0X0805.MultimediaIds.Add(id); + } + return jT808_0X0805; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0805 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteByte(value.Result); + writer.WriteUInt16((ushort)value.MultimediaIds.Count); + foreach (var item in value.MultimediaIds) + { + writer.WriteUInt32(item); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0900_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0900_Formatter.cs new file mode 100644 index 0000000..0ae8b53 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0900_Formatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0900_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0900 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0900 jT808_0X0900 = new JT808_0x0900(); + jT808_0X0900.PassthroughType = reader.ReadByte(); + jT808_0X0900.PassthroughData = reader.ReadContent().ToArray(); ; + return jT808_0X0900; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0900 value, IJT808Config config) + { + writer.WriteByte(value.PassthroughType); + object obj = config.GetMessagePackFormatterByType(value.JT808_0x0900_BodyBase.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(obj, ref writer, value.JT808_0x0900_BodyBase, config); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0901_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0901_Formatter.cs new file mode 100644 index 0000000..f44bf5c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0901_Formatter.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0901_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0901 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0901 jT808_0X0901 = new JT808_0x0901(); + var compressMessageLength = reader.ReadUInt32(); + var data = reader.ReadArray((int)compressMessageLength); + jT808_0X0901.UnCompressMessage = config.Compress.Decompress(data.ToArray()); + jT808_0X0901.UnCompressMessageLength = (uint)jT808_0X0901.UnCompressMessage.Length; + return jT808_0X0901; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0901 value, IJT808Config config) + { + var data = config.Compress.Compress(value.UnCompressMessage); + writer.WriteUInt32((uint)data.Length); + writer.WriteArray(data); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0A00_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0A00_Formatter.cs new file mode 100644 index 0000000..b0deaf6 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x0A00_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Exceptions; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x0A00_Formatter : IJT808MessagePackFormatter + { + public JT808_0x0A00 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x0A00 jT808_0X0A00 = new JT808_0x0A00 + { + E = reader.ReadUInt32(), + N = reader.ReadArray(128).ToArray() + }; + if (jT808_0X0A00.N.Length != 128) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(jT808_0X0A00.N)}->128"); + } + return jT808_0X0A00; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0A00 value, IJT808Config config) + { + writer.WriteUInt32(value.E); + if (value.N.Length != 128) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(value.N)}->128"); + } + writer.WriteArray(value.N); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8001_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8001_Formatter.cs new file mode 100644 index 0000000..63067ac --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8001_Formatter.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8001_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8001 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8001 jT808_0X8001 = new JT808_0x8001(); + jT808_0X8001.MsgNum = reader.ReadUInt16(); + jT808_0X8001.MsgId = reader.ReadUInt16(); + jT808_0X8001.JT808PlatformResult = (JT808PlatformResult)reader.ReadByte(); + return jT808_0X8001; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8001 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteUInt16(value.MsgId); + writer.WriteByte((byte)value.JT808PlatformResult); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8003_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8003_Formatter.cs new file mode 100644 index 0000000..8e7513b --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8003_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8003_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8003 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8003 jT808_0X8003 = new JT808_0x8003(); + jT808_0X8003.OriginalMsgNum = reader.ReadUInt16(); + jT808_0X8003.AgainPackageCount = reader.ReadByte(); + jT808_0X8003.AgainPackageData = reader.ReadArray(jT808_0X8003.AgainPackageCount * 2).ToArray(); + return jT808_0X8003; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8003 value, IJT808Config config) + { + writer.WriteUInt16(value.OriginalMsgNum); + writer.WriteByte((byte)(value.AgainPackageData.Length / 2)); + writer.WriteArray(value.AgainPackageData); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8100_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8100_Formatter.cs new file mode 100644 index 0000000..5b8a5d5 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8100_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8100_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8100 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8100 jT808_0X8100 = new JT808_0x8100(); + jT808_0X8100.MsgNum = reader.ReadUInt16(); + jT808_0X8100.JT808TerminalRegisterResult = (JT808TerminalRegisterResult)reader.ReadByte(); + // 只有在成功后才有该字段 + if (jT808_0X8100.JT808TerminalRegisterResult == JT808TerminalRegisterResult.成功) + { + jT808_0X8100.Code = reader.ReadRemainStringContent(); + } + return jT808_0X8100; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8100 value, IJT808Config config) + { + writer.WriteUInt16(value.MsgNum); + writer.WriteByte((byte)value.JT808TerminalRegisterResult); + // 只有在成功后才有该字段 + if (value.JT808TerminalRegisterResult == JT808TerminalRegisterResult.成功) + { + writer.WriteString(value.Code); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0001_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0001_Formatter.cs new file mode 100644 index 0000000..8ca5346 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0001_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0001_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0001 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0001 jT808_0x8103_0x0001 = new JT808_0x8103_0x0001(); + jT808_0x8103_0x0001.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0001.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0001.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0001; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0001 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0002_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0002_Formatter.cs new file mode 100644 index 0000000..ee8c89e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0002_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0002_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0002 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0002 jT808_0x8103_0x0002 = new JT808_0x8103_0x0002(); + jT808_0x8103_0x0002.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0002.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0002.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0002; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0002 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0003_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0003_Formatter.cs new file mode 100644 index 0000000..8ee4429 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0003_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0003_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0003 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0003 jT808_0x8103_0x0003 = new JT808_0x8103_0x0003(); + jT808_0x8103_0x0003.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0003.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0003.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0003; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0003 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0004_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0004_Formatter.cs new file mode 100644 index 0000000..24e1033 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0004_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0004_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0004 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0004 jT808_0x8103_0x0004 = new JT808_0x8103_0x0004(); + jT808_0x8103_0x0004.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0004.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0004.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0004; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0004 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0005_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0005_Formatter.cs new file mode 100644 index 0000000..07cc5e3 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0005_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0005_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0005 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0005 jT808_0x8103_0x0005 = new JT808_0x8103_0x0005(); + jT808_0x8103_0x0005.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0005.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0005.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0005; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0005 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0006_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0006_Formatter.cs new file mode 100644 index 0000000..7b2a1b5 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0006_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0006_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0006 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0006 jT808_0x8103_0x0006 = new JT808_0x8103_0x0006(); + jT808_0x8103_0x0006.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0006.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0006.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0006; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0006 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0007_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0007_Formatter.cs new file mode 100644 index 0000000..5c857a8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0007_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0007_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0007 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0007 jT808_0x8103_0x0007 = new JT808_0x8103_0x0007(); + jT808_0x8103_0x0007.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0007.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0007.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0007; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0007 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0010_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0010_Formatter.cs new file mode 100644 index 0000000..c8d3264 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0010_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0010_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0010 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0010 jT808_0x8103_0x0010 = new JT808_0x8103_0x0010(); + jT808_0x8103_0x0010.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0010.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0010.ParamValue = reader.ReadString(jT808_0x8103_0x0010.ParamLength); + return jT808_0x8103_0x0010; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0010 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0011_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0011_Formatter.cs new file mode 100644 index 0000000..0d81c5d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0011_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0011_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0011 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0011 jT808_0x8103_0x0011 = new JT808_0x8103_0x0011(); + jT808_0x8103_0x0011.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0011.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0011.ParamValue = reader.ReadString( jT808_0x8103_0x0011.ParamLength); + return jT808_0x8103_0x0011; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0011 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0012_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0012_Formatter.cs new file mode 100644 index 0000000..286a81d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0012_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0012_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0012 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0012 jT808_0x8103_0x0012 = new JT808_0x8103_0x0012(); + jT808_0x8103_0x0012.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0012.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0012.ParamValue = reader.ReadString(jT808_0x8103_0x0012.ParamLength); + return jT808_0x8103_0x0012; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0012 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0013_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0013_Formatter.cs new file mode 100644 index 0000000..22eabe9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0013_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0013_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0013 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0013 jT808_0x8103_0x0013 = new JT808_0x8103_0x0013(); + jT808_0x8103_0x0013.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0013.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0013.ParamValue = reader.ReadString(jT808_0x8103_0x0013.ParamLength); + return jT808_0x8103_0x0013; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0013 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0014_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0014_Formatter.cs new file mode 100644 index 0000000..cb5adfd --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0014_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0014_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0014 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0014 jT808_0x8103_0x0014 = new JT808_0x8103_0x0014(); + jT808_0x8103_0x0014.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0014.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0014.ParamValue = reader.ReadString( jT808_0x8103_0x0014.ParamLength); + return jT808_0x8103_0x0014; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0014 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0015_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0015_Formatter.cs new file mode 100644 index 0000000..98d1b8f --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0015_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0015_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0015 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0015 jT808_0x8103_0x0015 = new JT808_0x8103_0x0015(); + jT808_0x8103_0x0015.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0015.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0015.ParamValue = reader.ReadString(jT808_0x8103_0x0015.ParamLength); + return jT808_0x8103_0x0015; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0015 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0016_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0016_Formatter.cs new file mode 100644 index 0000000..b14df16 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0016_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0016_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0016 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0016 jT808_0x8103_0x0016 = new JT808_0x8103_0x0016(); + jT808_0x8103_0x0016.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0016.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0016.ParamValue = reader.ReadString(jT808_0x8103_0x0016.ParamLength); + return jT808_0x8103_0x0016; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0016 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0017_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0017_Formatter.cs new file mode 100644 index 0000000..34f3890 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0017_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0017_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0017 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0017 jT808_0x8103_0x0017 = new JT808_0x8103_0x0017(); + jT808_0x8103_0x0017.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0017.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0017.ParamValue = reader.ReadString(jT808_0x8103_0x0017.ParamLength); + return jT808_0x8103_0x0017; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0017 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0018_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0018_Formatter.cs new file mode 100644 index 0000000..30f862f --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0018_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0018_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0018 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0018 jT808_0x8103_0x0018 = new JT808_0x8103_0x0018(); + jT808_0x8103_0x0018.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0018.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0018.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0018; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0018 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0019_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0019_Formatter.cs new file mode 100644 index 0000000..5ccd7a8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0019_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0019_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0019 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0019 jT808_0x8103_0x0019 = new JT808_0x8103_0x0019(); + jT808_0x8103_0x0019.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0019.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0019.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0019; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0019 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001A_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001A_Formatter.cs new file mode 100644 index 0000000..4b0327a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001A_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x001A_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x001A Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x001A jT808_0x8103_0x001A = new JT808_0x8103_0x001A(); + jT808_0x8103_0x001A.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x001A.ParamLength = reader.ReadByte(); + jT808_0x8103_0x001A.ParamValue = reader.ReadString( jT808_0x8103_0x001A.ParamLength); + return jT808_0x8103_0x001A; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x001A value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001B_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001B_Formatter.cs new file mode 100644 index 0000000..2edec78 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001B_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x001B_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x001B Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x001B jT808_0x8103_0x001B = new JT808_0x8103_0x001B(); + jT808_0x8103_0x001B.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x001B.ParamLength = reader.ReadByte(); + jT808_0x8103_0x001B.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x001B; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x001B value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001C_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001C_Formatter.cs new file mode 100644 index 0000000..57b1156 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001C_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x001C_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x001C Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x001C jT808_0x8103_0x001C = new JT808_0x8103_0x001C(); + jT808_0x8103_0x001C.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x001C.ParamLength = reader.ReadByte(); + jT808_0x8103_0x001C.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x001C; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x001C value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001D_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001D_Formatter.cs new file mode 100644 index 0000000..25d6d64 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x001D_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x001D_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x001D Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x001D jT808_0x8103_0x001D = new JT808_0x8103_0x001D(); + jT808_0x8103_0x001D.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x001D.ParamLength = reader.ReadByte(); + jT808_0x8103_0x001D.ParamValue = reader.ReadString(jT808_0x8103_0x001D.ParamLength); + return jT808_0x8103_0x001D; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x001D value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0020_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0020_Formatter.cs new file mode 100644 index 0000000..1686266 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0020_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0020_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0020 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0020 jT808_0x8103_0x0020 = new JT808_0x8103_0x0020(); + jT808_0x8103_0x0020.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0020.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0020.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0020; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0020 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0021_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0021_Formatter.cs new file mode 100644 index 0000000..ad2a472 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0021_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0021_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0021 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0021 jT808_0x8103_0x0021 = new JT808_0x8103_0x0021(); + jT808_0x8103_0x0021.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0021.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0021.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0021; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0021 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0022_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0022_Formatter.cs new file mode 100644 index 0000000..4e7f0dd --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0022_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0022_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0022 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0022 jT808_0x8103_0x0022 = new JT808_0x8103_0x0022(); + jT808_0x8103_0x0022.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0022.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0022.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0022; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0022 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0027_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0027_Formatter.cs new file mode 100644 index 0000000..5046401 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0027_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0027_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0027 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0027 jT808_0x8103_0x0027 = new JT808_0x8103_0x0027(); + jT808_0x8103_0x0027.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0027.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0027.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0027; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0027 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0028_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0028_Formatter.cs new file mode 100644 index 0000000..e7e4763 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0028_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0028_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0028 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0028 jT808_0x8103_0x0028 = new JT808_0x8103_0x0028(); + jT808_0x8103_0x0028.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0028.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0028.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0028; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0028 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0029_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0029_Formatter.cs new file mode 100644 index 0000000..1943d82 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0029_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0029_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0029 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0029 jT808_0x8103_0x0029 = new JT808_0x8103_0x0029(); + jT808_0x8103_0x0029.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0029.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0029.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0029; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0029 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002C_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002C_Formatter.cs new file mode 100644 index 0000000..f2b37e9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002C_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x002C_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x002C Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x002C jT808_0x8103_0x002C = new JT808_0x8103_0x002C(); + jT808_0x8103_0x002C.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x002C.ParamLength = reader.ReadByte(); + jT808_0x8103_0x002C.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x002C; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x002C value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002D_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002D_Formatter.cs new file mode 100644 index 0000000..6ffa8ce --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002D_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x002D_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x002D Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x002D jT808_0x8103_0x002D = new JT808_0x8103_0x002D(); + jT808_0x8103_0x002D.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x002D.ParamLength = reader.ReadByte(); + jT808_0x8103_0x002D.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x002D; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x002D value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002E_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002E_Formatter.cs new file mode 100644 index 0000000..b4f00eb --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002E_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x002E_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x002E Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x002E jT808_0x8103_0x002E = new JT808_0x8103_0x002E(); + jT808_0x8103_0x002E.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x002E.ParamLength = reader.ReadByte(); + jT808_0x8103_0x002E.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x002E; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x002E value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002F_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002F_Formatter.cs new file mode 100644 index 0000000..68c190f --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x002F_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x002F_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x002F Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x002F jT808_0x8103_0x002F = new JT808_0x8103_0x002F(); + jT808_0x8103_0x002F.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x002F.ParamLength = reader.ReadByte(); + jT808_0x8103_0x002F.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x002F; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x002F value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0030_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0030_Formatter.cs new file mode 100644 index 0000000..708d157 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0030_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0030_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0030 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0030 jT808_0x8103_0x0030 = new JT808_0x8103_0x0030(); + jT808_0x8103_0x0030.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0030.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0030.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0030; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0030 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0031_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0031_Formatter.cs new file mode 100644 index 0000000..fd6ff98 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0031_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0031_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0031 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0031 jT808_0x8103_0x0031 = new JT808_0x8103_0x0031(); + jT808_0x8103_0x0031.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0031.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0031.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x0031; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0031 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0040_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0040_Formatter.cs new file mode 100644 index 0000000..a077658 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0040_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0040_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0040 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0040 jT808_0x8103_0x0040 = new JT808_0x8103_0x0040(); + jT808_0x8103_0x0040.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0040.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0040.ParamValue = reader.ReadString( jT808_0x8103_0x0040.ParamLength); + return jT808_0x8103_0x0040; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0040 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0041_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0041_Formatter.cs new file mode 100644 index 0000000..a5eba3d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0041_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0041_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0041 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0041 jT808_0x8103_0x0041 = new JT808_0x8103_0x0041(); + jT808_0x8103_0x0041.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0041.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0041.ParamValue = reader.ReadString( jT808_0x8103_0x0041.ParamLength); + return jT808_0x8103_0x0041; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0041 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0042_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0042_Formatter.cs new file mode 100644 index 0000000..38f5b3a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0042_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0042_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0042 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0042 jT808_0x8103_0x0042 = new JT808_0x8103_0x0042(); + jT808_0x8103_0x0042.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0042.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0042.ParamValue = reader.ReadString(jT808_0x8103_0x0042.ParamLength); + return jT808_0x8103_0x0042; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0042 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0043_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0043_Formatter.cs new file mode 100644 index 0000000..593e6a8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0043_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0043_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0043 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0043 jT808_0x8103_0x0043 = new JT808_0x8103_0x0043(); + jT808_0x8103_0x0043.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0043.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0043.ParamValue = reader.ReadString(jT808_0x8103_0x0043.ParamLength); + return jT808_0x8103_0x0043; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0043 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0044_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0044_Formatter.cs new file mode 100644 index 0000000..5f3871a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0044_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0044_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0044 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0044 jT808_0x8103_0x0044 = new JT808_0x8103_0x0044(); + jT808_0x8103_0x0044.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0044.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0044.ParamValue = reader.ReadString(jT808_0x8103_0x0044.ParamLength); + return jT808_0x8103_0x0044; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0044 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0045_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0045_Formatter.cs new file mode 100644 index 0000000..306916b --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0045_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0045_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0045 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0045 jT808_0x8103_0x0045 = new JT808_0x8103_0x0045(); + jT808_0x8103_0x0045.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0045.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0045.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0045; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0045 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0046_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0046_Formatter.cs new file mode 100644 index 0000000..2e0a914 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0046_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0046_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0046 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0046 jT808_0x8103_0x0046 = new JT808_0x8103_0x0046(); + jT808_0x8103_0x0046.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0046.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0046.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0046; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0046 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0047_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0047_Formatter.cs new file mode 100644 index 0000000..73d7251 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0047_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0047_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0047 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0047 jT808_0x8103_0x0047 = new JT808_0x8103_0x0047(); + jT808_0x8103_0x0047.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0047.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0047.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0047; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0047 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0048_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0048_Formatter.cs new file mode 100644 index 0000000..7edac0a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0048_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0048_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0048 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0048 jT808_0x8103_0x0048 = new JT808_0x8103_0x0048(); + jT808_0x8103_0x0048.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0048.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0048.ParamValue = reader.ReadString(jT808_0x8103_0x0048.ParamLength); + return jT808_0x8103_0x0048; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0048 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0049_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0049_Formatter.cs new file mode 100644 index 0000000..24e3019 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0049_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0049_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0049 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0049 jT808_0x8103_0x0049 = new JT808_0x8103_0x0049(); + jT808_0x8103_0x0049.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0049.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0049.ParamValue = reader.ReadString( jT808_0x8103_0x0049.ParamLength); + return jT808_0x8103_0x0049; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0049 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0050_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0050_Formatter.cs new file mode 100644 index 0000000..4ecacbc --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0050_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0050_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0050 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0050 jT808_0x8103_0x0050 = new JT808_0x8103_0x0050(); + jT808_0x8103_0x0050.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0050.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0050.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0050; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0050 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0051_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0051_Formatter.cs new file mode 100644 index 0000000..dfab89a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0051_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0051_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0051 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0051 jT808_0x8103_0x0051 = new JT808_0x8103_0x0051(); + jT808_0x8103_0x0051.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0051.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0051.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0051; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0051 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0052_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0052_Formatter.cs new file mode 100644 index 0000000..cd39961 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0052_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0052_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0052 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0052 jT808_0x8103_0x0052 = new JT808_0x8103_0x0052(); + jT808_0x8103_0x0052.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0052.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0052.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0052; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0052 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0053_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0053_Formatter.cs new file mode 100644 index 0000000..937a9a8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0053_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0053_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0053 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0053 jT808_0x8103_0x0053 = new JT808_0x8103_0x0053(); + jT808_0x8103_0x0053.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0053.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0053.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0053; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0053 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0054_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0054_Formatter.cs new file mode 100644 index 0000000..0692771 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0054_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0054_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0054 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0054 jT808_0x8103_0x0054 = new JT808_0x8103_0x0054(); + jT808_0x8103_0x0054.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0054.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0054.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0054; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0054 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0055_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0055_Formatter.cs new file mode 100644 index 0000000..7f8084f --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0055_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0055_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0055 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0055 jT808_0x8103_0x0055 = new JT808_0x8103_0x0055(); + jT808_0x8103_0x0055.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0055.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0055.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0055; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0055 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0056_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0056_Formatter.cs new file mode 100644 index 0000000..532c01c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0056_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0056_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0056 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0056 jT808_0x8103_0x0056 = new JT808_0x8103_0x0056(); + jT808_0x8103_0x0056.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0056.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0056.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0056; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0056 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0057_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0057_Formatter.cs new file mode 100644 index 0000000..936522e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0057_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0057_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0057 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0057 jT808_0x8103_0x0057 = new JT808_0x8103_0x0057(); + jT808_0x8103_0x0057.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0057.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0057.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0057; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0057 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0058_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0058_Formatter.cs new file mode 100644 index 0000000..7f9b1f9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0058_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0058_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0058 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0058 jT808_0x8103_0x0058 = new JT808_0x8103_0x0058(); + jT808_0x8103_0x0058.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0058.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0058.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0058; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0058 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0059_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0059_Formatter.cs new file mode 100644 index 0000000..0aef393 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0059_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0059_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0059 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0059 jT808_0x8103_0x0059 = new JT808_0x8103_0x0059(); + jT808_0x8103_0x0059.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0059.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0059.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0059; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0059 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005A_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005A_Formatter.cs new file mode 100644 index 0000000..e70d25a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005A_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x005A_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x005A Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x005A jT808_0x8103_0x005A = new JT808_0x8103_0x005A(); + jT808_0x8103_0x005A.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x005A.ParamLength = reader.ReadByte(); + jT808_0x8103_0x005A.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x005A; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x005A value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005B_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005B_Formatter.cs new file mode 100644 index 0000000..7969dc5 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005B_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x005B_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x005B Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x005B jT808_0x8103_0x005B = new JT808_0x8103_0x005B(); + jT808_0x8103_0x005B.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x005B.ParamLength = reader.ReadByte(); + jT808_0x8103_0x005B.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x005B; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x005B value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005C_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005C_Formatter.cs new file mode 100644 index 0000000..d4a929c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005C_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x005C_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x005C Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x005C jT808_0x8103_0x005C = new JT808_0x8103_0x005C(); + jT808_0x8103_0x005C.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x005C.ParamLength = reader.ReadByte(); + jT808_0x8103_0x005C.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x005C; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x005C value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005D_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005D_Formatter.cs new file mode 100644 index 0000000..5859a98 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005D_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x005D_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x005D Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x005D jT808_0x8103_0x005D = new JT808_0x8103_0x005D(); + jT808_0x8103_0x005D.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x005D.ParamLength = reader.ReadByte(); + jT808_0x8103_0x005D.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x005D; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x005D value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005E_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005E_Formatter.cs new file mode 100644 index 0000000..11782b9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x005E_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x005E_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x005E Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x005E jT808_0x8103_0x005E = new JT808_0x8103_0x005E(); + jT808_0x8103_0x005E.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x005E.ParamLength = reader.ReadByte(); + jT808_0x8103_0x005E.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x005E; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x005E value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0064_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0064_Formatter.cs new file mode 100644 index 0000000..2098dbf --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0064_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0064_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0064 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0064 jT808_0x8103_0x0064 = new JT808_0x8103_0x0064(); + jT808_0x8103_0x0064.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0064.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0064.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0064; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0064 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0065_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0065_Formatter.cs new file mode 100644 index 0000000..23925e6 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0065_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0065_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0065 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0065 jT808_0x8103_0x0065 = new JT808_0x8103_0x0065(); + jT808_0x8103_0x0065.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0065.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0065.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0065; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0065 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0070_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0070_Formatter.cs new file mode 100644 index 0000000..649f021 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0070_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0070_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0070 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0070 jT808_0x8103_0x0070 = new JT808_0x8103_0x0070(); + jT808_0x8103_0x0070.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0070.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0070.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0070; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0070 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0071_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0071_Formatter.cs new file mode 100644 index 0000000..5461352 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0071_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0071_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0071 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0071 jT808_0x8103_0x0071 = new JT808_0x8103_0x0071(); + jT808_0x8103_0x0071.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0071.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0071.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0071; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0071 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0072_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0072_Formatter.cs new file mode 100644 index 0000000..895666c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0072_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0072_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0072 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0072 jT808_0x8103_0x0072 = new JT808_0x8103_0x0072(); + jT808_0x8103_0x0072.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0072.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0072.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0072; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0072 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0073_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0073_Formatter.cs new file mode 100644 index 0000000..d3c9989 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0073_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0073_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0073 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0073 jT808_0x8103_0x0073 = new JT808_0x8103_0x0073(); + jT808_0x8103_0x0073.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0073.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0073.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0073; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0073 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0074_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0074_Formatter.cs new file mode 100644 index 0000000..e889a76 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0074_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0074_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0074 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0074 jT808_0x8103_0x0074 = new JT808_0x8103_0x0074(); + jT808_0x8103_0x0074.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0074.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0074.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0074; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0074 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0080_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0080_Formatter.cs new file mode 100644 index 0000000..dc82d7e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0080_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0080_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0080 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0080 jT808_0x8103_0x0080 = new JT808_0x8103_0x0080(); + jT808_0x8103_0x0080.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0080.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0080.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0080; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0080 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0081_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0081_Formatter.cs new file mode 100644 index 0000000..d1ff8b7 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0081_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0081_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0081 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0081 jT808_0x8103_0x0081 = new JT808_0x8103_0x0081(); + jT808_0x8103_0x0081.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0081.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0081.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x0081; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0081 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0082_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0082_Formatter.cs new file mode 100644 index 0000000..44ae17a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0082_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0082_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0082 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0082 jT808_0x8103_0x0082 = new JT808_0x8103_0x0082(); + jT808_0x8103_0x0082.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0082.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0082.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x0082; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0082 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0083_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0083_Formatter.cs new file mode 100644 index 0000000..0bca2cb --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0083_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0083_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0083 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0083 jT808_0x8103_0x0083 = new JT808_0x8103_0x0083(); + jT808_0x8103_0x0083.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0083.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0083.ParamValue = reader.ReadString(jT808_0x8103_0x0083.ParamLength); + return jT808_0x8103_0x0083; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0083 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.Skip(1, out int skipPosition); + writer.WriteString(value.ParamValue); + int length = writer.GetCurrentPosition() - skipPosition - 1; + writer.WriteByteReturn((byte)length, skipPosition); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0084_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0084_Formatter.cs new file mode 100644 index 0000000..4ab1ab9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0084_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0084_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0084 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0084 jT808_0x8103_0x0084 = new JT808_0x8103_0x0084(); + jT808_0x8103_0x0084.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0084.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0084.ParamValue = reader.ReadByte(); + return jT808_0x8103_0x0084; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0084 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteByte(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0090_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0090_Formatter.cs new file mode 100644 index 0000000..6b1ffc2 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0090_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0090_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0090 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0090 jT808_0x8103_0x0090 = new JT808_0x8103_0x0090(); + jT808_0x8103_0x0090.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0090.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0090.ParamValue = reader.ReadByte(); + return jT808_0x8103_0x0090; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0090 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteByte(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0091_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0091_Formatter.cs new file mode 100644 index 0000000..c43f154 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0091_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0091_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0091 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0091 jT808_0x8103_0x0091 = new JT808_0x8103_0x0091(); + jT808_0x8103_0x0091.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0091.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0091.ParamValue = reader.ReadByte(); + return jT808_0x8103_0x0091; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0091 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteByte(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0092_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0092_Formatter.cs new file mode 100644 index 0000000..09e1c1f --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0092_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0092_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0092 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0092 jT808_0x8103_0x0092 = new JT808_0x8103_0x0092(); + jT808_0x8103_0x0092.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0092.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0092.ParamValue = reader.ReadByte(); + return jT808_0x8103_0x0092; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0092 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteByte(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0093_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0093_Formatter.cs new file mode 100644 index 0000000..1c09508 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0093_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0093_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0093 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0093 jT808_0x8103_0x0093 = new JT808_0x8103_0x0093(); + jT808_0x8103_0x0093.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0093.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0093.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0093; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0093 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0094_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0094_Formatter.cs new file mode 100644 index 0000000..bb28cdc --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0094_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0094_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0094 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0094 jT808_0x8103_0x0094 = new JT808_0x8103_0x0094(); + jT808_0x8103_0x0094.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0094.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0094.ParamValue = reader.ReadByte(); + return jT808_0x8103_0x0094; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0094 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteByte(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0095_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0095_Formatter.cs new file mode 100644 index 0000000..35b1dc2 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0095_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0095_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0095 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0095 jT808_0x8103_0x0095 = new JT808_0x8103_0x0095(); + jT808_0x8103_0x0095.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0095.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0095.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0095; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0095 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0100_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0100_Formatter.cs new file mode 100644 index 0000000..176d18a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0100_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0100_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0100 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0100 jT808_0x8103_0x0100 = new JT808_0x8103_0x0100(); + jT808_0x8103_0x0100.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0100.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0100.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0100; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0100 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0101_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0101_Formatter.cs new file mode 100644 index 0000000..f2dd085 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0101_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0101_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0101 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0101 jT808_0x8103_0x0101 = new JT808_0x8103_0x0101(); + jT808_0x8103_0x0101.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0101.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0101.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x0101; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0101 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0102_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0102_Formatter.cs new file mode 100644 index 0000000..2b909b2 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0102_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0102_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0102 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0102 jT808_0x8103_0x0102 = new JT808_0x8103_0x0102(); + jT808_0x8103_0x0102.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0102.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0102.ParamValue = reader.ReadUInt32(); + return jT808_0x8103_0x0102; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0102 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt32(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0103_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0103_Formatter.cs new file mode 100644 index 0000000..50165e4 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0103_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0103_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0103 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0103 jT808_0x8103_0x0103 = new JT808_0x8103_0x0103(); + jT808_0x8103_0x0103.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0103.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0103.ParamValue = reader.ReadUInt16(); + return jT808_0x8103_0x0103; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0103 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte(value.ParamLength); + writer.WriteUInt16(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0110_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0110_Formatter.cs new file mode 100644 index 0000000..fa0077e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_0x0110_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_0x0110_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103_0x0110 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103_0x0110 jT808_0x8103_0x0110 = new JT808_0x8103_0x0110(); + jT808_0x8103_0x0110.ParamId = reader.ReadUInt32(); + jT808_0x8103_0x0110.ParamLength = reader.ReadByte(); + jT808_0x8103_0x0110.ParamValue = reader.ReadArray(jT808_0x8103_0x0110.ParamLength).ToArray(); + return jT808_0x8103_0x0110; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103_0x0110 value, IJT808Config config) + { + writer.WriteUInt32(value.ParamId); + writer.WriteByte((byte)value.ParamValue.Length); + writer.WriteArray(value.ParamValue); + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_Formatter.cs new file mode 100644 index 0000000..dec980c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8103_Formatter.cs @@ -0,0 +1,65 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using JT808.Protocol.MessagePack; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8103_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8103 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8103 jT808_0x8103 = new JT808_0x8103 + { + ParamList = new List(), + CustomParamList = new List() + }; + var paramCount = reader.ReadByte();//参数总数 + try + { + for (int i = 0; i < paramCount; i++) + { + var paramId = reader.ReadVirtualUInt32();//参数ID + if (JT808_0x8103_BodyBase.JT808_0x8103Method.TryGetValue(paramId, out Type type)) + { + object attachImplObj = config.GetMessagePackFormatterByType(type); + dynamic attachImpl = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize(attachImplObj, ref reader, config); + jT808_0x8103.ParamList.Add(attachImpl); + } + else if (config.JT808_0X8103_Custom_Factory.ParamMethods.TryGetValue(paramId, out Type customType)) + { + object attachImplObj = config.GetMessagePackFormatterByType(customType); + dynamic attachImpl = JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize(attachImplObj, ref reader, config); + jT808_0x8103.ParamList.Add(attachImpl); + } + } + } + catch (Exception ex) { } + return jT808_0x8103; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8103 value, IJT808Config config) + { + writer.WriteByte(value.ParamCount); + try + { + foreach (var item in value.ParamList) + { + object attachImplObj = config.GetMessagePackFormatterByType(item.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(attachImplObj, ref writer, item, config); + } + if (value.CustomParamList != null) + { + foreach (var item in value.CustomParamList) + { + object attachImplObj = config.GetMessagePackFormatterByType(item.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(attachImplObj, ref writer, item, config); + } + } + } + catch (Exception ex) { } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8105_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8105_Formatter.cs new file mode 100644 index 0000000..84d7eff --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8105_Formatter.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8105_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8105 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8105 jT808_0x8105 = new JT808_0x8105 + { + CommandWord = reader.ReadByte() + }; + if (jT808_0x8105.CommandWord == 1 || jT808_0x8105.CommandWord == 2) + { + jT808_0x8105.CommandValue = new CommandParams(); + jT808_0x8105.CommandValue.SetCommandParams(reader.ReadRemainStringContent()); + } + return jT808_0x8105; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8105 value, IJT808Config config) + { + writer.WriteByte(value.CommandWord); + if (value.CommandWord == 1 || value.CommandWord == 2) + { + writer.WriteString(value.CommandValue.ToString()); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8106_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8106_Formatter.cs new file mode 100644 index 0000000..f86a1e1 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8106_Formatter.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8106_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8106 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8106 jT808_0X8106 = new JT808_0x8106(); + jT808_0X8106.ParameterCount = reader.ReadByte(); + jT808_0X8106.Parameters = new uint[jT808_0X8106.ParameterCount]; + for (int i = 0; i < jT808_0X8106.ParameterCount; i++) + { + jT808_0X8106.Parameters.SetValue(reader.ReadUInt32(), i); + } + return jT808_0X8106; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8106 value, IJT808Config config) + { + writer.WriteByte(value.ParameterCount); + for (int i = 0; i < value.ParameterCount; i++) + { + writer.WriteUInt32(value.Parameters[i]); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8108_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8108_Formatter.cs new file mode 100644 index 0000000..63180a6 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8108_Formatter.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8108_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8108 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8108 jT808_0X8108 = new JT808_0x8108(); + jT808_0X8108.UpgradeType = (JT808UpgradeType)reader.ReadByte(); + jT808_0X8108.MakerId = reader.ReadString(5); + jT808_0X8108.VersionNumLength = reader.ReadByte(); + jT808_0X8108.VersionNum = reader.ReadString(jT808_0X8108.VersionNumLength); + jT808_0X8108.UpgradePackageLength = reader.ReadInt32(); + jT808_0X8108.UpgradePackage = reader.ReadArray(jT808_0X8108.UpgradePackageLength).ToArray(); + return jT808_0X8108; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8108 value, IJT808Config config) + { + writer.WriteByte((byte)value.UpgradeType); + writer.WriteString(value.MakerId.PadRight(5, '0')); + writer.WriteByte((byte)value.VersionNum.Length); + writer.WriteString(value.VersionNum); + writer.WriteInt32(value.UpgradePackage.Length); + writer.WriteArray(value.UpgradePackage); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8202_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8202_Formatter.cs new file mode 100644 index 0000000..e562aa9 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8202_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8202_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8202 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8202 jT808_0X8202 = new JT808_0x8202(); + jT808_0X8202.Interval = reader.ReadUInt16(); + jT808_0X8202.LocationTrackingValidity = reader.ReadInt32(); + return jT808_0X8202; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8202 value, IJT808Config config) + { + writer.WriteUInt16(value.Interval); + writer.WriteInt32(value.LocationTrackingValidity); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8203_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8203_Formatter.cs new file mode 100644 index 0000000..8c8dd6c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8203_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8203_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8203 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8203 jT808_0X8203 = new JT808_0x8203(); + jT808_0X8203.AlarmMsgNum = reader.ReadUInt16(); + jT808_0X8203.ManualConfirmAlarmType = reader.ReadUInt32(); + return jT808_0X8203; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8203 value, IJT808Config config) + { + writer.WriteUInt16(value.AlarmMsgNum); + writer.WriteUInt32(value.ManualConfirmAlarmType); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8300_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8300_Formatter.cs new file mode 100644 index 0000000..9410829 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8300_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8300_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8300 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8300 jT808_0X8300 = new JT808_0x8300(); + jT808_0X8300.TextFlag = reader.ReadByte(); + jT808_0X8300.TextInfo = reader.ReadRemainStringContent(); + return jT808_0X8300; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8300 value, IJT808Config config) + { + writer.WriteByte(value.TextFlag); + writer.WriteString(value.TextInfo); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8301_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8301_Formatter.cs new file mode 100644 index 0000000..a8ad2ad --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8301_Formatter.cs @@ -0,0 +1,48 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8301_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8301 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8301 jT808_0X8301 = new JT808_0x8301(); + jT808_0X8301.SettingType = reader.ReadByte(); + jT808_0X8301.SettingCount = reader.ReadByte(); + jT808_0X8301.EventItems = new List(); + for (var i = 0; i < jT808_0X8301.SettingCount; i++) + { + JT808EventProperty jT808EventProperty = new JT808EventProperty(); + jT808EventProperty.EventId = reader.ReadByte(); + jT808EventProperty.EventContentLength = reader.ReadByte(); + jT808EventProperty.EventContent = reader.ReadString(jT808EventProperty.EventContentLength); + jT808_0X8301.EventItems.Add(jT808EventProperty); + } + return jT808_0X8301; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8301 value, IJT808Config config) + { + writer.WriteByte(value.SettingType); + if (value.EventItems != null && value.EventItems.Count > 0) + { + writer.WriteByte((byte)value.EventItems.Count); + foreach (var item in value.EventItems) + { + writer.WriteByte(item.EventId); + // 先计算内容长度(汉字为两个字节) + writer.Skip(1, out int eventPosition); + writer.WriteString(item.EventContent); + byte eventLength = (byte)(writer.GetCurrentPosition() - eventPosition - 1); + writer.WriteByteReturn(eventLength, eventPosition); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8302_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8302_Formatter.cs new file mode 100644 index 0000000..dead93e --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8302_Formatter.cs @@ -0,0 +1,38 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8302_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8302 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8302 jT808_0X8302 = new JT808_0x8302(); + jT808_0X8302.Flag = reader.ReadByte(); + jT808_0X8302.IssueContentLength = reader.ReadByte(); + jT808_0X8302.Issue = reader.ReadString(jT808_0X8302.IssueContentLength); + jT808_0X8302.AnswerId = reader.ReadByte(); + jT808_0X8302.AnswerContentLength = reader.ReadUInt16(); + jT808_0X8302.AnswerContent = reader.ReadString(jT808_0X8302.AnswerContentLength); + return jT808_0X8302; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8302 value, IJT808Config config) + { + writer.WriteByte(value.Flag); + // 先计算内容长度(汉字为两个字节) + writer.Skip(1, out int issuePosition); + writer.WriteString(value.Issue); + ushort issueLength = (ushort)(writer.GetCurrentPosition() - issuePosition - 1); + writer.WriteByteReturn((byte)issueLength, issuePosition); + writer.WriteByte(value.AnswerId); + writer.Skip(2, out int answerPosition); + writer.WriteString(value.AnswerContent); + ushort answerLength = (ushort)(writer.GetCurrentPosition() - answerPosition - 2); + writer.WriteUInt16Return(answerLength, answerPosition); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8303_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8303_Formatter.cs new file mode 100644 index 0000000..8865b10 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8303_Formatter.cs @@ -0,0 +1,45 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8303_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8303 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8303 jT808_0X8303 = new JT808_0x8303(); + jT808_0X8303.SettingType = reader.ReadByte(); + jT808_0X8303.InformationItemCount = reader.ReadByte(); + jT808_0X8303.InformationItems = new List(); + for (var i = 0; i < jT808_0X8303.InformationItemCount; i++) + { + JT808InformationItemProperty jT808InformationItemProperty = new JT808InformationItemProperty(); + jT808InformationItemProperty.InformationType = reader.ReadByte(); + jT808InformationItemProperty.InformationLength = reader.ReadUInt16(); + jT808InformationItemProperty.InformationName = reader.ReadString(jT808InformationItemProperty.InformationLength); + jT808_0X8303.InformationItems.Add(jT808InformationItemProperty); + } + return jT808_0X8303; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8303 value, IJT808Config config) + { + writer.WriteByte(value.SettingType); + writer.WriteByte((byte)value.InformationItems.Count); + foreach (var item in value.InformationItems) + { + writer.WriteByte(item.InformationType); + // 先计算内容长度(汉字为两个字节) + writer.Skip(2, out int position); + writer.WriteString(item.InformationName); + ushort length = (ushort)(writer.GetCurrentPosition() - position - 2); + writer.WriteUInt16Return(length, position); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8304_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8304_Formatter.cs new file mode 100644 index 0000000..25e3b91 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8304_Formatter.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8304_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8304 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8304 jT808_0X8304 = new JT808_0x8304(); + jT808_0X8304.InformationType = reader.ReadByte(); + jT808_0X8304.InformationLength = reader.ReadUInt16(); + jT808_0X8304.InformationContent = reader.ReadString(jT808_0X8304.InformationLength); + return jT808_0X8304; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8304 value, IJT808Config config) + { + writer.WriteByte(value.InformationType); + // 先计算内容长度(汉字为两个字节) + writer.Skip(2, out int position); + writer.WriteString(value.InformationContent); + ushort length =(ushort)( writer.GetCurrentPosition() - position - 2); + writer.WriteUInt16Return(length, position); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8400_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8400_Formatter.cs new file mode 100644 index 0000000..4a31d2c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8400_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8400_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8400 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8400 jT808_0X8400 = new JT808_0x8400(); + jT808_0X8400.CallBack = (JT808CallBackType)reader.ReadByte(); + // 最长为 20 字节 + jT808_0X8400.PhoneNumber = reader.ReadRemainStringContent(); + return jT808_0X8400; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8400 value, IJT808Config config) + { + writer.WriteByte((byte)value.CallBack); + writer.WriteString(value.PhoneNumber); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8401_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8401_Formatter.cs new file mode 100644 index 0000000..b394326 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8401_Formatter.cs @@ -0,0 +1,48 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8401_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8401 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8401 jT808_0X8401 = new JT808_0x8401(); + jT808_0X8401.SettingTelephoneBook = (JT808SettingTelephoneBook)reader.ReadByte(); + jT808_0X8401.ContactCount = reader.ReadByte(); + List jT808_0X8401s = new List(); + for (var i = 0; i < jT808_0X8401.ContactCount; i++) + { + JT808ContactProperty jT808ContactProperty = new JT808ContactProperty(); + jT808ContactProperty.TelephoneBookContactType = (JT808TelephoneBookContactType)reader.ReadByte(); + jT808ContactProperty.PhoneNumberLength = reader.ReadByte(); + jT808ContactProperty.PhoneNumber = reader.ReadString(jT808ContactProperty.PhoneNumberLength); + jT808ContactProperty.ContactLength = reader.ReadByte(); + jT808ContactProperty.Contact = reader.ReadString(jT808ContactProperty.ContactLength); + jT808_0X8401s.Add(jT808ContactProperty); + } + jT808_0X8401.JT808ContactProperties = jT808_0X8401s; + return jT808_0X8401; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8401 value, IJT808Config config) + { + writer.WriteByte((byte)value.SettingTelephoneBook); + writer.WriteByte((byte)value.JT808ContactProperties.Count); + foreach (var item in value.JT808ContactProperties) + { + writer.WriteByte((byte)item.TelephoneBookContactType); + writer.WriteByte((byte)item.PhoneNumber.Length); + writer.WriteString(item.PhoneNumber); + writer.WriteByte((byte)item.Contact.Length); + writer.WriteString(item.Contact); + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8500_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8500_Formatter.cs new file mode 100644 index 0000000..fc5d0a8 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8500_Formatter.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8500_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8500 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8500 jT808_0X8500 = new JT808_0x8500(); + jT808_0X8500.ControlFlag = reader.ReadByte(); + return jT808_0X8500; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8500 value, IJT808Config config) + { + writer.WriteByte(value.ControlFlag); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8600_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8600_Formatter.cs new file mode 100644 index 0000000..c27416a --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8600_Formatter.cs @@ -0,0 +1,87 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8600_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8600 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8600 jT808_0X8600 = new JT808_0x8600(); + jT808_0X8600.SettingAreaProperty = reader.ReadByte(); + jT808_0X8600.AreaCount = reader.ReadByte(); + jT808_0X8600.AreaItems = new List(); + for (var i = 0; i < jT808_0X8600.AreaCount; i++) + { + JT808CircleAreaProperty jT808CircleAreaProperty = new JT808CircleAreaProperty(); + jT808CircleAreaProperty.AreaId = reader.ReadUInt32(); + jT808CircleAreaProperty.AreaProperty = reader.ReadUInt16(); + jT808CircleAreaProperty.CenterPointLat = reader.ReadUInt32(); + jT808CircleAreaProperty.CenterPointLng = reader.ReadUInt32(); + jT808CircleAreaProperty.Radius = reader.ReadUInt32(); + ReadOnlySpan areaProperty16Bit = Convert.ToString(jT808CircleAreaProperty.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + jT808CircleAreaProperty.StartTime = reader.ReadDateTime6(); + jT808CircleAreaProperty.EndTime = reader.ReadDateTime6(); + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + jT808CircleAreaProperty.HighestSpeed = reader.ReadUInt16(); + jT808CircleAreaProperty.OverspeedDuration = reader.ReadByte(); + } + jT808_0X8600.AreaItems.Add(jT808CircleAreaProperty); + } + return jT808_0X8600; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8600 value, IJT808Config config) + { + writer.WriteByte(value.SettingAreaProperty); + if (value.AreaItems != null) + { + writer.WriteByte((byte)value.AreaItems.Count); + foreach (var item in value.AreaItems) + { + writer.WriteUInt32(item.AreaId); + writer.WriteUInt16(item.AreaProperty); + writer.WriteUInt32(item.CenterPointLat); + writer.WriteUInt32(item.CenterPointLng); + writer.WriteUInt32(item.Radius); + ReadOnlySpan areaProperty16Bit = Convert.ToString(item.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + if (item.StartTime.HasValue) + { + writer.WriteDateTime6(item.StartTime.Value); + } + if (item.EndTime.HasValue) + { + writer.WriteDateTime6(item.EndTime.Value); + } + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + if (item.HighestSpeed.HasValue) + { + writer.WriteUInt16(item.HighestSpeed.Value); + } + if (item.OverspeedDuration.HasValue) + { + writer.WriteByte(item.OverspeedDuration.Value); + } + } + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8601_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8601_Formatter.cs new file mode 100644 index 0000000..f62638d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8601_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8601_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8601 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8601 jT808_0X8601 = new JT808_0x8601(); + jT808_0X8601.AreaCount = reader.ReadByte(); + jT808_0X8601.AreaIds = new List(); + for (var i = 0; i < jT808_0X8601.AreaCount; i++) + { + jT808_0X8601.AreaIds.Add(reader.ReadUInt32()); + } + return jT808_0X8601; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8601 value, IJT808Config config) + { + if (value.AreaIds != null) + { + writer.WriteByte((byte)value.AreaIds.Count); + foreach (var item in value.AreaIds) + { + writer.WriteUInt32(item); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8602_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8602_Formatter.cs new file mode 100644 index 0000000..9d88adb --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8602_Formatter.cs @@ -0,0 +1,89 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8602_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8602 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8602 jT808_0X8602 = new JT808_0x8602(); + jT808_0X8602.SettingAreaProperty = reader.ReadByte(); + jT808_0X8602.AreaCount = reader.ReadByte(); + jT808_0X8602.AreaItems = new List(); + for (var i = 0; i < jT808_0X8602.AreaCount; i++) + { + JT808RectangleAreaProperty jT808CircleAreaProperty = new JT808RectangleAreaProperty(); + jT808CircleAreaProperty.AreaId = reader.ReadUInt32(); + jT808CircleAreaProperty.AreaProperty = reader.ReadUInt16(); + jT808CircleAreaProperty.UpLeftPointLat = reader.ReadUInt32(); + jT808CircleAreaProperty.UpLeftPointLng = reader.ReadUInt32(); + jT808CircleAreaProperty.LowRightPointLat = reader.ReadUInt32(); + jT808CircleAreaProperty.LowRightPointLng = reader.ReadUInt32(); + ReadOnlySpan areaProperty16Bit = Convert.ToString(jT808CircleAreaProperty.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + jT808CircleAreaProperty.StartTime = reader.ReadDateTime6(); + jT808CircleAreaProperty.EndTime = reader.ReadDateTime6(); + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + jT808CircleAreaProperty.HighestSpeed = reader.ReadUInt16(); + jT808CircleAreaProperty.OverspeedDuration = reader.ReadByte(); + } + jT808_0X8602.AreaItems.Add(jT808CircleAreaProperty); + } + return jT808_0X8602; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8602 value, IJT808Config config) + { + writer.WriteByte( value.SettingAreaProperty); + if (value.AreaItems != null) + { + writer.WriteByte((byte)value.AreaItems.Count); + foreach (var item in value.AreaItems) + { + writer.WriteUInt32( item.AreaId); + writer.WriteUInt16( item.AreaProperty); + writer.WriteUInt32( item.UpLeftPointLat); + writer.WriteUInt32( item.UpLeftPointLng); + writer.WriteUInt32( item.LowRightPointLat); + writer.WriteUInt32( item.LowRightPointLng); + ReadOnlySpan areaProperty16Bit = Convert.ToString(item.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + if (item.StartTime.HasValue) + { + writer.WriteDateTime6(item.StartTime.Value); + } + if (item.EndTime.HasValue) + { + writer.WriteDateTime6(item.EndTime.Value); + } + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + if (item.HighestSpeed.HasValue) + { + writer.WriteUInt16(item.HighestSpeed.Value); + } + if (item.OverspeedDuration.HasValue) + { + writer.WriteByte( item.OverspeedDuration.Value); + } + } + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8603_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8603_Formatter.cs new file mode 100644 index 0000000..47bec87 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8603_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8603_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8603 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8603 jT808_0X8603 = new JT808_0x8603(); + jT808_0X8603.AreaCount = reader.ReadByte(); + jT808_0X8603.AreaIds = new List(); + for (var i = 0; i < jT808_0X8603.AreaCount; i++) + { + jT808_0X8603.AreaIds.Add(reader.ReadUInt32()); + } + return jT808_0X8603; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8603 value, IJT808Config config) + { + if (value.AreaIds != null) + { + writer.WriteByte((byte)value.AreaIds.Count); + foreach (var item in value.AreaIds) + { + writer.WriteUInt32(item); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8604_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8604_Formatter.cs new file mode 100644 index 0000000..f7d7f28 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8604_Formatter.cs @@ -0,0 +1,83 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8604_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8604 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8604 jT808_0X8604 = new JT808_0x8604(); + jT808_0X8604.AreaId = reader.ReadUInt32(); + jT808_0X8604.AreaProperty = reader.ReadUInt16(); + ReadOnlySpan areaProperty16Bit = Convert.ToString(jT808_0X8604.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + jT808_0X8604.StartTime = reader.ReadDateTime6(); + jT808_0X8604.EndTime = reader.ReadDateTime6(); + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + jT808_0X8604.HighestSpeed = reader.ReadUInt16(); + jT808_0X8604.OverspeedDuration = reader.ReadByte(); + } + jT808_0X8604.PeakCount = reader.ReadUInt16(); + jT808_0X8604.PeakItems = new List(); + for (var i = 0; i < jT808_0X8604.PeakCount; i++) + { + var item = new JT808PeakProperty(); + item.Lat = reader.ReadUInt32(); + item.Lng = reader.ReadUInt32(); + jT808_0X8604.PeakItems.Add(item); + } + return jT808_0X8604; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8604 value, IJT808Config config) + { + writer.WriteUInt32(value.AreaId); + writer.WriteUInt16(value.AreaProperty); + ReadOnlySpan areaProperty16Bit = Convert.ToString(value.AreaProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + if (value.StartTime.HasValue) + { + writer.WriteDateTime6(value.StartTime.Value); + } + if (value.EndTime.HasValue) + { + writer.WriteDateTime6(value.EndTime.Value); + } + } + bool bit1Flag = areaProperty16Bit.Slice(areaProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!bit1Flag) + { + if (value.HighestSpeed.HasValue) + { + writer.WriteUInt16(value.HighestSpeed.Value); + } + if (value.OverspeedDuration.HasValue) + { + writer.WriteByte(value.OverspeedDuration.Value); + } + } + if (value.PeakItems != null && value.PeakItems.Count > 0) + { + writer.WriteUInt16((ushort)value.PeakItems.Count); + foreach (var item in value.PeakItems) + { + writer.WriteUInt32(item.Lat); + writer.WriteUInt32(item.Lng); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8605_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8605_Formatter.cs new file mode 100644 index 0000000..a3b588b --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8605_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8605_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8605 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8605 jT808_0X8605 = new JT808_0x8605(); + jT808_0X8605.AreaCount = reader.ReadByte(); + jT808_0X8605.AreaIds = new List(); + for (var i = 0; i < jT808_0X8605.AreaCount; i++) + { + jT808_0X8605.AreaIds.Add(reader.ReadUInt32()); + } + return jT808_0X8605; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8605 value, IJT808Config config) + { + if (value.AreaIds != null) + { + writer.WriteByte((byte)value.AreaIds.Count); + foreach (var item in value.AreaIds) + { + writer.WriteUInt32(item); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8606_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8606_Formatter.cs new file mode 100644 index 0000000..3081e0c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8606_Formatter.cs @@ -0,0 +1,102 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Metadata; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8606_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8606 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8606 jT808_0X8606 = new JT808_0x8606(); + jT808_0X8606.RouteId = reader.ReadUInt32(); + jT808_0X8606.RouteProperty = reader.ReadUInt16(); + ReadOnlySpan routeProperty16Bit = Convert.ToString(jT808_0X8606.RouteProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = routeProperty16Bit.Slice(routeProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + jT808_0X8606.StartTime = reader.ReadDateTime6(); + jT808_0X8606.EndTime = reader.ReadDateTime6(); + } + jT808_0X8606.InflectionPointCount = reader.ReadUInt16(); + jT808_0X8606.InflectionPointItems = new List(); + for (var i = 0; i < jT808_0X8606.InflectionPointCount; i++) + { + JT808InflectionPointProperty jT808InflectionPointProperty = new JT808InflectionPointProperty(); + jT808InflectionPointProperty.InflectionPointId = reader.ReadUInt32(); + jT808InflectionPointProperty.SectionId = reader.ReadUInt32(); + jT808InflectionPointProperty.InflectionPointLat = reader.ReadUInt32(); + jT808InflectionPointProperty.InflectionPointLng = reader.ReadUInt32(); + jT808InflectionPointProperty.SectionWidth = reader.ReadByte(); + jT808InflectionPointProperty.SectionProperty = reader.ReadByte(); + ReadOnlySpan sectionProperty16Bit = Convert.ToString(jT808InflectionPointProperty.SectionProperty, 2).PadLeft(16, '0').AsSpan(); + bool sectionBit0Flag = sectionProperty16Bit.Slice(sectionProperty16Bit.Length - 1).ToString().Equals("0"); + if (!sectionBit0Flag) + { + jT808InflectionPointProperty.SectionLongDrivingThreshold = reader.ReadUInt16(); + jT808InflectionPointProperty.SectionDrivingUnderThreshold = reader.ReadUInt16(); + } + bool sectionBit1Flag = sectionProperty16Bit.Slice(sectionProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!sectionBit1Flag) + { + jT808InflectionPointProperty.SectionHighestSpeed = reader.ReadUInt16(); + jT808InflectionPointProperty.SectionOverspeedDuration = reader.ReadByte(); + } + jT808_0X8606.InflectionPointItems.Add(jT808InflectionPointProperty); + } + return jT808_0X8606; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8606 value, IJT808Config config) + { + writer.WriteUInt32(value.RouteId); + writer.WriteUInt16(value.RouteProperty); + ReadOnlySpan routeProperty16Bit = Convert.ToString(value.RouteProperty, 2).PadLeft(16, '0').AsSpan(); + bool bit0Flag = routeProperty16Bit.Slice(routeProperty16Bit.Length - 1).ToString().Equals("0"); + if (!bit0Flag) + { + if (value.StartTime.HasValue) + writer.WriteDateTime6(value.StartTime.Value); + + if (value.EndTime.HasValue) + writer.WriteDateTime6(value.EndTime.Value); + } + //bool bit1Flag = routeProperty16Bit.Slice(routeProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (value.InflectionPointItems != null && value.InflectionPointItems.Count > 0) + { + writer.WriteUInt16((ushort)value.InflectionPointItems.Count); + foreach (var item in value.InflectionPointItems) + { + writer.WriteUInt32( item.InflectionPointId); + writer.WriteUInt32( item.SectionId); + writer.WriteUInt32(item.InflectionPointLat); + writer.WriteUInt32(item.InflectionPointLng); + writer.WriteByte(item.SectionWidth); + writer.WriteByte(item.SectionProperty); + + ReadOnlySpan sectionProperty16Bit = Convert.ToString(item.SectionProperty, 2).PadLeft(16, '0').AsSpan(); + bool sectionBit0Flag = sectionProperty16Bit.Slice(sectionProperty16Bit.Length - 1).ToString().Equals("0"); + if (!sectionBit0Flag) + { + if (item.SectionLongDrivingThreshold.HasValue) + writer.WriteUInt16(item.SectionLongDrivingThreshold.Value); + if (item.SectionDrivingUnderThreshold.HasValue) + writer.WriteUInt16(item.SectionDrivingUnderThreshold.Value); + } + bool sectionBit1Flag = sectionProperty16Bit.Slice(sectionProperty16Bit.Length - 2, 1).ToString().Equals("0"); + if (!sectionBit1Flag) + { + if (item.SectionHighestSpeed.HasValue) + writer.WriteUInt16(item.SectionHighestSpeed.Value); + if (item.SectionOverspeedDuration.HasValue) + writer.WriteByte(item.SectionOverspeedDuration.Value); + } + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8607_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8607_Formatter.cs new file mode 100644 index 0000000..270a4ce --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8607_Formatter.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8607_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8607 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8607 jT808_0X8607 = new JT808_0x8607(); + jT808_0X8607.AreaCount = reader.ReadByte(); + jT808_0X8607.AreaIds = new List(); + for (var i = 0; i < jT808_0X8607.AreaCount; i++) + { + jT808_0X8607.AreaIds.Add(reader.ReadUInt32()); + } + return jT808_0X8607; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8607 value, IJT808Config config) + { + if (value.AreaIds != null) + { + writer.WriteByte((byte)value.AreaIds.Count); + foreach (var item in value.AreaIds) + { + writer.WriteUInt32(item); + } + } + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8800_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8800_Formatter.cs new file mode 100644 index 0000000..11d3ab5 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8800_Formatter.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8800_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8800 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8800 jT808_0X8800 = new JT808_0x8800(); + jT808_0X8800.MultimediaId = reader.ReadUInt32(); + jT808_0X8800.RetransmitPackageCount = reader.ReadByte(); + jT808_0X8800.RetransmitPackageIds = reader.ReadArray(jT808_0X8800.RetransmitPackageCount * 2).ToArray(); + return jT808_0X8800; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8800 value, IJT808Config config) + { + writer.WriteUInt32(value.MultimediaId); + writer.WriteByte((byte)(value.RetransmitPackageIds.Length / 2)); + writer.WriteArray(value.RetransmitPackageIds); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8801_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8801_Formatter.cs new file mode 100644 index 0000000..4ff64fd --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8801_Formatter.cs @@ -0,0 +1,41 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8801_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8801 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8801 jT808_0X8801 = new JT808_0x8801(); + jT808_0X8801.ChannelId = reader.ReadByte(); + jT808_0X8801.ShootingCommand = reader.ReadUInt16(); + jT808_0X8801.VideoTime = reader.ReadUInt16(); + jT808_0X8801.SaveFlag = reader.ReadByte(); + jT808_0X8801.Resolution = reader.ReadByte(); + jT808_0X8801.VideoQuality = reader.ReadByte(); + jT808_0X8801.Lighting = reader.ReadByte(); + jT808_0X8801.Contrast = reader.ReadByte(); + jT808_0X8801.Saturability = reader.ReadByte(); + jT808_0X8801.Chroma = reader.ReadByte(); + return jT808_0X8801; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8801 value, IJT808Config config) + { + writer.WriteByte(value.ChannelId); + writer.WriteUInt16(value.ShootingCommand); + writer.WriteUInt16(value.VideoTime); + writer.WriteByte(value.SaveFlag); + writer.WriteByte(value.Resolution); + writer.WriteByte(value.VideoQuality); + writer.WriteByte(value.Lighting); + writer.WriteByte(value.Contrast); + writer.WriteByte(value.Saturability); + writer.WriteByte(value.Chroma); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8802_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8802_Formatter.cs new file mode 100644 index 0000000..dc03818 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8802_Formatter.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8802_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8802 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8802 jT808_0X8802 = new JT808_0x8802(); + jT808_0X8802.MultimediaType = reader.ReadByte(); + jT808_0X8802.ChannelId = reader.ReadByte(); + jT808_0X8802.EventItemCoding = reader.ReadByte(); + jT808_0X8802.StartTime = reader.ReadDateTime6(); + jT808_0X8802.EndTime = reader.ReadDateTime6(); + return jT808_0X8802; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8802 value, IJT808Config config) + { + writer.WriteByte(value.MultimediaType); + writer.WriteByte(value.ChannelId); + writer.WriteByte(value.EventItemCoding); + writer.WriteDateTime6(value.StartTime); + writer.WriteDateTime6(value.EndTime); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8803_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8803_Formatter.cs new file mode 100644 index 0000000..990477d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8803_Formatter.cs @@ -0,0 +1,33 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8803_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8803 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8803 jT808_0X8803 = new JT808_0x8803(); + jT808_0X8803.MultimediaType = reader.ReadByte(); + jT808_0X8803.ChannelId = reader.ReadByte(); + jT808_0X8803.EventItemCoding = reader.ReadByte(); + jT808_0X8803.StartTime = reader.ReadDateTime6(); + jT808_0X8803.EndTime = reader.ReadDateTime6(); + jT808_0X8803.MultimediaDeleted = reader.ReadByte(); + return jT808_0X8803; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8803 value, IJT808Config config) + { + writer.WriteByte(value.MultimediaType); + writer.WriteByte(value.ChannelId); + writer.WriteByte(value.EventItemCoding); + writer.WriteDateTime6(value.StartTime); + writer.WriteDateTime6(value.EndTime); + writer.WriteByte(value.MultimediaDeleted); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8804_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8804_Formatter.cs new file mode 100644 index 0000000..9ccfa4d --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8804_Formatter.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8804_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8804 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8804 jT808_0X8804 = new JT808_0x8804(); + jT808_0X8804.RecordCmd = (JT808RecordCmd)reader.ReadByte(); + jT808_0X8804.RecordTime = reader.ReadUInt16(); + jT808_0X8804.RecordSave = (JT808RecordSave)reader.ReadByte(); + jT808_0X8804.AudioSampleRate = reader.ReadByte(); + return jT808_0X8804; + } + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8804 value, IJT808Config config) + { + writer.WriteByte((byte)value.RecordCmd); + writer.WriteUInt16(value.RecordTime); + writer.WriteByte((byte)value.RecordSave); + writer.WriteByte(value.AudioSampleRate); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8805_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8805_Formatter.cs new file mode 100644 index 0000000..351a58c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8805_Formatter.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8805_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8805 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8805 jT808_0X8805 = new JT808_0x8805(); + jT808_0X8805.MultimediaId = reader.ReadUInt32(); + jT808_0X8805.MultimediaDeleted = reader.ReadByte(); + return jT808_0X8805; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8805 value, IJT808Config config) + { + writer.WriteUInt32(value.MultimediaId); + writer.WriteByte(value.MultimediaDeleted); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8900_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8900_Formatter.cs new file mode 100644 index 0000000..0f26d0c --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8900_Formatter.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using JT808.Protocol.Interfaces; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8900_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8900 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8900 jT808_0X8900 = new JT808_0x8900(); + jT808_0X8900.PassthroughType = reader.ReadByte(); + jT808_0X8900.PassthroughData = reader.ReadContent().ToArray(); + return jT808_0X8900; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8900 value, IJT808Config config) + { + writer.WriteByte(value.PassthroughType); + object obj = config.GetMessagePackFormatterByType(value.JT808_0X8900_BodyBase.GetType()); + JT808MessagePackFormatterResolverExtensions.JT808DynamicSerialize(obj, ref writer, value.JT808_0X8900_BodyBase, config); + } + } +} diff --git a/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8A00_Formatter.cs b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8A00_Formatter.cs new file mode 100644 index 0000000..b1bc104 --- /dev/null +++ b/src/JT808.Protocol/Formatters/MessageBodyFormatters/JT808_0x8A00_Formatter.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Exceptions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Extensions; +using JT808.Protocol.MessageBody; +using System; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Formatters.MessageBodyFormatters +{ + public class JT808_0x8A00_Formatter : IJT808MessagePackFormatter + { + public JT808_0x8A00 Deserialize(ref JT808MessagePackReader reader, IJT808Config config) + { + JT808_0x8A00 jT808_0X8A00 = new JT808_0x8A00(); + jT808_0X8A00.E = reader.ReadUInt32(); + jT808_0X8A00.N = reader.ReadArray(128).ToArray(); + return jT808_0X8A00; + } + + public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8A00 value, IJT808Config config) + { + writer.WriteUInt32(value.E); + if (value.N.Length != 128) + { + throw new JT808Exception(Enums.JT808ErrorCode.NotEnoughLength, $"{nameof(value.N)}->128"); + } + writer.WriteArray(value.N); + } + } +} diff --git a/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs new file mode 100644 index 0000000..878fb8b --- /dev/null +++ b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs @@ -0,0 +1,50 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Internal; +using System; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + public abstract class GlobalConfigBase : IJT808Config + { + protected GlobalConfigBase() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + MsgSNDistributed = new DefaultMsgSNDistributedImpl(); + Compress = new JT808GZipCompressImpl(); + SplitPackageStrategy = new DefaultSplitPackageStrategyImpl(); + SkipCRCCode = false; + MsgIdFactory = new JT808MsgIdFactory(); + Encoding = Encoding.GetEncoding("GBK"); + FormatterFactory = new JT808FormatterFactory(); + JT808_0X0200_Custom_Factory = new JT808_0x0200_Custom_Factory(); + JT808_0X8103_Custom_Factory = new JT808_0x8103_Custom_Factory(); + TerminalPhoneNoLength = 12; + } + public abstract string ConfigId { get; } + public virtual IJT808MsgSNDistributed MsgSNDistributed { get; set; } + public virtual IJT808Compress Compress { get; set; } + public virtual IJT808SplitPackageStrategy SplitPackageStrategy { get; set; } + public virtual IJT808MsgIdFactory MsgIdFactory { get; set; } + public virtual Encoding Encoding { get; set; } + public virtual bool SkipCRCCode { get; set; } + public virtual IJT808FormatterFactory FormatterFactory { get; set; } + public virtual IJT808_0x0200_Custom_Factory JT808_0X0200_Custom_Factory { get; set; } + public virtual IJT808_0x8103_Custom_Factory JT808_0X8103_Custom_Factory { get; set; } + public virtual int TerminalPhoneNoLength { get; set; } + public virtual IJT808Config Register(params Assembly[] externalAssemblies) + { + if (externalAssemblies != null) + { + foreach (var easb in externalAssemblies) + { + FormatterFactory.Register(easb); + JT808_0X0200_Custom_Factory.Register(easb); + JT808_0X8103_Custom_Factory.Register(easb); + } + } + return this; + } + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808Compress.cs b/src/JT808.Protocol/Interfaces/IJT808Compress.cs new file mode 100644 index 0000000..235461b --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808Compress.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol.Interfaces +{ + /// + /// 压缩接口 + /// + public interface IJT808Compress + { + byte[] Compress(byte[] data); + + byte[] Decompress(byte[] compressData); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808Config.cs b/src/JT808.Protocol/Interfaces/IJT808Config.cs new file mode 100644 index 0000000..f7f690d --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808Config.cs @@ -0,0 +1,63 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + public interface IJT808Config + { + string ConfigId { get; } + /// + /// 消息流水号 + /// + IJT808MsgSNDistributed MsgSNDistributed { get; set; } + /// + /// 消息工厂 + /// + IJT808MsgIdFactory MsgIdFactory { get; set; } + /// + /// 压缩接口 + /// + IJT808Compress Compress { get; set; } + /// + /// 分包策略 + /// 注意:处理808的分包读取完流需要先进行转义在进行分包 + /// + IJT808SplitPackageStrategy SplitPackageStrategy { get; set; } + /// + /// 序列化器工厂 + /// + IJT808FormatterFactory FormatterFactory { get; set; } + /// + /// 自定义附加信息工厂 + /// + IJT808_0x0200_Custom_Factory JT808_0X0200_Custom_Factory { get; set; } + /// + ///自定义设置终端参数工厂 + /// + IJT808_0x8103_Custom_Factory JT808_0X8103_Custom_Factory { get; set; } + /// + /// 统一编码 + /// + Encoding Encoding { get; set; } + /// + /// 跳过校验码 + /// 测试的时候需要手动修改值,避免验证 + /// 默认:false + /// + bool SkipCRCCode { get; set; } + /// + /// 设备终端号(默认12位) + /// + int TerminalPhoneNoLength { get; set; } + /// + /// 全局注册外部程序集 + /// + /// + /// + IJT808Config Register(params Assembly[] externalAssemblies); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808ExternalRegister.cs b/src/JT808.Protocol/Interfaces/IJT808ExternalRegister.cs new file mode 100644 index 0000000..52242c5 --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808ExternalRegister.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + public interface IJT808ExternalRegister + { + void Register(Assembly externalAssembly); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808MsgIdFactory.cs b/src/JT808.Protocol/Interfaces/IJT808MsgIdFactory.cs new file mode 100644 index 0000000..89a0cab --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808MsgIdFactory.cs @@ -0,0 +1,17 @@ +using System; + +namespace JT808.Protocol.Interfaces +{ + public interface IJT808MsgIdFactory + { + Type GetBodiesImplTypeByMsgId(ushort msgId, string terminalPhoneNo); + IJT808MsgIdFactory SetMap(ushort msgId, string terminalPhoneNo) + where TJT808Bodies : JT808Bodies; + IJT808MsgIdFactory SetMap(ushort msgId, string terminalPhoneNo, Type bodiesImplType); + IJT808MsgIdFactory ReplaceMap(ushort msgId, string terminalPhoneNo) + where TJT808Bodies : JT808Bodies; + IJT808MsgIdFactory CustomSetMap(ushort msgId, string terminalPhoneNo) + where TJT808Bodies : JT808Bodies; + IJT808MsgIdFactory CustomSetMap(ushort msgId, string terminalPhoneNo, Type bodiesImplType); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808MsgSNDistributed.cs b/src/JT808.Protocol/Interfaces/IJT808MsgSNDistributed.cs new file mode 100644 index 0000000..3317429 --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808MsgSNDistributed.cs @@ -0,0 +1,7 @@ +namespace JT808.Protocol.Interfaces +{ + public interface IJT808MsgSNDistributed + { + ushort Increment(); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808SplitPackageStrategy.cs b/src/JT808.Protocol/Interfaces/IJT808SplitPackageStrategy.cs new file mode 100644 index 0000000..1cba18a --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808SplitPackageStrategy.cs @@ -0,0 +1,15 @@ +using JT808.Protocol.Metadata; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.Interfaces +{ + /// + /// 分包策略 + /// 注意:处理808的分包读取完流需要先进行转义在进行分包 + /// + public interface IJT808SplitPackageStrategy + { + IEnumerable Processor(ReadOnlySpan bigData); + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808_0x0200_Custom_Factory.cs b/src/JT808.Protocol/Interfaces/IJT808_0x0200_Custom_Factory.cs new file mode 100644 index 0000000..17aee5f --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808_0x0200_Custom_Factory.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + public interface IJT808_0x0200_Custom_Factory: IJT808ExternalRegister + { + HashSet AttachIds { get; } + } +} diff --git a/src/JT808.Protocol/Interfaces/IJT808_0x8103_Custom_Factory.cs b/src/JT808.Protocol/Interfaces/IJT808_0x8103_Custom_Factory.cs new file mode 100644 index 0000000..b716b44 --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IJT808_0x8103_Custom_Factory.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + public interface IJT808_0x8103_Custom_Factory : IJT808ExternalRegister + { + IDictionary ParamMethods { get;} + } +} diff --git a/src/JT808.Protocol/Internal/DefaultGlobalConfig.cs b/src/JT808.Protocol/Internal/DefaultGlobalConfig.cs new file mode 100644 index 0000000..b788771 --- /dev/null +++ b/src/JT808.Protocol/Internal/DefaultGlobalConfig.cs @@ -0,0 +1,14 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using System; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Internal +{ + class DefaultGlobalConfig : GlobalConfigBase + { + public override string ConfigId => "Default"; + } +} diff --git a/src/JT808.Protocol/Internal/DefaultMsgSNDistributedImpl.cs b/src/JT808.Protocol/Internal/DefaultMsgSNDistributedImpl.cs new file mode 100644 index 0000000..5bfcfbb --- /dev/null +++ b/src/JT808.Protocol/Internal/DefaultMsgSNDistributedImpl.cs @@ -0,0 +1,15 @@ +using System.Threading; +using JT808.Protocol.Interfaces; + +namespace JT808.Protocol.Internal +{ + internal class DefaultMsgSNDistributedImpl : IJT808MsgSNDistributed + { + int _counter = 0; + + public ushort Increment() + { + return (ushort)Interlocked.Increment(ref _counter); + } + } +} diff --git a/src/JT808.Protocol/Internal/DefaultSplitPackageStrategyImpl.cs b/src/JT808.Protocol/Internal/DefaultSplitPackageStrategyImpl.cs new file mode 100644 index 0000000..6952fcf --- /dev/null +++ b/src/JT808.Protocol/Internal/DefaultSplitPackageStrategyImpl.cs @@ -0,0 +1,44 @@ +using JT808.Protocol.Metadata; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("JT808.Protocol.Benchmark")] +[assembly: InternalsVisibleTo("JT808.Protocol.Test")] +namespace JT808.Protocol.Internal +{ + internal class DefaultSplitPackageStrategyImpl : IJT808SplitPackageStrategy + { + private const int N = 256 * 3; + + public IEnumerable Processor(ReadOnlySpan bigData) + { + List jT808SplitPackagePropertys = new List(); + var quotient = bigData.Length / N; + var remainder = bigData.Length % N; + if (remainder != 0) + { + quotient = quotient + 1; + } + for (int i = 1; i <= quotient; i++) + { + JT808SplitPackageProperty jT808SplitPackageProperty = new JT808SplitPackageProperty + { + PackgeIndex = i, + PackgeCount = quotient + }; + if (i == quotient) + { + jT808SplitPackageProperty.Data = bigData.Slice((i - 1) * N).ToArray(); + } + else + { + jT808SplitPackageProperty.Data = bigData.Slice((i - 1) * N, N).ToArray(); + } + jT808SplitPackagePropertys.Add(jT808SplitPackageProperty); + } + return jT808SplitPackagePropertys; + } + } +} diff --git a/src/JT808.Protocol/Internal/JT808FormatterFactory.cs b/src/JT808.Protocol/Internal/JT808FormatterFactory.cs new file mode 100644 index 0000000..ed7b2ed --- /dev/null +++ b/src/JT808.Protocol/Internal/JT808FormatterFactory.cs @@ -0,0 +1,68 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Exceptions; +using JT808.Protocol.Formatters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Internal +{ + class JT808FormatterFactory : IJT808FormatterFactory + { + public Dictionary FormatterDict { get; } + + public JT808FormatterFactory() + { + FormatterDict = new Dictionary(); + Init(Assembly.GetExecutingAssembly()); + } + + private void Init(Assembly assembly) + { + foreach(var type in assembly.GetTypes().Where(w=>w.GetInterfaces().Contains(typeof(IJT808Formatter)))) + { + var implTypes = type.GetInterfaces(); + if(implTypes!=null && implTypes .Length>1) + { + var firstType = implTypes.FirstOrDefault(); + var genericImplType = firstType.GetGenericArguments().FirstOrDefault(); + if (genericImplType == null) + { + throw new JT808Exception(JT808ErrorCode.GetFormatterAttributeError, genericImplType.FullName); + } + var attr = genericImplType.GetCustomAttribute(); + if (attr != null) + { + if (!FormatterDict.ContainsKey(genericImplType.GUID)) + { + FormatterDict.Add(genericImplType.GUID, Activator.CreateInstance(attr.FormatterType)); + } + } + } + } + } + + public IJT808FormatterFactory SetMap() where TJT808Bodies : JT808Bodies + { + Type bodiesType = typeof(TJT808Bodies); + var attr = bodiesType.GetTypeInfo().GetCustomAttribute(); + if (attr == null) + { + throw new JT808Exception(JT808ErrorCode.GetFormatterAttributeError, bodiesType.FullName); + } + if (!FormatterDict.ContainsKey(bodiesType.GUID)) + { + FormatterDict.Add(bodiesType.GUID, Activator.CreateInstance(attr.FormatterType)); + } + return this; + } + + public void Register(Assembly externalAssembly) + { + Init(externalAssembly); + } + } +} diff --git a/src/JT808.Protocol/Internal/JT808GZipCompressImpl.cs b/src/JT808.Protocol/Internal/JT808GZipCompressImpl.cs new file mode 100644 index 0000000..64a3408 --- /dev/null +++ b/src/JT808.Protocol/Internal/JT808GZipCompressImpl.cs @@ -0,0 +1,31 @@ +using System.IO; +using System.IO.Compression; +using JT808.Protocol.Interfaces; + +namespace JT808.Protocol.Internal +{ + internal class JT808GZipCompressImpl : IJT808Compress + { + public byte[] Compress(byte[] data) + { + using (var outStream = new MemoryStream()) + { + using (var gZipStream = new GZipStream(outStream, CompressionMode.Compress)) + using (var mStream = new MemoryStream(data)) + mStream.CopyTo(gZipStream); + return outStream.ToArray(); + } + } + + public byte[] Decompress(byte[] compressData) + { + using (var inStream = new MemoryStream(compressData)) + using (var gZipStream = new GZipStream(inStream, CompressionMode.Decompress)) + using (var outStream = new MemoryStream()) + { + gZipStream.CopyTo(outStream); + return outStream.ToArray(); + } + } + } +} diff --git a/src/JT808.Protocol/Internal/JT808MsgIdFactory.cs b/src/JT808.Protocol/Internal/JT808MsgIdFactory.cs new file mode 100644 index 0000000..3dfd454 --- /dev/null +++ b/src/JT808.Protocol/Internal/JT808MsgIdFactory.cs @@ -0,0 +1,133 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.Internal +{ + internal class JT808MsgIdFactory: IJT808MsgIdFactory + { + private Dictionary map; + + private Dictionary> customMap; + + internal JT808MsgIdFactory() + { + map = new Dictionary(); + customMap = new Dictionary>(StringComparer.OrdinalIgnoreCase); + InitMap(); + } + + private void InitMap() + { + foreach (var item in Enum.GetNames(typeof(JT808MsgId))) + { + JT808MsgId msgId = item.ToEnum(); + if (!map.ContainsKey((ushort)msgId)) + { + JT808BodiesTypeAttribute jT808BodiesTypeAttribute = msgId.GetAttribute(); + if (jT808BodiesTypeAttribute != null) + { + map.Add((ushort)msgId, jT808BodiesTypeAttribute.JT808BodiesType); + } + } + } + } + + public Type GetBodiesImplTypeByMsgId(ushort msgId, string terminalPhoneNo) + { + //判断有无自定义消息Id类型 + if (customMap.TryGetValue(terminalPhoneNo, out var dict)) + { + if (dict != null) + { + return dict.TryGetValue(msgId, out Type bodiesImptType)? bodiesImptType:null; + } + } + return map.TryGetValue(msgId, out Type type) ? type : null; + } + + public IJT808MsgIdFactory SetMap(ushort msgId, string terminalPhoneNo) + where TJT808Bodies : JT808Bodies + { + if (!map.ContainsKey(msgId)) + { + map.Add(msgId, typeof(TJT808Bodies)); + } + return this; + } + + public IJT808MsgIdFactory SetMap(ushort msgId, string terminalPhoneNo, Type bodiesImplType) + { + if (!map.ContainsKey(msgId)) + { + map.Add(msgId, bodiesImplType); + } + return this; + } + + public IJT808MsgIdFactory ReplaceMap(ushort msgId, string terminalPhoneNo) where TJT808Bodies : JT808Bodies + { + if (!map.ContainsKey(msgId)) + { + map.Add(msgId, typeof(TJT808Bodies)); + } + else + { + map[msgId] = typeof(TJT808Bodies); + } + return this; + } + + public IJT808MsgIdFactory CustomSetMap(ushort msgId, string terminalPhoneNo) where TJT808Bodies : JT808Bodies + { + if (!string.IsNullOrEmpty(terminalPhoneNo)) + { + if (!customMap.TryGetValue(terminalPhoneNo, out var dict)) + { + if (dict == null) + { + Dictionary tmp = new Dictionary(); + tmp.Add(msgId, typeof(TJT808Bodies)); + customMap.Add(terminalPhoneNo, tmp); + } + else + { + if (!dict.ContainsKey(msgId)) + { + dict.Add(msgId, typeof(TJT808Bodies)); + } + } + } + } + return this; + } + + public IJT808MsgIdFactory CustomSetMap(ushort msgId, string terminalPhoneNo, Type bodiesImplType) + { + if (!string.IsNullOrEmpty(terminalPhoneNo)) + { + if (!customMap.TryGetValue(terminalPhoneNo, out var dict)) + { + if (dict == null) + { + Dictionary tmp = new Dictionary(); + tmp.Add(msgId, bodiesImplType); + customMap.Add(terminalPhoneNo, tmp); + return this; + } + else + { + if (!dict.ContainsKey(msgId)) + { + dict.Add(msgId, bodiesImplType); + } + } + } + } + return this; + } + } +} diff --git a/src/JT808.Protocol/Internal/JT808_0x0200_Custom_Factory.cs b/src/JT808.Protocol/Internal/JT808_0x0200_Custom_Factory.cs new file mode 100644 index 0000000..4ff7f31 --- /dev/null +++ b/src/JT808.Protocol/Internal/JT808_0x0200_Custom_Factory.cs @@ -0,0 +1,33 @@ +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Internal +{ + class JT808_0x0200_Custom_Factory : IJT808_0x0200_Custom_Factory + { + public HashSet AttachIds { get; } + + public JT808_0x0200_Custom_Factory() + { + AttachIds = new HashSet(); + } + + public void Register(Assembly externalAssembly) + { + var types = externalAssembly.GetTypes().Where(w => w.BaseType == typeof(JT808_0x0200_CustomBodyBase)).ToList(); + foreach(var type in types) + { + var attachid = (byte)type.GetProperty(nameof(JT808_0x0200_CustomBodyBase.AttachInfoId)).GetValue(Activator.CreateInstance(type)); + if (!AttachIds.Contains(attachid)) + { + AttachIds.Add(attachid); + } + } + } + } +} diff --git a/src/JT808.Protocol/Internal/JT808_0x8103_Custom_Factory.cs b/src/JT808.Protocol/Internal/JT808_0x8103_Custom_Factory.cs new file mode 100644 index 0000000..94be0d1 --- /dev/null +++ b/src/JT808.Protocol/Internal/JT808_0x8103_Custom_Factory.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.MessageBody; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace JT808.Protocol.Interfaces +{ + class JT808_0x8103_Custom_Factory : IJT808_0x8103_Custom_Factory + { + public JT808_0x8103_Custom_Factory() + { + ParamMethods = new Dictionary(); + } + + public IDictionary ParamMethods { get;} + + public void Register(Assembly externalAssembly) + { + var types = externalAssembly.GetTypes().Where(w => w.BaseType == typeof(JT808_0x8103_CustomBodyBase)).ToList(); + foreach (var type in types) + { + var paramId = (uint)type.GetProperty(nameof(JT808_0x8103_CustomBodyBase.ParamId)).GetValue(Activator.CreateInstance(type)); + if (!ParamMethods.ContainsKey(paramId)) + { + ParamMethods.Add(paramId, type); + } + } + } + } +} diff --git a/src/JT808.Protocol/JT808.Protocol.csproj b/src/JT808.Protocol/JT808.Protocol.csproj new file mode 100644 index 0000000..dc382fb --- /dev/null +++ b/src/JT808.Protocol/JT808.Protocol.csproj @@ -0,0 +1,70 @@ + + + netstandard2.0 + 8.0 + Copyright 2018. + SmallChi + JT808 + JT808 + JT808协议、GB808协议、道路运输车辆卫星定位系统-北斗兼容车载终端通讯协议 + JT808协议、GB808协议、道路运输车辆卫星定位系统-北斗兼容车载终端通讯协议 + false + https://github.com/SmallChi/JT808 + https://github.com/SmallChi/JT808 + https://github.com/SmallChi/JT808/blob/master/LICENSE + https://github.com/SmallChi/JT808/blob/master/LICENSE + true + 2.0.0 + + + bin\Release\netstandard2.0\JT808.Protocol.xml + true + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextTemplatingFileGenerator + JT808PackageExtensionsTemplate.cs + + + + + + + + + + True + True + JT808PackageExtensionsTemplate.tt + + + + diff --git a/src/JT808.Protocol/JT808ArrayPool.cs b/src/JT808.Protocol/JT808ArrayPool.cs new file mode 100644 index 0000000..076e606 --- /dev/null +++ b/src/JT808.Protocol/JT808ArrayPool.cs @@ -0,0 +1,24 @@ +using System.Buffers; + +namespace JT808.Protocol +{ + internal static class JT808ArrayPool + { + private readonly static ArrayPool ArrayPool; + + static JT808ArrayPool() + { + ArrayPool = ArrayPool.Create(); + } + + public static byte[] Rent(int minimumLength) + { + return ArrayPool.Rent(minimumLength); + } + + public static void Return(byte[] array, bool clearArray = false) + { + ArrayPool.Return(array, clearArray); + } + } +} diff --git a/src/JT808.Protocol/JT808Bodies.cs b/src/JT808.Protocol/JT808Bodies.cs new file mode 100644 index 0000000..612020b --- /dev/null +++ b/src/JT808.Protocol/JT808Bodies.cs @@ -0,0 +1,12 @@ +namespace JT808.Protocol +{ + public abstract class JT808Bodies + { + /// + /// 跳过数据体序列化 + /// 默认不跳过 + /// 当数据体为空的时候,使用null作为空包感觉不适合,所以就算使用空包也需要new一下来表达意思。 + /// + public virtual bool SkipSerialization { get; set; } = false; + } +} diff --git a/src/JT808.Protocol/JT808Constants.cs b/src/JT808.Protocol/JT808Constants.cs new file mode 100644 index 0000000..a086a53 --- /dev/null +++ b/src/JT808.Protocol/JT808Constants.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Protocol +{ + public static class JT808Constants + { + static JT808Constants() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Encoding = Encoding.GetEncoding("GBK"); + } + /// + /// 日期限制于2000年 + /// + public const int DateLimitYear = 2000; + public static readonly DateTime UTCBaseTime = new DateTime(1970, 1, 1); + public static Encoding Encoding { get;} + } +} diff --git a/src/JT808.Protocol/JT808GlobalConfig.cs b/src/JT808.Protocol/JT808GlobalConfig.cs new file mode 100644 index 0000000..bd3e6e9 --- /dev/null +++ b/src/JT808.Protocol/JT808GlobalConfig.cs @@ -0,0 +1,140 @@ +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; + +[assembly: InternalsVisibleTo("JT808.Protocol.Benchmark")] +[assembly: InternalsVisibleTo("JT808.Protocol.Test")] +namespace JT808.Protocol +{ + public class JT808GlobalConfig + { + public static readonly JT808GlobalConfig Instance = new JT808GlobalConfig(); + + public JT808GlobalConfig() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + MsgSNDistributed = new DefaultMsgSNDistributedImpl(); + Compress = new JT808GZipCompressImpl(); + SplitPackageStrategy = new DefaultSplitPackageStrategyImpl(); + SkipCRCCode = false; + MsgIdFactory = new JT808MsgIdFactory(); + Encoding = Encoding.GetEncoding("GBK"); + FormatterFactory = new JT808FormatterFactory(); + JT808_0X0200_Custom_Factory = new JT808_0x0200_Custom_Factory(); + JT808_0X8103_Custom_Factory = new JT808_0x8103_Custom_Factory(); + } + + public IJT808MsgSNDistributed MsgSNDistributed { get; private set; } + + public IJT808Compress Compress { get; private set; } + + public IJT808SplitPackageStrategy SplitPackageStrategy { get; private set; } + + public IJT808MsgIdFactory MsgIdFactory { get; private set; } + + public Encoding Encoding; + + /// + /// 序列化器工厂 + /// + internal IJT808FormatterFactory FormatterFactory { get; } + + /// + /// 自定义附加信息工厂 + /// + internal IJT808_0x0200_Custom_Factory JT808_0X0200_Custom_Factory { get; } + + /// + ///自定义设置终端参数工厂 + /// + internal IJT808_0x8103_Custom_Factory JT808_0X8103_Custom_Factory { get; } + + /// + /// 跳过校验码 + /// 测试的时候需要手动修改值,避免验证 + /// 默认:false + /// + public bool SkipCRCCode { get; private set; } + + + /// + /// 设置消息序列号 + /// + /// + /// + public JT808GlobalConfig SetMsgSNDistributed(IJT808MsgSNDistributed msgSNDistributed) + { + Instance.MsgSNDistributed = msgSNDistributed; + return this; + } + + /// + /// 设置压缩算法 + /// 默认GZip + /// + /// + /// + public JT808GlobalConfig SetCompress(IJT808Compress compressImpl) + { + Instance.Compress = compressImpl; + return this; + } + /// + /// 设置分包算法 + /// 默认3*256 + /// + /// + /// + public JT808GlobalConfig SetSplitPackageStrategy(IJT808SplitPackageStrategy splitPackageStrategy) + { + Instance.SplitPackageStrategy = splitPackageStrategy; + return this; + } + /// + /// 设置跳过校验码 + /// 场景:测试的时候,可能需要手动改数据,所以测试的时候有用 + /// + /// + /// + public JT808GlobalConfig SetSkipCRCCode(bool skipCRCCode) + { + Instance.SkipCRCCode = skipCRCCode; + return this; + } + /// + /// 设置消息工厂的实现 + /// + /// + /// + public JT808GlobalConfig SetMsgIdFactory(IJT808MsgIdFactory msgIdFactory) + { + if (msgIdFactory != null) + { + Instance.MsgIdFactory = msgIdFactory; + } + return this; + } + /// + /// 全局注册外部程序集 + /// + /// + /// + public JT808GlobalConfig Register(params Assembly[] externalAssemblies) + { + if (externalAssemblies != null) + { + foreach(var easb in externalAssemblies) + { + FormatterFactory.Register(easb); + JT808_0X0200_Custom_Factory.Register(easb); + JT808_0X8103_Custom_Factory.Register(easb); + } + } + return this; + } + } +} diff --git a/src/JT808.Protocol/JT808Header.cs b/src/JT808.Protocol/JT808Header.cs new file mode 100644 index 0000000..673ddc7 --- /dev/null +++ b/src/JT808.Protocol/JT808Header.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters; + +namespace JT808.Protocol +{ + /// + /// 头部 + /// + [JT808Formatter(typeof(JT808HeaderFormatter))] + public class JT808Header + { + /// + /// 消息ID + /// + /// + public ushort MsgId { get; set; } + public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; } = new JT808HeaderMessageBodyProperty(); + /// + /// 终端手机号 + /// 根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充 + /// + public string TerminalPhoneNo { get; set; } + /// + /// 消息流水号 + /// 发送计数器 + /// 占用四个字节,为发送信息的序列号,用于接收方检测是否有信息的丢失,上级平台和下级平台接自己发送数据包的个数计数,互不影响。 + /// 程序开始运行时等于零,发送第一帧数据时开始计数,到最大数后自动归零 + /// + public ushort MsgNum { get; set; } + } +} diff --git a/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs b/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs new file mode 100644 index 0000000..41eb3e2 --- /dev/null +++ b/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs @@ -0,0 +1,111 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using System; + +namespace JT808.Protocol +{ + [JT808Formatter(typeof(JT808HeaderMessageBodyPropertyFormatter))] + public class JT808HeaderMessageBodyProperty + { + private const string encrypt_none = "000"; + private const string encrypt_rsa = "001"; + private const char char_zero = '0'; + private const char char_one = '1'; + public JT808HeaderMessageBodyProperty() + { + IsPackge = false; + Encrypt = JT808EncryptMethod.None; + PackgeCount = 0; + PackageIndex = 0; + } + /// + /// 是否分包 + /// true-1 表示消息体为长消息,进行分包发送处理 + /// false-0 消息头中无消息包封装项字段。 + /// + public bool IsPackge { get; set; } + /// + /// 加密标识,0为不加密 + /// 当此三位都为 0,表示消息体不加密; + /// 当第 10 位为 1,表示消息体经过 RSA 算法加密; + /// todo:没有涉及到加密先不考虑 + /// + public JT808EncryptMethod Encrypt { get; set; } + /// + /// 消息体长度 + /// + public int DataLength { get; set; } + /// + /// 消息总包数 + /// + public ushort PackgeCount { get; set; } + /// + /// 报序号 从1开始 + /// + public ushort PackageIndex { get; set; } + public ushort Wrap(IJT808Config jT808Config) + { + // 2.消息体属性 + Span msgMethod = new char[16]; + // 2.1.保留 + msgMethod[0] = char_zero; + msgMethod[1] = char_zero; + // 2.2.是否分包 + msgMethod[2] = IsPackge ? char_one : char_zero; + // 2.3.数据加密方式 + switch (Encrypt) + { + case JT808EncryptMethod.None: + msgMethod[3] = char_zero; + msgMethod[4] = char_zero; + msgMethod[5] = char_zero; + break; + case JT808EncryptMethod.RSA: + msgMethod[3] = char_zero; + msgMethod[4] = char_zero; + msgMethod[5] = char_one; + break; + default: + msgMethod[3] = char_zero; + msgMethod[4] = char_zero; + msgMethod[5] = char_zero; + break; + } + // 2.4.数据长度 + if (DataLength <= 0) + { + // 判断有无数据体长度 + DataLength = 0; + } + ReadOnlySpan dataLen = Convert.ToString(DataLength, 2).PadLeft(10, char_zero).AsSpan(); + for (int i = 1; i <= 10; i++) + { + msgMethod[5 + i] = dataLen[i - 1]; + } + return Convert.ToUInt16(msgMethod.ToString(), 2); + } + public void Unwrap(ushort value, IJT808Config jT808Config) + { + ReadOnlySpan msgMethod = Convert.ToString(value, 2).PadLeft(16, '0').AsSpan(); + DataLength = Convert.ToInt32(msgMethod.Slice(6, 10).ToString(), 2); + // 2.2. 数据加密方式 + switch (msgMethod.Slice(3, 3).ToString()) + { + case encrypt_none: + Encrypt = JT808EncryptMethod.None; + break; + case encrypt_rsa: + Encrypt = JT808EncryptMethod.RSA; + break; + default: + Encrypt = JT808EncryptMethod.None; + break; + } + IsPackge = msgMethod[2] != char_zero; + PackgeCount = 0; + PackageIndex = 0; + } + } +} diff --git a/src/JT808.Protocol/JT808HeaderPackage.cs b/src/JT808.Protocol/JT808HeaderPackage.cs new file mode 100644 index 0000000..e648389 --- /dev/null +++ b/src/JT808.Protocol/JT808HeaderPackage.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters; + +namespace JT808.Protocol +{ + /// + /// JT808头部数据包 + /// + [JT808Formatter(typeof(JT808HeaderPackageFormatter))] + public class JT808HeaderPackage + { + /// + /// 起始符 + /// + public byte Begin { get; set; } + /// + /// 头数据 + /// + public JT808Header Header { get; set; } + /// + /// 数据体 + /// + public byte[] Bodies { get; set; } + /// + /// 校验码 + /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 + /// + public byte CheckCode { get; set; } + /// + /// 终止符 + /// + public byte End { get; set; } + } +} diff --git a/src/JT808.Protocol/JT808Package.cs b/src/JT808.Protocol/JT808Package.cs new file mode 100644 index 0000000..8951888 --- /dev/null +++ b/src/JT808.Protocol/JT808Package.cs @@ -0,0 +1,50 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters; + +namespace JT808.Protocol +{ + /// + /// JT808数据包 + /// + [JT808Formatter(typeof(JT808PackageFormatter))] + public class JT808Package + { + /// + /// 起始符 + /// + public const byte BeginFlag = 0x7e; + /// + /// 终止符 + /// + public const byte EndFlag = 0x7e; + /// + /// 头部固定长度 + /// + public const int FixedHeaderLength = 12; + /// + /// 起始符 + /// + public byte Begin { get; set; } = BeginFlag; + + /// + /// 终止符 + /// + public byte End { get; set; } = EndFlag; + + /// + /// 校验码 + /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。 + /// + public byte CheckCode { get; set; } + + /// + /// 头数据 + /// + public JT808Header Header { get; set; } + + /// + /// 数据体 + /// + public JT808Bodies Bodies { get; set; } + } +} diff --git a/src/JT808.Protocol/JT808Serializer.cs b/src/JT808.Protocol/JT808Serializer.cs new file mode 100644 index 0000000..b37b324 --- /dev/null +++ b/src/JT808.Protocol/JT808Serializer.cs @@ -0,0 +1,131 @@ +using JT808.Protocol.Extensions; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessagePack; +using System; + +namespace JT808.Protocol +{ + public class JT808Serializer + { + public JT808Serializer(IJT808Config jT808Config) + { + this.jT808Config = jT808Config; + } + + public JT808Serializer():this(new DefaultGlobalConfig()) + { + + } + + public string SerializerId => jT808Config.ConfigId; + + private readonly IJT808Config jT808Config; + + public byte[] Serialize(JT808Package jT808Package, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer); + JT808PackageFormatter.Instance.Serialize(ref jT808MessagePackWriter, jT808Package, jT808Config); + return jT808MessagePackWriter.FlushAndGetEncodingArray(); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + + public JT808Package Deserialize(ReadOnlySpan bytes, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(buffer); + return JT808PackageFormatter.Instance.Deserialize(ref jT808MessagePackReader, jT808Config); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + + public byte [] Serialize(T obj, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + var formatter = jT808Config.GetMessagePackFormatter(); + JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer); + formatter.Serialize(ref jT808MessagePackWriter, obj, jT808Config); + return jT808MessagePackWriter.FlushAndGetEncodingArray(); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + + public T Deserialize(ReadOnlySpan bytes, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + if(CheckPackageType(typeof(T))) + jT808MessagePackReader.Decode(buffer); + var formatter = jT808Config.GetMessagePackFormatter(); + return formatter.Deserialize(ref jT808MessagePackReader, jT808Config); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + + private static bool CheckPackageType(Type type) + { + return type == typeof(JT808Package) || type == typeof(JT808HeaderPackage); + } + + /// + /// 用于负载或者分布式的时候,在网关只需要解到头部。 + /// 根据头部的消息Id进行分发处理,可以防止小部分性能损耗。 + /// + /// + /// + public JT808HeaderPackage HeaderDeserialize(ReadOnlySpan bytes, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + jT808MessagePackReader.Decode(buffer); + return JT808HeaderPackageFormatter.Instance.Deserialize(ref jT808MessagePackReader,jT808Config); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + public dynamic Deserialize(ReadOnlySpan bytes, Type type, int minBufferSize = 4096) + { + byte[] buffer = JT808ArrayPool.Rent(minBufferSize); + try + { + var formatter = jT808Config.GetMessagePackFormatterByType(type); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + if (CheckPackageType(type)) + jT808MessagePackReader.Decode(buffer); + return JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize(formatter,ref jT808MessagePackReader, jT808Config); + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + } +} diff --git a/src/JT808.Protocol/JT808SplitPackageBodies.cs b/src/JT808.Protocol/JT808SplitPackageBodies.cs new file mode 100644 index 0000000..f72236f --- /dev/null +++ b/src/JT808.Protocol/JT808SplitPackageBodies.cs @@ -0,0 +1,14 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters; + +namespace JT808.Protocol +{ + /// + /// 统一分包数据体 + /// + [JT808Formatter(typeof(JT808SplitPackageBodiesFormatter))] + public class JT808SplitPackageBodies : JT808Bodies + { + public byte[] Data { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0001.cs b/src/JT808.Protocol/MessageBody/JT808_0x0001.cs new file mode 100644 index 0000000..66c79e2 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0001.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Attributes; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端通用应答 + /// + [JT808Formatter(typeof(JT808_0x0001_Formatter))] + public class JT808_0x0001 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的平台消息的流水号 + /// + public ushort MsgNum { get; set; } + /// + /// 应答 ID + /// 对应的平台消息的 ID + /// + /// + public ushort MsgId { get; set; } + /// + /// 结果 + /// 0:成功/确认;1:失败;2:消息有误;3:不支持 + /// + public JT808TerminalResult JT808TerminalResult { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0002.cs b/src/JT808.Protocol/MessageBody/JT808_0x0002.cs new file mode 100644 index 0000000..02edcbc --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0002.cs @@ -0,0 +1,10 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端心跳 + /// + public class JT808_0x0002 : JT808Bodies + { + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0003.cs b/src/JT808.Protocol/MessageBody/JT808_0x0003.cs new file mode 100644 index 0000000..fd5d91b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0003.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端注销请求 + /// + public class JT808_0x0003 : JT808Bodies + { + /// + /// 跳过数据体序列化 + /// + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0100.cs b/src/JT808.Protocol/MessageBody/JT808_0x0100.cs new file mode 100644 index 0000000..0d727d3 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0100.cs @@ -0,0 +1,62 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端注册 + /// + [JT808Formatter(typeof(JT808_0x0100_Formatter))] + public class JT808_0x0100 : JT808Bodies + { + /// + /// 省域 ID + /// 标示终端安装车辆所在的省域,0 保留,由平台取默 + /// 认值。省域 ID 采用 GB/T 2260 中规定的行政区划代 + /// 码六位中前两位 + /// + public ushort AreaID { get; set; } + + /// + /// 市县域 ID + /// 标示终端安装车辆所在的市域和县域,0 保留,由平 + /// 台取默认值。市县域 ID 采用 GB/T 2260 中规定的行 + /// 政区划代码六位中后四位。 + /// + public ushort CityOrCountyId { get; set; } + + /// + /// 制造商 ID + /// 5 个字节,终端制造商编码 + /// + public string MakerId { get; set; } + + /// + /// 终端型号 + /// 20 个字节,此终端型号由制造商自行定义,位数不 + /// 足时,后补“0X00”。 + /// + public string TerminalModel { get; set; } + + /// + /// 终端 ID + /// 7 个字节,由大写字母和数字组成,此终端 ID 由制 + /// 造商自行定义,位数不足时,后补“0X00”。 + /// + public string TerminalId { get; set; } + + /// + /// 车牌颜色 + /// 车牌颜色,按照 JT/T415-2006 的 5.4.12。 + /// 未上牌时,取值为 0。 + /// + public byte PlateColor { get; set; } + + /// + /// 车辆标识 + /// 车牌颜色为 0 时,表示车辆 VIN; + /// 否则,表示公安交通管理部门颁发的机动车号牌。 + /// + public string PlateNo { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0102.cs b/src/JT808.Protocol/MessageBody/JT808_0x0102.cs new file mode 100644 index 0000000..31f7138 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0102.cs @@ -0,0 +1,17 @@ +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Attributes; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端鉴权 + /// + [JT808Formatter(typeof(JT808_0x0102_Formatter))] + public class JT808_0x0102 : JT808Bodies + { + /// + /// 鉴权码 + /// + public string Code { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0104.cs b/src/JT808.Protocol/MessageBody/JT808_0x0104.cs new file mode 100644 index 0000000..59ac6b3 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0104.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 查询终端参数应答 + /// + [JT808Formatter(typeof(JT808_0x0104_Formatter))] + public class JT808_0x0104 : JT808Bodies + { + /// + /// 应答流水号 + /// 查询指定终端参数的流水号 + /// + public ushort MsgNum { get; set; } + /// + /// 应答参数个数 + /// + public byte AnswerParamsCount { get; set; } + /// + /// 参数列表 + /// + public IList ParamList { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0107.cs b/src/JT808.Protocol/MessageBody/JT808_0x0107.cs new file mode 100644 index 0000000..4930fac --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0107.cs @@ -0,0 +1,80 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 查询终端属性应答 + /// + [JT808Formatter(typeof(JT808_0x0107_Formatter))] + public class JT808_0x0107 : JT808Bodies + { + /// + /// 终端类型 + /// bit0,0:不适用客运车辆,1:适用客运车辆; + /// bit1,0:不适用危险品车辆,1:适用危险品车辆; + /// bit2,0:不适用普通货运车辆,1:适用普通货运车辆; + /// bit3,0:不适用出租车辆,1:适用出租车辆; + /// bit6,0:不支持硬盘录像,1:支持硬盘录像; + /// bit7,0:一体机,1:分体机 + /// + public ushort TerminalType { get; set; } + /// + /// 制造商 ID + /// 5 个字节,终端制造商编码 + /// + public string MakerId { get; set; } + /// + /// 终端型号 + /// BYTE[20] + /// 20 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。 + /// + public string TerminalModel { get; set; } + /// + /// 终端ID + /// BYTE[7] + /// 7 个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00” + /// + public string TerminalId { get; set; } + /// + /// 终端 SIM 卡 ICCID + /// BCD[10] + /// + public string Terminal_SIM_ICCID { get; set; } + /// + /// 终端硬件版本号长度 + /// + public byte Terminal_Hardware_Version_Length { get; set; } + /// + /// 终端硬件版本号 + /// + public string Terminal_Hardware_Version_Num { get; set; } + /// + /// 终端固件版本号长度 + /// + public byte Terminal_Firmware_Version_Length { get; set; } + /// + /// 终端固件版本号 + /// + public string Terminal_Firmware_Version_Num { get; set; } + /// + /// GNSS 模块属性 + /// bit0,0:不支持 GPS 定位, 1:支持 GPS 定位; + /// bit1,0:不支持北斗定位, 1:支持北斗定位; + /// bit2,0:不支持 GLONASS 定位, 1:支持 GLONASS 定位; + /// bit3,0:不支持 Galileo 定位, 1:支持 Galileo 定位 + /// + public byte GNSSModule { get; set; } + /// + /// 通信模块属性 + /// bit0,0:不支持GPRS通信, 1:支持GPRS通信; + /// bit1,0:不支持CDMA通信, 1:支持CDMA通信; + /// bit2,0:不支持TD-SCDMA通信, 1:支持TD-SCDMA通信; + /// bit3,0:不支持WCDMA通信, 1:支持WCDMA通信; + /// bit4,0:不支持CDMA2000通信, 1:支持CDMA2000通信。 + /// bit5,0:不支持TD-LTE通信, 1:支持TD-LTE通信; + /// bit7,0:不支持其他通信方式, 1:支持其他通信方式 + /// + public byte CommunicationModule { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0108.cs b/src/JT808.Protocol/MessageBody/JT808_0x0108.cs new file mode 100644 index 0000000..8c522b6 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0108.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端升级结果通知 + /// + [JT808Formatter(typeof(JT808_0x0108_Formatter))] + public class JT808_0x0108 : JT808Bodies + { + /// + /// 升级类型 + /// 0:终端,12:道路运输证 IC 卡读卡器,52:北斗卫星定位模块 + /// + public JT808UpgradeType UpgradeType { get; set; } + + /// + /// 升级结果 + /// 0:成功,1:失败,2:取消 + /// + public JT808UpgradeResult UpgradeResult { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200.cs new file mode 100644 index 0000000..d7a4886 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200.cs @@ -0,0 +1,73 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置信息汇报 + /// + [JT808Formatter(typeof(JT808_0x0200_Formatter))] + public class JT808_0x0200 : JT808Bodies + { + /// + /// 报警标志 + /// + public uint AlarmFlag { get; set; } + /// + /// 状态位标志 + /// + public uint StatusFlag { get; set; } + /// + /// 纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public int Lat { get; set; } + /// + /// 经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public int Lng { get; set; } + /// + /// 高程 + /// 海拔高度,单位为米(m) + /// + public ushort Altitude { get; set; } + /// + /// 速度 1/10km/h + /// + public ushort Speed { get; set; } + /// + /// 方向 0-359,正北为 0,顺时针 + /// + public ushort Direction { get; set; } + /// + /// YY-MM-DD-hh-mm-ss(GMT+8 时间,本标准中之后涉及的时间均采用此时区) + /// + public DateTime GPSTime { get; set; } + /// + /// 位置附加信息 + /// + public Dictionary JT808LocationAttachData { get; set; } + /// + /// 存储自定义附加信息源数据 + /// + public Dictionary JT808CustomLocationAttachOriginalData { get; set; } + /// + /// 存储未知的附加信息源数据 + /// + public Dictionary JT808UnknownLocationAttachOriginalData { get; set; } + /// + /// 自定义位置附加信息 + /// 场景: + /// 一个设备厂商对应多个设备类型,不同设备类型可能存在相同的自定义位置附加信息Id,导致自定义附加信息Id冲突,无法解析。 + /// 解决方式: + /// 1.凡是解析自定义附加信息Id协议的,先进行分割存储,然后在根据外部的设备类型进行统一处理。 + /// 2.可以根据设备类型做个工厂,解耦对公共序列化器的依赖。 + /// 缺点: + /// 依赖平台录入的设备类型 + /// + public Dictionary JT808CustomLocationAttachData { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x01.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x01.cs new file mode 100644 index 0000000..9472e6e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x01.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Runtime.Serialization; + +namespace JT808.Protocol.MessageBody +{ + + [JT808Formatter(typeof(JT808_0x0200_0x01_Formatter))] + public class JT808_0x0200_0x01 : JT808_0x0200_BodyBase + { + public override byte AttachInfoId { get; set; } = 0x01; + public override byte AttachInfoLength { get; set; } = 4; + /// + /// 里程 + /// + public int Mileage { get; set; } + /// + /// 里程 1/10km,对应车上里程表读数 + /// + [IgnoreDataMember] + public double ConvertMileage => Mileage / 10.0; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x02.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x02.cs new file mode 100644 index 0000000..029e101 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x02.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Runtime.Serialization; + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x02_Formatter))] + public class JT808_0x0200_0x02 : JT808_0x0200_BodyBase + { + /// + /// 油量 + /// + public ushort Oil { get; set; } + /// + /// 油量 1/10L,对应车上油量表读数 + /// + [IgnoreDataMember] + public double ConvertOil => Oil / 10.0; + public override byte AttachInfoId { get; set; } = 0x02; + public override byte AttachInfoLength { get; set; } = 2; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x03.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x03.cs new file mode 100644 index 0000000..6728959 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x03.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Runtime.Serialization; + +namespace JT808.Protocol.MessageBody +{ + + [JT808Formatter(typeof(JT808_0x0200_0x03_Formatter))] + public class JT808_0x0200_0x03 : JT808_0x0200_BodyBase + { + /// + /// 行驶记录功能获取的速度 + /// + public ushort Speed { get; set; } + /// + /// 行驶记录功能获取的速度 1/10km/h + /// + [IgnoreDataMember] + public double ConvertSpeed => Speed / 10.0; + public override byte AttachInfoId { get; set; } = 0x03; + public override byte AttachInfoLength { get; set; } = 2; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x04.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x04.cs new file mode 100644 index 0000000..fd1a908 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x04.cs @@ -0,0 +1,16 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x04_Formatter))] + public class JT808_0x0200_0x04 : JT808_0x0200_BodyBase + { + /// + /// 需要人工确认报警事件的 ID,从 1 开始计数 + /// + public ushort EventId { get; set; } + public override byte AttachInfoId { get; set; } = 0x04; + public override byte AttachInfoLength { get; set; } = 2; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x11.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x11.cs new file mode 100644 index 0000000..09a47c1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x11.cs @@ -0,0 +1,42 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x11_Formatter))] + public class JT808_0x0200_0x11 : JT808_0x0200_BodyBase + { + /// + /// 超速报警附加信息 + /// 0:无特定位置; + /// 1:圆形区域; + /// 2:矩形区域; + /// 3:多边形区域; + /// 4:路段 + /// + public JT808PositionType JT808PositionType { get; set; } + + /// + /// 区域或路段 ID + /// 若位置类型为 0,无该字段 + /// + public int AreaId { get; set; } + public override byte AttachInfoId { get; set; } = 0x11; + public override byte AttachInfoLength + { + get + { + if (JT808PositionType != JT808PositionType.无特定位置) + { + return 5; + } + else + { + return 1; + } + } + set { } + } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x12.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x12.cs new file mode 100644 index 0000000..1112948 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x12.cs @@ -0,0 +1,33 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x12_Formatter))] + public class JT808_0x0200_0x12 : JT808_0x0200_BodyBase + { + /// + /// 位置类型 + /// 1:圆形区域; + /// 2:矩形区域; + /// 3:多边形区域; + /// 4:路段 + /// + public JT808PositionType JT808PositionType { get; set; } + + /// + /// 区域或路段 ID + /// + public int AreaId { get; set; } + + /// + /// 方向 + /// 0:进 + /// 1:出 + /// + public JT808DirectionType Direction { get; set; } + public override byte AttachInfoId { get; set; } = 0x12; + public override byte AttachInfoLength { get; set; } = 6; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x13.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x13.cs new file mode 100644 index 0000000..c05cff6 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x13.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + + +namespace JT808.Protocol.MessageBody +{ + + [JT808Formatter(typeof(JT808_0x0200_0x13_Formatter))] + public class JT808_0x0200_0x13 : JT808_0x0200_BodyBase + { + public override byte AttachInfoId { get; set; } = 0x13; + public override byte AttachInfoLength { get; set; } = 7; + + /// + /// 路段 ID + /// + public int DrivenRouteId { get; set; } + + /// + /// 路段行驶时间 + /// 单位为秒(s) + /// + public ushort Time { get; set; } + + /// + /// 结果 0:不足;1:过长 + /// + public JT808DrivenRouteType DrivenRoute { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x25.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x25.cs new file mode 100644 index 0000000..a311942 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x25.cs @@ -0,0 +1,17 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x25_Formatter))] + public class JT808_0x0200_0x25 : JT808_0x0200_BodyBase + { + /// + /// 扩展车辆信号状态位 + /// + public int CarSignalStatus { get; set; } + public override byte AttachInfoId { get; set; } = 0x25; + public override byte AttachInfoLength { get; set; } = 4; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2A.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2A.cs new file mode 100644 index 0000000..1928517 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2A.cs @@ -0,0 +1,17 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x2A_Formatter))] + public class JT808_0x0200_0x2A : JT808_0x0200_BodyBase + { + /// + /// IO状态位 + /// + public ushort IOStatus { get; set; } + public override byte AttachInfoId { get; set; } = 0x2A; + public override byte AttachInfoLength { get; set; } = 2; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2B.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2B.cs new file mode 100644 index 0000000..67d70be --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x2B.cs @@ -0,0 +1,17 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x2B_Formatter))] + public class JT808_0x0200_0x2B : JT808_0x0200_BodyBase + { + /// + /// 模拟量 bit0-15,AD0;bit16-31,AD1 + /// + public int Analog { get; set; } + public override byte AttachInfoId { get; set; } = 0x2B; + public override byte AttachInfoLength { get; set; } = 4; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x30.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x30.cs new file mode 100644 index 0000000..efb7b05 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x30.cs @@ -0,0 +1,17 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x30_Formatter))] + public class JT808_0x0200_0x30 : JT808_0x0200_BodyBase + { + /// + /// 无线通信网络信号强度 + /// + public byte WiFiSignalStrength { get; set; } + public override byte AttachInfoId { get; set; } = 0x30; + public override byte AttachInfoLength { get; set; } = 1; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_0x31.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x31.cs new file mode 100644 index 0000000..83cd000 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_0x31.cs @@ -0,0 +1,16 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + [JT808Formatter(typeof(JT808_0x0200_0x31_Formatter))] + public class JT808_0x0200_0x31 : JT808_0x0200_BodyBase + { + /// + /// GNSS 定位卫星数 + /// + public byte GNSSCount { get; set; } + public override byte AttachInfoId { get; set; } = 0x31; + public override byte AttachInfoLength { get; set; } = 1; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_BodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_BodyBase.cs new file mode 100644 index 0000000..a7937ec --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_BodyBase.cs @@ -0,0 +1,75 @@ +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置附加信息 + /// + public abstract class JT808_0x0200_BodyBase + { + /// + /// 位置附加信息方法 + /// + internal static IDictionary JT808LocationAttachMethod { get; private set; } + + static JT808_0x0200_BodyBase() + { + InitJT808LocationAttachMethod(); + } + + private static void InitJT808LocationAttachMethod() + { + JT808LocationAttachMethod = new Dictionary + { + {AttachId0x01, typeof(JT808_0x0200_0x01)}, + {AttachId0x02, typeof(JT808_0x0200_0x02)}, + {AttachId0x03, typeof(JT808_0x0200_0x03)}, + {AttachId0x04, typeof(JT808_0x0200_0x04)}, + {AttachId0x11, typeof(JT808_0x0200_0x11)}, + {AttachId0x12, typeof(JT808_0x0200_0x12)}, + {AttachId0x13, typeof(JT808_0x0200_0x13)}, + {AttachId0x25, typeof(JT808_0x0200_0x25)}, + {AttachId0x2A, typeof(JT808_0x0200_0x2A)}, + {AttachId0x2B, typeof(JT808_0x0200_0x2B)}, + {AttachId0x30, typeof(JT808_0x0200_0x30)}, + {AttachId0x31, typeof(JT808_0x0200_0x31)}, + }; + } + + internal static void AddJT808LocationAttachMethod(byte attachInfoId) + where TJT808LocationAttach : JT808_0x0200_BodyBase + { + JT808LocationAttachMethod.Add(attachInfoId, typeof(TJT808LocationAttach)); + } + + internal static void AddJT808LocationAttachMethod(byte attachInfoId, Type type) + { + JT808LocationAttachMethod.Add(attachInfoId, type); + } + + /// + /// 附加信息Id + /// + public abstract byte AttachInfoId { get; set; } + + /// + /// 附加信息长度 + /// + public abstract byte AttachInfoLength { get; set; } + + public const byte AttachId0x01 = 0x01; + public const byte AttachId0x02 = 0x02; + public const byte AttachId0x03 = 0x03; + public const byte AttachId0x04 = 0x04; + public const byte AttachId0x11 = 0x11; + public const byte AttachId0x12 = 0x12; + public const byte AttachId0x13 = 0x13; + public const byte AttachId0x25 = 0x25; + public const byte AttachId0x2A = 0x2A; + public const byte AttachId0x2B = 0x2B; + public const byte AttachId0x30 = 0x30; + public const byte AttachId0x31 = 0x31; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0200_CustomBodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x0200_CustomBodyBase.cs new file mode 100644 index 0000000..f317ba0 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0200_CustomBodyBase.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 自定义位置附加信息 + /// + public abstract class JT808_0x0200_CustomBodyBase + { + /// + /// 自定义附加信息Id + /// + public abstract byte AttachInfoId { get; set; } + + /// + /// 自定义附加信息长度 + /// + public abstract byte AttachInfoLength { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0201.cs b/src/JT808.Protocol/MessageBody/JT808_0x0201.cs new file mode 100644 index 0000000..b0645b1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0201.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置信息查询应答 + /// + [JT808Formatter(typeof(JT808_0x0201_Formatter))] + public class JT808_0x0201 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的终端注册消息的流水号 + /// + public ushort MsgNum { get; set; } + + /// + /// 位置信息汇报见 8.12 + /// + public JT808_0x0200 Position { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0301.cs b/src/JT808.Protocol/MessageBody/JT808_0x0301.cs new file mode 100644 index 0000000..ac52cea --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0301.cs @@ -0,0 +1,18 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 事件报告 + /// 0x0301 + /// + [JT808Formatter(typeof(JT808_0x0301_Formatter))] + public class JT808_0x0301 : JT808Bodies + { + /// + /// 事件 ID + /// + public byte EventId { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0302.cs b/src/JT808.Protocol/MessageBody/JT808_0x0302.cs new file mode 100644 index 0000000..bc2ce56 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0302.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 提问应答 + /// 0x0302 + /// + [JT808Formatter(typeof(JT808_0x0302_Formatter))] + public class JT808_0x0302 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的提问下发消息的流水号 + /// + public ushort ReplySNo { get; set; } + /// + /// 答案 ID + /// 提问下发中附带的答案 ID + /// + public byte AnswerId { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0303.cs b/src/JT808.Protocol/MessageBody/JT808_0x0303.cs new file mode 100644 index 0000000..f098c59 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0303.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 信息点播/取消 + /// 0x0303 + /// + [JT808Formatter(typeof(JT808_0x0303_Formatter))] + public class JT808_0x0303 : JT808Bodies + { + /// + /// 信息类型 + /// + public byte InformationType { get; set; } + /// + /// 点播/取消标志 + /// + public byte Flag { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0500.cs b/src/JT808.Protocol/MessageBody/JT808_0x0500.cs new file mode 100644 index 0000000..270320e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0500.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车辆控制应答 + /// + [JT808Formatter(typeof(JT808_0x0500_Formatter))] + public class JT808_0x0500 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的终端注册消息的流水号 + /// + public ushort MsgNum { get; set; } + /// + /// 位置信息汇报消息体 + /// + public JT808_0x0200 JT808_0x0200 { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0701.cs b/src/JT808.Protocol/MessageBody/JT808_0x0701.cs new file mode 100644 index 0000000..73284ee --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0701.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 电子运单上报 + /// 0x0701 + /// + [JT808Formatter(typeof(JT808_0x0701_Formatter))] + public class JT808_0x0701 : JT808Bodies + { + /// + /// 电子运单长度 + /// + public uint ElectronicWaybillLength { get; set; } + + public byte[] ElectronicContent { get; set; } + + /// + /// 电子运单内容 + /// 注意:需要具体的实现 + /// + public JT808_0x0701_CustomBodyBase ElectronicContentObj { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0701_CustomBodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x0701_CustomBodyBase.cs new file mode 100644 index 0000000..2678763 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0701_CustomBodyBase.cs @@ -0,0 +1,15 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 电子运单内容基类 + /// 注意:需要具体的实现 + /// + public abstract class JT808_0x0701_CustomBodyBase + { + + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0702.cs b/src/JT808.Protocol/MessageBody/JT808_0x0702.cs new file mode 100644 index 0000000..fc8ca2c --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0702.cs @@ -0,0 +1,62 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 驾驶员身份信息采集上报 + /// + [JT808Formatter(typeof(JT808_0x0702_Formatter))] + public class JT808_0x0702 : JT808Bodies + { + /// + /// 状态 + /// 0x01:从业资格证 IC 卡插入(驾驶员上班); + /// 0x02:从业资格证 IC 卡拔出(驾驶员下班)。 + /// + public JT808ICCardStatus IC_Card_Status { get; set; } + /// + /// 插卡/拔卡时间,YY-MM-DD-hh-mm-ss; + /// 以下字段在状态为 0x01 时才有效并做填充。 + /// BCD[6] + /// + public DateTime IC_Card_PlugDateTime { get; set; } + /// + /// IC 卡读取结果 + /// 0x00:IC 卡读卡成功; + /// 0x01:读卡失败,原因为卡片密钥认证未通过; + /// 0x02:读卡失败,原因为卡片已被锁定; + /// 0x03:读卡失败,原因为卡片被拔出; + /// 0x04:读卡失败,原因为数据校验错误。 + /// 以下字段在 IC 卡读取结果等于 0x00 时才有效。 + /// + public JT808ICCardReadResult IC_Card_ReadResult { get; set; } + /// + /// 驾驶员姓名长度 + /// + public byte DriverUserNameLength { get; set; } + /// + /// 驾驶员姓名 + /// + public string DriverUserName { get; set; } + /// + /// 从业资格证编码 + /// 长度 20 位,不足补 0x00。 + /// + public string QualificationCode { get; set; } + /// + /// 发证机构名称长度 + /// + public byte LicenseIssuingLength { get; set; } + /// + /// 发证机构名称长度 + /// + public string LicenseIssuing { get; set; } + /// + /// 证件有效期 BCD[4] + /// + public DateTime CertificateExpiresDate { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0704.cs b/src/JT808.Protocol/MessageBody/JT808_0x0704.cs new file mode 100644 index 0000000..389b3d8 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0704.cs @@ -0,0 +1,37 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 定位数据批量上传 + /// + [JT808Formatter(typeof(JT808_0x0704_Formatter))] + public class JT808_0x0704 : JT808Bodies + { + /// + /// 数据项个数 + /// + public ushort Count { get; set; } + + /// + /// 位置数据类型 + /// + public BatchLocationType LocationType { get; set; } + + /// + /// 位置汇报数据集合 + /// + public IList Positions { get; set; } + + /// + /// 位置数据类型 + /// + public enum BatchLocationType : byte + { + 正常位置批量汇报 = 0x00, + 盲区补报 = 0x01 + } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0705.cs b/src/JT808.Protocol/MessageBody/JT808_0x0705.cs new file mode 100644 index 0000000..2deed02 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0705.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线数据上传 + /// 0x0705 + /// + [JT808Formatter(typeof(JT808_0x0705_Formatter))] + public class JT808_0x0705 : JT808Bodies + { + /// + /// 数据项个数 + /// 包含的 CAN 总线数据项个数,>0 + /// + public ushort CanItemCount { get; set; } + /// + /// CAN 总线数据接收时间 + /// 第 1 条 CAN 总线数据的接收时间,hh-mm-ss-msms + /// + public DateTime FirstCanReceiveTime { get; set; } + /// + /// CAN 总线数据项 + /// + public List CanItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0800.cs b/src/JT808.Protocol/MessageBody/JT808_0x0800.cs new file mode 100644 index 0000000..4473784 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0800.cs @@ -0,0 +1,47 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 多媒体事件信息上传 + /// 0x0800 + /// + [JT808Formatter(typeof(JT808_0x0800_Formatter))] + public class JT808_0x0800 : JT808Bodies + { + /// + /// 多媒体数据 ID + /// + public uint MultimediaId { get; set; } + /// + /// 多媒体类型 + /// 0:图像;1:音频;2:视频; + /// + /// + public byte MultimediaType { get; set; } + /// + /// 多媒体格式编码 + /// 0:JPEG;1:TIF;2:MP3;3:WAV;4:WMV;其他保留 + /// + /// + public byte MultimediaCodingFormat { get; set; } + /// + /// 事件项编码 + /// 0:平台下发指令; + /// 1:定时动作; + /// 2:抢劫报警触发; + /// 3:碰撞侧翻报警触发; + /// 4:门开拍照; + /// 5:门关拍照; + /// 6:车门由开变关,时速从<20 公里到超过 20 公里; + /// 7:定距拍照; + /// 其他保留 + /// + public byte EventItemCoding { get; set; } + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0801.cs b/src/JT808.Protocol/MessageBody/JT808_0x0801.cs new file mode 100644 index 0000000..a27b30c --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0801.cs @@ -0,0 +1,47 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 多媒体数据上传 + /// 0x0801 + /// + [JT808Formatter(typeof(JT808_0x0801_Formatter))] + public class JT808_0x0801 : JT808Bodies + { + /// + /// 多媒体 ID + /// + public uint MultimediaId { get; set; } + /// + /// 多媒体类型 + /// + /// + public byte MultimediaType { get; set; } + /// + /// 多媒体格式编码 + /// 0:JPEG;1:TIF;2:MP3;3:WAV;4:WMV;其他保留 + /// + /// + public byte MultimediaCodingFormat { get; set; } + /// + /// 事件项编码 + /// + /// + public byte EventItemCoding { get; set; } + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + /// + /// 位置信息汇报(0x0200)消息体 + /// 表示拍摄或录制的起始时刻的位置基本信息数据 + /// + public JT808_0x0200 Position { get; set; } + /// + /// 多媒体数据包 + /// + public byte[] MultimediaDataPackage { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0802.cs b/src/JT808.Protocol/MessageBody/JT808_0x0802.cs new file mode 100644 index 0000000..acd4491 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0802.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 存储多媒体数据检索应答 + /// 0x0802 + /// + [JT808Formatter(typeof(JT808_0x0802_Formatter))] + public class JT808_0x0802 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的多媒体数据检索消息的流水号 + /// + public ushort MsgNum { get; set; } + /// + /// 多媒体数据总项数 + /// 满足检索条件的多媒体数据总项数 + /// + public ushort MultimediaItemCount { get; set; } + /// + /// 检索项集合 + /// + public List MultimediaSearchItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0805.cs b/src/JT808.Protocol/MessageBody/JT808_0x0805.cs new file mode 100644 index 0000000..afb60a8 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0805.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 摄像头立即拍摄命令应答 + /// 0x0805 + /// + [JT808Formatter(typeof(JT808_0x0805_Formatter))] + public class JT808_0x0805 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应平台摄像头立即拍摄命令的消息流水号 + /// + public ushort MsgNum { get; set; } + /// + /// 结果 + /// 0:成功;1:失败;2:通道不支持。以下字段在结果=0 时才有效。 + /// + public byte Result { get; set; } + /// + /// 多媒体ID个数 + /// 拍摄成功的多媒体个数 + /// + public ushort MultimediaIdCount { get; set; } + /// + /// 多媒体ID列表 + /// + public List MultimediaIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0900.cs b/src/JT808.Protocol/MessageBody/JT808_0x0900.cs new file mode 100644 index 0000000..27c3042 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0900.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 数据上行透传 + /// + [JT808Formatter(typeof(JT808_0x0900_Formatter))] + public class JT808_0x0900 : JT808Bodies + { + /// + /// 透传消息类型 + /// + public byte PassthroughType { get; set; } + + /// + /// 透传数据 + /// + public byte[] PassthroughData { get; set; } + + /// + /// 透传消息内容 + /// + public JT808_0x0900_BodyBase JT808_0x0900_BodyBase { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0900_BodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x0900_BodyBase.cs new file mode 100644 index 0000000..4c99af1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0900_BodyBase.cs @@ -0,0 +1,10 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 数据上行透传 + /// + public abstract class JT808_0x0900_BodyBase + { + + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0901.cs b/src/JT808.Protocol/MessageBody/JT808_0x0901.cs new file mode 100644 index 0000000..26c2e16 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0901.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 数据压缩上报 + /// 0x0901 + /// + [JT808Formatter(typeof(JT808_0x0901_Formatter))] + public class JT808_0x0901 : JT808Bodies + { + /// + /// 未压缩消息长度 + /// + public uint UnCompressMessageLength { get; set; } + /// + /// 未压缩消息体 + /// 压缩消息体为需要压缩的消息经过 GZIP 压缩算法后的消息 + /// 可实现 自定义压缩算法 + /// + public byte[] UnCompressMessage { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0A00.cs b/src/JT808.Protocol/MessageBody/JT808_0x0A00.cs new file mode 100644 index 0000000..eb3c985 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x0A00.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端 RSA 公钥 + /// 0x0A00 + /// + [JT808Formatter(typeof(JT808_0x0A00_Formatter))] + public class JT808_0x0A00 : JT808Bodies + { + /// + /// e + /// 终端 RSA 公钥{e,n}中的 e + /// + public uint E { get; set; } + /// + /// n + /// RSA 公钥{e,n}中的 n + /// + public byte[] N { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8001.cs b/src/JT808.Protocol/MessageBody/JT808_0x8001.cs new file mode 100644 index 0000000..f295779 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8001.cs @@ -0,0 +1,20 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 平台通用应答 + /// + [JT808Formatter(typeof(JT808_0x8001_Formatter))] + public class JT808_0x8001 : JT808Bodies + { + public ushort MsgNum { get; set; } + /// + /// + /// + public ushort MsgId { get; set; } + public JT808PlatformResult JT808PlatformResult { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8003.cs b/src/JT808.Protocol/MessageBody/JT808_0x8003.cs new file mode 100644 index 0000000..2ff7b65 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8003.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 补传分包请求 + /// 0x8003 + /// + [JT808Formatter(typeof(JT808_0x8003_Formatter))] + public class JT808_0x8003 : JT808Bodies + { + /// + /// 原始消息流水号 + /// 对应要求补传的原始消息第一包的消息流水号 + /// + public ushort OriginalMsgNum { get; set; } + /// + /// 重传包总数 + /// n + /// + public byte AgainPackageCount { get; set; } + /// + /// 重传包 ID 列表 + /// BYTE[2*n] + /// 重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。 + /// + public byte[] AgainPackageData { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8100.cs b/src/JT808.Protocol/MessageBody/JT808_0x8100.cs new file mode 100644 index 0000000..bd5191a --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8100.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端注册应答 + /// + [JT808Formatter(typeof(JT808_0x8100_Formatter))] + public class JT808_0x8100 : JT808Bodies + { + /// + /// 应答流水号 + /// 对应的终端注册消息的流水号 + /// + public ushort MsgNum { get; set; } + + /// + /// 结果 + /// + public JT808TerminalRegisterResult JT808TerminalRegisterResult { get; set; } + + /// + /// 鉴权码 + /// 只有在成功后才有该字段 + /// + public string Code { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103.cs new file mode 100644 index 0000000..c0816c5 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103.cs @@ -0,0 +1,36 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; +using System.Linq; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置终端参数 + /// + [JT808Formatter(typeof(JT808_0x8103_Formatter))] + public class JT808_0x8103 : JT808Bodies + { + /// + /// 参数总数 + /// + internal byte ParamCount + { + get + { + if (CustomParamList != null) + { + return (byte)(ParamList.Count + CustomParamList.Count); + } + return (byte)(ParamList.Count); + } + } + + /// + /// 参数列表 + /// + public List ParamList { get; set; } + + public List CustomParamList { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0001.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0001.cs new file mode 100644 index 0000000..803f672 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0001.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端心跳发送间隔,单位为秒(s) + /// 0x8103_0x0001 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0001_Formatter))] + public class JT808_0x8103_0x0001 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0001; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 终端心跳发送间隔,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0002.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0002.cs new file mode 100644 index 0000000..d5329b7 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0002.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// TCP 消息应答超时时间,单位为秒(s) + /// 0x8103_0x0002 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0002_Formatter))] + public class JT808_0x8103_0x0002 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0002; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// TCP 消息应答超时时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0003.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0003.cs new file mode 100644 index 0000000..bf91318 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0003.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// TCP 消息重传次数 + /// 0x8103_0x0003 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0003_Formatter))] + public class JT808_0x8103_0x0003 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0003; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// TCP 消息重传次数 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0004.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0004.cs new file mode 100644 index 0000000..e3e5501 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0004.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// UDP 消息应答超时时间,单位为秒(s) + /// 0x8103_0x0004 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0004_Formatter))] + public class JT808_0x8103_0x0004 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0004; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// UDP 消息应答超时时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0005.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0005.cs new file mode 100644 index 0000000..4833c36 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0005.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// UDP 消息重传次数 + /// 0x8103_0x0005 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0005_Formatter))] + public class JT808_0x8103_0x0005 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0005; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// UDP 消息重传次数 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0006.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0006.cs new file mode 100644 index 0000000..1718568 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0006.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// SMS 消息应答超时时间,单位为秒(s) + /// 0x8103_0x0006 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0006_Formatter))] + public class JT808_0x8103_0x0006 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0006; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// SMS 消息应答超时时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0007.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0007.cs new file mode 100644 index 0000000..4e71207 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0007.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// SMS 消息重传次数 + /// 0x8103_0x0007 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0007_Formatter))] + public class JT808_0x8103_0x0007 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0007; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// SMS 消息重传次数 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0010.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0010.cs new file mode 100644 index 0000000..0dd35de --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0010.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 主服务器 APN,无线通信拨号访问点。若网络制式为 CDMA,则该处为PPP 拨号号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0010_Formatter))] + public class JT808_0x8103_0x0010 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0010; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 主服务器 APN,无线通信拨号访问点。若网络制式为 CDMA,则该处为PPP 拨号号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0011.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0011.cs new file mode 100644 index 0000000..396c8b0 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0011.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 主服务器无线通信拨号用户名 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0011_Formatter))] + public class JT808_0x8103_0x0011 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0011; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 主服务器无线通信拨号用户名 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0012.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0012.cs new file mode 100644 index 0000000..0a7ddc9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0012.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 主服务器无线通信拨号密码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0012_Formatter))] + public class JT808_0x8103_0x0012 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0012; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 主服务器无线通信拨号密码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0013.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0013.cs new file mode 100644 index 0000000..c953c93 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0013.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 主服务器地址,IP 或域名 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0013_Formatter))] + public class JT808_0x8103_0x0013 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0013; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 主服务器地址,IP 或域名 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0014.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0014.cs new file mode 100644 index 0000000..7432614 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0014.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 备份服务器 APN,无线通信拨号访问点 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0014_Formatter))] + public class JT808_0x8103_0x0014 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0014; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 备份服务器 APN,无线通信拨号访问点 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0015.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0015.cs new file mode 100644 index 0000000..7aa2217 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0015.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 备份服务器无线通信拨号用户名 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0015_Formatter))] + public class JT808_0x8103_0x0015 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0015; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 备份服务器无线通信拨号用户名 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0016.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0016.cs new file mode 100644 index 0000000..a64e979 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0016.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 备份服务器无线通信拨号密码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0016_Formatter))] + public class JT808_0x8103_0x0016 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0016; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 备份服务器无线通信拨号密码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0017.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0017.cs new file mode 100644 index 0000000..f0c34f1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0017.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 备份服务器地址,IP 或域名 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0017_Formatter))] + public class JT808_0x8103_0x0017 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0017; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 备份服务器地址,IP 或域名 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0018.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0018.cs new file mode 100644 index 0000000..89fa14c --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0018.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 服务器 TCP 端口 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0018_Formatter))] + public class JT808_0x8103_0x0018 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0018; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + ///服务器 TCP 端口 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0019.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0019.cs new file mode 100644 index 0000000..5676162 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0019.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 服务器 UDP 端口 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0019_Formatter))] + public class JT808_0x8103_0x0019 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0019; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + ///服务器 TCP 端口 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001A.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001A.cs new file mode 100644 index 0000000..b518f29 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001A.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 道路运输证 IC 卡认证主服务器 IP 地址或域名 + /// + [JT808Formatter(typeof(JT808_0x8103_0x001A_Formatter))] + public class JT808_0x8103_0x001A : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x001A; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 道路运输证 IC 卡认证主服务器 IP 地址或域名 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001B.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001B.cs new file mode 100644 index 0000000..65b2a5c --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001B.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 道路运输证 IC 卡认证主服务器 TCP 端口 + /// + [JT808Formatter(typeof(JT808_0x8103_0x001B_Formatter))] + public class JT808_0x8103_0x001B : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x001B; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + ///道路运输证 IC 卡认证主服务器 TCP 端口 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001C.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001C.cs new file mode 100644 index 0000000..34b7bed --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001C.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 道路运输证 IC 卡认证主服务器 UDP 端口 + /// + [JT808Formatter(typeof(JT808_0x8103_0x001C_Formatter))] + public class JT808_0x8103_0x001C : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x001C; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + ///道路运输证 IC 卡认证主服务器 UDP 端口 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001D.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001D.cs new file mode 100644 index 0000000..158442b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x001D.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 道路运输证 IC 卡认证备份服务器 IP 地址或域名,端口同主服务器 + /// + [JT808Formatter(typeof(JT808_0x8103_0x001D_Formatter))] + public class JT808_0x8103_0x001D : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x001D; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 道路运输证 IC 卡认证备份服务器 IP 地址或域名,端口同主服务器 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0020.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0020.cs new file mode 100644 index 0000000..191479d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0020.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置汇报策略,0:定时汇报;1:定距汇报;2:定时和定距汇报 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0020_Formatter))] + public class JT808_0x8103_0x0020 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0020; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 位置汇报策略,0:定时汇报;1:定距汇报;2:定时和定距汇报 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0021.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0021.cs new file mode 100644 index 0000000..ccf9e6b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0021.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置汇报方案,0:根据 ACC 状态; 1:根据登录状态和 ACC 状态,先判断登录状态,若登录再根据 ACC 状态 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0021_Formatter))] + public class JT808_0x8103_0x0021 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0021; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 位置汇报方案,0:根据 ACC 状态; 1:根据登录状态和 ACC 状态,先判断登录状态,若登录再根据 ACC 状态 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0022.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0022.cs new file mode 100644 index 0000000..9727f66 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0022.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 驾驶员未登录汇报时间间隔,单位为秒(s),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0022_Formatter))] + public class JT808_0x8103_0x0022 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0022; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 驾驶员未登录汇报时间间隔,单位为秒(s),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0027.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0027.cs new file mode 100644 index 0000000..c7af276 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0027.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 休眠时汇报时间间隔,单位为秒(s),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0027_Formatter))] + public class JT808_0x8103_0x0027 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0027; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 休眠时汇报时间间隔,单位为秒(s),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0028.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0028.cs new file mode 100644 index 0000000..355ae3e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0028.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 紧急报警时汇报时间间隔,单位为秒(s),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0028_Formatter))] + public class JT808_0x8103_0x0028 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0028; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 紧急报警时汇报时间间隔,单位为秒(s),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0029.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0029.cs new file mode 100644 index 0000000..c8ee297 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0029.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 缺省时间汇报间隔,单位为秒(s),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0029_Formatter))] + public class JT808_0x8103_0x0029 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0029; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 缺省时间汇报间隔,单位为秒(s),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002C.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002C.cs new file mode 100644 index 0000000..2a7af06 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002C.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 缺省距离汇报间隔,单位为米(m),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x002C_Formatter))] + public class JT808_0x8103_0x002C : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x002C; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 缺省距离汇报间隔,单位为米(m),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002D.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002D.cs new file mode 100644 index 0000000..a9b79c4 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002D.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 驾驶员未登录汇报距离间隔,单位为米(m),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x002D_Formatter))] + public class JT808_0x8103_0x002D : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x002D; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 驾驶员未登录汇报距离间隔,单位为米(m),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002E.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002E.cs new file mode 100644 index 0000000..c061742 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002E.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 休眠时汇报距离间隔,单位为米(m),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x002E_Formatter))] + public class JT808_0x8103_0x002E : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x002E; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 休眠时汇报距离间隔,单位为米(m),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002F.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002F.cs new file mode 100644 index 0000000..6543d10 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x002F.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 紧急报警时汇报距离间隔,单位为米(m),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x002F_Formatter))] + public class JT808_0x8103_0x002F : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x002F; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 紧急报警时汇报距离间隔,单位为米(m),>0 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0030.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0030.cs new file mode 100644 index 0000000..b089441 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0030.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 拐点补传角度,<180 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0030_Formatter))] + public class JT808_0x8103_0x0030 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0030; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 拐点补传角度,<180 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0031.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0031.cs new file mode 100644 index 0000000..ce64476 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0031.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 电子围栏半径(非法位移阈值),单位为米 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0031_Formatter))] + public class JT808_0x8103_0x0031 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0031; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 电子围栏半径(非法位移阈值),单位为米 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0040.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0040.cs new file mode 100644 index 0000000..024d821 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0040.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 监控平台电话号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0040_Formatter))] + public class JT808_0x8103_0x0040 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0040; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 监控平台电话号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0041.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0041.cs new file mode 100644 index 0000000..825df95 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0041.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 复位电话号码,可采用此电话号码拨打终端电话让终端复位 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0041_Formatter))] + public class JT808_0x8103_0x0041 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0041; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 复位电话号码,可采用此电话号码拨打终端电话让终端复位 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0042.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0042.cs new file mode 100644 index 0000000..c27cca7 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0042.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 恢复出厂设置电话号码,可采用此电话号码拨打终端电话让终端恢复出厂设置 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0042_Formatter))] + public class JT808_0x8103_0x0042 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0042; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 恢复出厂设置电话号码,可采用此电话号码拨打终端电话让终端恢复出厂设置 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0043.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0043.cs new file mode 100644 index 0000000..593aeac --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0043.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 监控平台 SMS 电话号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0043_Formatter))] + public class JT808_0x8103_0x0043 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0043; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 监控平台 SMS 电话号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0044.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0044.cs new file mode 100644 index 0000000..3e87dde --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0044.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 接收终端 SMS 文本报警号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0044_Formatter))] + public class JT808_0x8103_0x0044 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0044; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 接收终端 SMS 文本报警号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0045.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0045.cs new file mode 100644 index 0000000..42dd696 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0045.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端电话接听策略,0:自动接听;1:ACC ON 时自动接听,OFF 时手动接听 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0045_Formatter))] + public class JT808_0x8103_0x0045 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0045; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 终端电话接听策略,0:自动接听;1:ACC ON 时自动接听,OFF 时手动接听 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0046.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0046.cs new file mode 100644 index 0000000..fed5456 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0046.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 每次最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0046_Formatter))] + public class JT808_0x8103_0x0046 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0046; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 每次最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0047.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0047.cs new file mode 100644 index 0000000..e7b1d9d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0047.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 当月最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0047_Formatter))] + public class JT808_0x8103_0x0047 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0047; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 当月最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0048.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0048.cs new file mode 100644 index 0000000..0c87e80 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0048.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 监听电话号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0048_Formatter))] + public class JT808_0x8103_0x0048 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0048; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 监听电话号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0049.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0049.cs new file mode 100644 index 0000000..d084851 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0049.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 监管平台特权短信号码 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0049_Formatter))] + public class JT808_0x8103_0x0049 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0049; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 监管平台特权短信号码 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0050.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0050.cs new file mode 100644 index 0000000..0ca5b95 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0050.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 报警屏蔽字,与位置信息汇报消息中的报警标志相对应,相应位为 1则相应报警被屏蔽 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0050_Formatter))] + public class JT808_0x8103_0x0050 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0050; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 报警屏蔽字,与位置信息汇报消息中的报警标志相对应,相应位为 1则相应报警被屏蔽 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0051.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0051.cs new file mode 100644 index 0000000..8c7feb1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0051.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 报警发送文本 SMS 开关,与位置信息汇报消息中的报警标志相对应,相应位为 1 则相应报警时发送文本 SMS + /// + [JT808Formatter(typeof(JT808_0x8103_0x0051_Formatter))] + public class JT808_0x8103_0x0051 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0051; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 报警发送文本 SMS 开关,与位置信息汇报消息中的报警标志相对应,相应位为 1 则相应报警时发送文本 SMS + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0052.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0052.cs new file mode 100644 index 0000000..fda4251 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0052.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 报警拍摄开关,与位置信息汇报消息中的报警标志相对应,相应位为1 则相应报警时摄像头拍摄 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0052_Formatter))] + public class JT808_0x8103_0x0052 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0052; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 报警拍摄开关,与位置信息汇报消息中的报警标志相对应,相应位为1 则相应报警时摄像头拍摄 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0053.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0053.cs new file mode 100644 index 0000000..d87d6f7 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0053.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 报警拍摄存储标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警时拍的照片进行存储,否则实时上传 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0053_Formatter))] + public class JT808_0x8103_0x0053 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0053; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 报警拍摄存储标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警时拍的照片进行存储,否则实时上传 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0054.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0054.cs new file mode 100644 index 0000000..2dd0135 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0054.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 关键标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警为关键报警 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0054_Formatter))] + public class JT808_0x8103_0x0054 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0054; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 关键标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警为关键报警 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0055.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0055.cs new file mode 100644 index 0000000..717e739 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0055.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 最高速度,单位为公里每小时(km/h) + /// + [JT808Formatter(typeof(JT808_0x8103_0x0055_Formatter))] + public class JT808_0x8103_0x0055 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0055; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 最高速度,单位为公里每小时(km/h) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0056.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0056.cs new file mode 100644 index 0000000..4090ef3 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0056.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 超速持续时间,单位为秒(s) + /// + [JT808Formatter(typeof(JT808_0x8103_0x0056_Formatter))] + public class JT808_0x8103_0x0056 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0056; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 超速持续时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0057.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0057.cs new file mode 100644 index 0000000..1854bfe --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0057.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 连续驾驶时间门限,单位为秒(s) + /// + [JT808Formatter(typeof(JT808_0x8103_0x0057_Formatter))] + public class JT808_0x8103_0x0057 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0057; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 连续驾驶时间门限,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0058.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0058.cs new file mode 100644 index 0000000..3139f77 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0058.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 当天累计驾驶时间门限,单位为秒(s) + /// + [JT808Formatter(typeof(JT808_0x8103_0x0058_Formatter))] + public class JT808_0x8103_0x0058 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0058; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 当天累计驾驶时间门限,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0059.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0059.cs new file mode 100644 index 0000000..b90b684 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0059.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 最小休息时间,单位为秒(s) + /// + [JT808Formatter(typeof(JT808_0x8103_0x0059_Formatter))] + public class JT808_0x8103_0x0059 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0059; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 最小休息时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005A.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005A.cs new file mode 100644 index 0000000..baa46b6 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005A.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 最长停车时间,单位为秒(s) + /// + [JT808Formatter(typeof(JT808_0x8103_0x005A_Formatter))] + public class JT808_0x8103_0x005A : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x005A; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 最长停车时间,单位为秒(s) + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005B.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005B.cs new file mode 100644 index 0000000..18d7d7d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005B.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 超速报警预警差值,单位为 1/10Km/h + /// + [JT808Formatter(typeof(JT808_0x8103_0x005B_Formatter))] + public class JT808_0x8103_0x005B : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x005B; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 超速报警预警差值,单位为 1/10Km/h + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005C.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005C.cs new file mode 100644 index 0000000..350a58f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005C.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 疲劳驾驶预警差值,单位为秒(s),>0 + /// + [JT808Formatter(typeof(JT808_0x8103_0x005C_Formatter))] + public class JT808_0x8103_0x005C : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x005C; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 疲劳驾驶预警差值,单位为秒(s),>0 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005D.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005D.cs new file mode 100644 index 0000000..13f562d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005D.cs @@ -0,0 +1,26 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 碰撞报警参数设置 + /// b7-b0: 碰撞时间,单位 4ms; + /// b15-b8:碰撞加速度,单位 0.1g,设置范围在:0-79 之间,默认为10。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x005D_Formatter))] + public class JT808_0x8103_0x005D : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x005D; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 碰撞报警参数设置 + /// b7-b0: 碰撞时间,单位 4ms; + /// b15-b8:碰撞加速度,单位 0.1g,设置范围在:0-79 之间,默认为10。 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005E.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005E.cs new file mode 100644 index 0000000..6fdd507 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x005E.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 侧翻报警参数设置: + /// 侧翻角度,单位 1 度,默认为 30 度 + /// + [JT808Formatter(typeof(JT808_0x8103_0x005E_Formatter))] + public class JT808_0x8103_0x005E : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x005E; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 侧翻报警参数设置: + /// 侧翻角度,单位 1 度,默认为 30 度 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0064.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0064.cs new file mode 100644 index 0000000..5ba7a87 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0064.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 定时拍照控制,见 表 13 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0064_Formatter))] + public class JT808_0x8103_0x0064 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0064; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 定时拍照控制,见 表 13 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0065.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0065.cs new file mode 100644 index 0000000..d8c2742 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0065.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 定距拍照控制,见 表 14 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0065_Formatter))] + public class JT808_0x8103_0x0065 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0065; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 定距拍照控制,见 表 14 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0070.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0070.cs new file mode 100644 index 0000000..82034b8 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0070.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 图像/视频质量,1-10,1 最好 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0070_Formatter))] + public class JT808_0x8103_0x0070 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0070; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 图像/视频质量,1-10,1 最好 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0071.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0071.cs new file mode 100644 index 0000000..b47746c --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0071.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 亮度,0-255 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0071_Formatter))] + public class JT808_0x8103_0x0071 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0071; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 亮度,0-255 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0072.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0072.cs new file mode 100644 index 0000000..fa9ac9d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0072.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 对比度,0-127 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0072_Formatter))] + public class JT808_0x8103_0x0072 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0072; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 对比度,0-127 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0073.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0073.cs new file mode 100644 index 0000000..b6b9601 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0073.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 饱和度,0-127 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0073_Formatter))] + public class JT808_0x8103_0x0073 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0073; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 饱和度,0-127 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0074.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0074.cs new file mode 100644 index 0000000..3a7abe0 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0074.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 色度,0-255 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0074_Formatter))] + public class JT808_0x8103_0x0074 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0074; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 饱和度,0-127 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0080.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0080.cs new file mode 100644 index 0000000..1fd7f65 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0080.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车辆里程表读数,1/10km + /// + [JT808Formatter(typeof(JT808_0x8103_0x0080_Formatter))] + public class JT808_0x8103_0x0080 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0080; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 4; + /// + /// 车辆里程表读数,1/10km + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0081.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0081.cs new file mode 100644 index 0000000..36e2b24 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0081.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车辆所在的省域 ID + /// + [JT808Formatter(typeof(JT808_0x8103_0x0081_Formatter))] + public class JT808_0x8103_0x0081 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0081; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 车辆所在的省域 ID + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0082.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0082.cs new file mode 100644 index 0000000..e6dd69f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0082.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车辆所在的市域 ID + /// + [JT808Formatter(typeof(JT808_0x8103_0x0082_Formatter))] + public class JT808_0x8103_0x0082 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0082; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } = 2; + /// + /// 车辆所在的市域 ID + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0083.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0083.cs new file mode 100644 index 0000000..87914c1 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0083.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 公安交通管理部门颁发的机动车号牌 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0083_Formatter))] + public class JT808_0x8103_0x0083 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0083; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 公安交通管理部门颁发的机动车号牌 + /// + public string ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0084.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0084.cs new file mode 100644 index 0000000..0048e3f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0084.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车牌颜色,按照 JT/T415-2006 的 5.4.12 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0084_Formatter))] + public class JT808_0x8103_0x0084 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0084; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// 车牌颜色,按照 JT/T415-2006 的 5.4.12 + /// + public byte ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0090.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0090.cs new file mode 100644 index 0000000..e9420e9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0090.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 定位模式,定义如下: + /// bit0,0:禁用 GPS 定位, 1:启用 GPS 定位; + /// bit1,0:禁用北斗定位, 1:启用北斗定位; + /// bit2,0:禁用 GLONASS 定位, 1:启用 GLONASS 定位; + /// bit3,0:禁用 Galileo 定位, 1:启用 Galileo 定位。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0090_Formatter))] + public class JT808_0x8103_0x0090 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0090; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 定位模式,定义如下: + /// bit0,0:禁用 GPS 定位, 1:启用 GPS 定位; + /// bit1,0:禁用北斗定位, 1:启用北斗定位; + /// bit2,0:禁用 GLONASS 定位, 1:启用 GLONASS 定位; + /// bit3,0:禁用 Galileo 定位, 1:启用 Galileo 定位。 + /// + public byte ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0091.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0091.cs new file mode 100644 index 0000000..26df052 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0091.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 波特率,定义如下: + /// 0x00:4800;0x01:9600; + /// 0x02:19200;0x03:38400; + /// 0x04:57600;0x05:115200。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0091_Formatter))] + public class JT808_0x8103_0x0091 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0091; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 波特率,定义如下: + /// 0x00:4800;0x01:9600; + /// 0x02:19200;0x03:38400; + /// 0x04:57600;0x05:115200。 + /// + public byte ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0092.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0092.cs new file mode 100644 index 0000000..bef54ee --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0092.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 模块详细定位数据输出频率,定义如下: + /// 0x00:500ms;0x01:1000ms(默认值); + /// 0x02:2000ms;0x03:3000ms; + /// 0x04:4000ms。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0092_Formatter))] + public class JT808_0x8103_0x0092 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0092; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 模块详细定位数据输出频率,定义如下: + /// 0x00:500ms;0x01:1000ms(默认值); + /// 0x02:2000ms;0x03:3000ms; + /// 0x04:4000ms。 + /// + public byte ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0093.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0093.cs new file mode 100644 index 0000000..1b77ad7 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0093.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 模块详细定位数据采集频率,单位为秒,默认为 1。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0093_Formatter))] + public class JT808_0x8103_0x0093 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0093; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 模块详细定位数据采集频率,单位为秒,默认为 1。 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0094.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0094.cs new file mode 100644 index 0000000..6f6f446 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0094.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 模块详细定位数据上传方式 + /// 0x00,本地存储,不上传(默认值); + /// 0x01,按时间间隔上传; + /// 0x02,按距离间隔上传; + /// 0x0B,按累计时间上传,达到传输时间后自动停止上传; + /// 0x0C,按累计距离上传,达到距离后自动停止上传; + /// 0x0D,按累计条数上传,达到上传条数后自动停止上传。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0094_Formatter))] + public class JT808_0x8103_0x0094 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0094; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 模块详细定位数据上传方式 + /// 0x00,本地存储,不上传(默认值); + /// 0x01,按时间间隔上传; + /// 0x02,按距离间隔上传; + /// 0x0B,按累计时间上传,达到传输时间后自动停止上传; + /// 0x0C,按累计距离上传,达到距离后自动停止上传; + /// 0x0D,按累计条数上传,达到上传条数后自动停止上传。 + /// + public byte ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0095.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0095.cs new file mode 100644 index 0000000..b9fd2aa --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0095.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// GNSS 模块详细定位数据上传设置: + /// 上传方式为 0x01 时,单位为秒; + /// 上传方式为 0x02 时,单位为米; + /// 上传方式为 0x0B 时,单位为秒; + /// 上传方式为 0x0C 时,单位为米; + /// 上传方式为 0x0D 时,单位为条。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0095_Formatter))] + public class JT808_0x8103_0x0095 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0095; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// GNSS 模块详细定位数据上传设置: + /// 上传方式为 0x01 时,单位为秒; + /// 上传方式为 0x02 时,单位为米; + /// 上传方式为 0x0B 时,单位为秒; + /// 上传方式为 0x0C 时,单位为米; + /// 上传方式为 0x0D 时,单位为条。 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0100.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0100.cs new file mode 100644 index 0000000..a77c4e7 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0100.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线通道 1 采集时间间隔(ms),0 表示不采集 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0100_Formatter))] + public class JT808_0x8103_0x0100 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0100; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// CAN 总线通道 1 采集时间间隔(ms),0 表示不采集 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0101.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0101.cs new file mode 100644 index 0000000..ed84494 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0101.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线通道 1 上传时间间隔(s),0 表示不上传 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0101_Formatter))] + public class JT808_0x8103_0x0101 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0101; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// CAN 总线通道 1 上传时间间隔(s),0 表示不上传 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0102.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0102.cs new file mode 100644 index 0000000..9136275 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0102.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线通道 2 采集时间间隔(ms),0 表示不采集 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0102_Formatter))] + public class JT808_0x8103_0x0102 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0102; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// CAN 总线通道 2 采集时间间隔(ms),0 表示不采集 + /// + public uint ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0103.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0103.cs new file mode 100644 index 0000000..a23c489 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0103.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线通道 2 上传时间间隔(s),0 表示不上传 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0103_Formatter))] + public class JT808_0x8103_0x0103 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0103; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// CAN 总线通道 2 上传时间间隔(s),0 表示不上传 + /// + public ushort ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0110.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0110.cs new file mode 100644 index 0000000..fde4b13 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_0x0110.cs @@ -0,0 +1,32 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// CAN 总线 ID 单独采集设置: + /// bit63-bit32 表示此 ID 采集时间间隔(ms),0 表示不采集; + /// bit31 表示 CAN 通道号,0:CAN1,1:CAN2; + /// bit30 表示帧类型,0:标准帧,1:扩展帧; + /// bit29 表示数据采集方式,0:原始数据,1:采集区间的计算值; + /// bit28-bit0 表示 CAN 总线 ID。 + /// + [JT808Formatter(typeof(JT808_0x8103_0x0110_Formatter))] + public class JT808_0x8103_0x0110 : JT808_0x8103_BodyBase + { + public override uint ParamId { get; set; } = 0x0110; + /// + /// 数据 长度 + /// + public override byte ParamLength { get; set; } + /// + /// CAN 总线 ID 单独采集设置: + /// bit63-bit32 表示此 ID 采集时间间隔(ms),0 表示不采集; + /// bit31 表示 CAN 通道号,0:CAN1,1:CAN2; + /// bit30 表示帧类型,0:标准帧,1:扩展帧; + /// bit29 表示数据采集方式,0:原始数据,1:采集区间的计算值; + /// bit28-bit0 表示 CAN 总线 ID。 + /// + public byte[] ParamValue { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_BodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_BodyBase.cs new file mode 100644 index 0000000..7c1eaba --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_BodyBase.cs @@ -0,0 +1,461 @@ +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + public abstract class JT808_0x8103_BodyBase + { + /// + /// 终端心跳发送间隔,单位为秒(s) + /// + public const uint JT808_0x8103_0x0001_Type = 0x0001; + /// + /// TCP 消息应答超时时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x0002_Type = 0x0002; + /// + /// TCP 消息重传次数 + /// + public const uint JT808_0x8103_0x0003_Type = 0x0003; + /// + /// UDP 消息应答超时时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x0004_Type = 0x0004; + /// + /// UDP 消息重传次数 + /// + public const uint JT808_0x8103_0x0005_Type = 0x0005; + /// + /// SMS 消息应答超时时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x0006_Type = 0x0006; + /// + /// SMS 消息重传次数 + /// + public const uint JT808_0x8103_0x0007_Type = 0x0007; + /// + /// 主服务器 APN,无线通信拨号访问点。若网络制式为 CDMA,则该处为PPP 拨号号码 + /// + public const uint JT808_0x8103_0x0010_Type = 0x0010; + /// + /// 主服务器无线通信拨号用户名 + /// + public const uint JT808_0x8103_0x0011_Type = 0x0011; + /// + /// 主服务器无线通信拨号密码 + /// + public const uint JT808_0x8103_0x0012_Type = 0x0012; + /// + /// 主服务器地址,IP 或域名 + /// + public const uint JT808_0x8103_0x0013_Type = 0x0013; + /// + /// 主服务器地址,IP 或域名 + /// + public const uint JT808_0x8103_0x0014_Type = 0x0014; + /// + /// 备份服务器无线通信拨号用户名 + /// + public const uint JT808_0x8103_0x0015_Type = 0x0015; + /// + /// 备份服务器无线通信拨号密码 + /// + public const uint JT808_0x8103_0x0016_Type = 0x0016; + /// + /// 备份服务器地址,IP 或域名 + /// + public const uint JT808_0x8103_0x0017_Type = 0x0017; + /// + /// 服务器 TCP 端口 + /// + public const uint JT808_0x8103_0x0018_Type = 0x0018; + /// + /// 服务器 UDP 端口 + /// + public const uint JT808_0x8103_0x0019_Type = 0x0019; + /// + /// 道路运输证 IC 卡认证主服务器 IP 地址或域名 + /// + public const uint JT808_0x8103_0x001A_Type = 0x001A; + /// + /// 道路运输证 IC 卡认证主服务器 TCP 端口 + /// + public const uint JT808_0x8103_0x001B_Type = 0x001B; + /// + /// 道路运输证 IC 卡认证主服务器 UDP 端口 + /// + public const uint JT808_0x8103_0x001C_Type = 0x001C; + /// + /// 道路运输证 IC 卡认证备份服务器 IP 地址或域名,端口同主服务器 + /// + public const uint JT808_0x8103_0x001D_Type = 0x001D; + /// + /// 位置汇报策略,0:定时汇报;1:定距汇报;2:定时和定距汇报 + /// + public const uint JT808_0x8103_0x0020_Type = 0x0020; + /// + /// 位置汇报方案,0:根据 ACC 状态; 1:根据登录状态和 ACC 状态,先判断登录状态,若登录再根据 ACC 状态 + /// + public const uint JT808_0x8103_0x0021_Type = 0x0021; + /// + /// 驾驶员未登录汇报时间间隔,单位为秒(s),>0 + /// + public const uint JT808_0x8103_0x0022_Type = 0x0022; + /// + /// 休眠时汇报时间间隔,单位为秒(s),>0 + /// + public const uint JT808_0x8103_0x0027_Type = 0x0027; + /// + /// 紧急报警时汇报时间间隔,单位为秒(s),>0 + /// + public const uint JT808_0x8103_0x0028_Type = 0x0028; + /// + /// 缺省时间汇报间隔,单位为秒(s),>0 + /// + public const uint JT808_0x8103_0x0029_Type = 0x0029; + /// + /// 缺省距离汇报间隔,单位为米(m),>0 + /// + public const uint JT808_0x8103_0x002C_Type = 0x002C; + /// + /// 驾驶员未登录汇报距离间隔,单位为米(m),>0 + /// + public const uint JT808_0x8103_0x002D_Type = 0x002D; + /// + /// 休眠时汇报距离间隔,单位为米(m),>0 + /// + public const uint JT808_0x8103_0x002E_Type = 0x002E; + /// + /// 紧急报警时汇报距离间隔,单位为米(m),>0 + /// + public const uint JT808_0x8103_0x002F_Type = 0x002F; + /// + /// 拐点补传角度,<180 + /// + public const uint JT808_0x8103_0x0030_Type = 0x0030; + /// + /// 电子围栏半径(非法位移阈值),单位为米 + /// + public const uint JT808_0x8103_0x0031_Type = 0x0031; + /// + /// 监控平台电话号码 + /// + public const uint JT808_0x8103_0x0040_Type = 0x0040; + /// + /// 复位电话号码,可采用此电话号码拨打终端电话让终端复位 + /// + public const uint JT808_0x8103_0x0041_Type = 0x0041; + /// + /// 恢复出厂设置电话号码,可采用此电话号码拨打终端电话让终端恢复出厂设置 + /// + public const uint JT808_0x8103_0x0042_Type = 0x0042; + /// + /// 监控平台 SMS 电话号码 + /// + public const uint JT808_0x8103_0x0043_Type = 0x0043; + /// + /// 接收终端 SMS 文本报警号码 + /// + public const uint JT808_0x8103_0x0044_Type = 0x0044; + /// + /// 终端电话接听策略,0:自动接听;1:ACC ON 时自动接听,OFF 时手动接听 + /// + public const uint JT808_0x8103_0x0045_Type = 0x0045; + /// + /// 每次最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + public const uint JT808_0x8103_0x0046_Type = 0x0046; + /// + /// 当月最长通话时间,单位为秒(s),0 为不允许通话,0xFFFFFFFF 为不限制 + /// + public const uint JT808_0x8103_0x0047_Type = 0x0047; + /// + /// 监听电话号码 + /// + public const uint JT808_0x8103_0x0048_Type = 0x0048; + /// + /// 监管平台特权短信号码 + /// + public const uint JT808_0x8103_0x0049_Type = 0x0049; + /// + /// 报警屏蔽字,与位置信息汇报消息中的报警标志相对应,相应位为 1则相应报警被屏蔽 + /// + public const uint JT808_0x8103_0x0050_Type = 0x0050; + /// + /// 报警发送文本 SMS 开关,与位置信息汇报消息中的报警标志相对应,相应位为 1 则相应报警时发送文本 SMS + /// + public const uint JT808_0x8103_0x0051_Type = 0x0051; + /// + /// 报警拍摄开关,与位置信息汇报消息中的报警标志相对应,相应位为1 则相应报警时摄像头拍摄 + /// + public const uint JT808_0x8103_0x0052_Type = 0x0052; + /// + /// 报警拍摄存储标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警时拍的照片进行存储,否则实时上传 + /// + public const uint JT808_0x8103_0x0053_Type = 0x0053; + /// + /// 关键标志,与位置信息汇报消息中的报警标志相对应,相应位为 1 则对相应报警为关键报警 + /// + public const uint JT808_0x8103_0x0054_Type = 0x0054; + /// + /// 最高速度,单位为公里每小时(km/h) + /// + public const uint JT808_0x8103_0x0055_Type = 0x0055; + /// + /// 超速持续时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x0056_Type = 0x0056; + /// + /// 连续驾驶时间门限,单位为秒(s) + /// + public const uint JT808_0x8103_0x0057_Type = 0x0057; + /// + /// 当天累计驾驶时间门限,单位为秒(s) + /// + public const uint JT808_0x8103_0x0058_Type = 0x0058; + /// + /// 最小休息时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x0059_Type = 0x0059; + /// + /// 最长停车时间,单位为秒(s) + /// + public const uint JT808_0x8103_0x005A_Type = 0x005A; + /// + /// 超速报警预警差值,单位为 1/10Km/h + /// + public const uint JT808_0x8103_0x005B_Type = 0x005B; + /// + /// 疲劳驾驶预警差值,单位为秒(s),>0 + /// + public const uint JT808_0x8103_0x005C_Type = 0x005C; + /// + /// 碰撞报警参数设置 + /// b7-b0: 碰撞时间,单位 4ms; + /// b15-b8:碰撞加速度,单位 0.1g,设置范围在:0-79 之间,默认为10。 + /// + public const uint JT808_0x8103_0x005D_Type = 0x005D; + /// + /// 侧翻报警参数设置: + /// 侧翻角度,单位 1 度,默认为 30 度 + /// + public const uint JT808_0x8103_0x005E_Type = 0x005E; + /// + /// 定时拍照控制,见 表 13 + /// + public const uint JT808_0x8103_0x0064_Type = 0x0064; + /// + /// 定距拍照控制,见 表 14 + /// + public const uint JT808_0x8103_0x0065_Type = 0x0065; + /// + /// 图像/视频质量,1-10,1 最好 + /// + public const uint JT808_0x8103_0x0070_Type = 0x0070; + /// + /// 亮度,0-255 + /// + public const uint JT808_0x8103_0x0071_Type = 0x0071; + /// + /// 对比度,0-127 + /// + public const uint JT808_0x8103_0x0072_Type = 0x0072; + /// + /// 饱和度,0-127 + /// + public const uint JT808_0x8103_0x0073_Type = 0x0073; + /// + /// 色度,0-255 + /// + public const uint JT808_0x8103_0x0074_Type = 0x0074; + /// + /// 车辆里程表读数,1/10km + /// + public const uint JT808_0x8103_0x0080_Type = 0x0080; + /// + /// 车辆所在的省域 ID + /// + public const uint JT808_0x8103_0x0081_Type = 0x0081; + /// + /// 车辆所在的市域 ID + /// + public const uint JT808_0x8103_0x0082_Type = 0x0082; + /// + /// 公安交通管理部门颁发的机动车号牌 + /// + public const uint JT808_0x8103_0x0083_Type = 0x0083; + /// + /// 车牌颜色,按照 JT/T415-2006 的 5.4.12 + /// + public const uint JT808_0x8103_0x0084_Type = 0x0084; + /// + /// GNSS 定位模式,定义如下: + /// bit0,0:禁用 GPS 定位, 1:启用 GPS 定位; + /// bit1,0:禁用北斗定位, 1:启用北斗定位; + /// bit2,0:禁用 GLONASS 定位, 1:启用 GLONASS 定位; + /// bit3,0:禁用 Galileo 定位, 1:启用 Galileo 定位。 + /// + public const uint JT808_0x8103_0x0090_Type = 0x0090; + /// + /// GNSS 波特率,定义如下: + /// 0x00:4800;0x01:9600; + /// 0x02:19200;0x03:38400; + /// 0x04:57600;0x05:115200。 + /// + public const uint JT808_0x8103_0x0091_Type = 0x0091; + /// + /// GNSS 模块详细定位数据输出频率,定义如下: + /// 0x00:500ms;0x01:1000ms(默认值); + /// 0x02:2000ms;0x03:3000ms; + /// 0x04:4000ms。 + /// + public const uint JT808_0x8103_0x0092_Type = 0x0092; + /// + /// GNSS 模块详细定位数据采集频率,单位为秒,默认为 1。 + /// + public const uint JT808_0x8103_0x0093_Type = 0x0093; + /// + /// GNSS 模块详细定位数据上传方式 + /// 0x00,本地存储,不上传(默认值); + /// 0x01,按时间间隔上传; + /// 0x02,按距离间隔上传; + /// 0x0B,按累计时间上传,达到传输时间后自动停止上传; + /// 0x0C,按累计距离上传,达到距离后自动停止上传; + /// 0x0D,按累计条数上传,达到上传条数后自动停止上传。 + /// + public const uint JT808_0x8103_0x0094_Type = 0x0094; + /// + /// GNSS 模块详细定位数据上传设置: + /// 上传方式为 0x01 时,单位为秒; + /// 上传方式为 0x02 时,单位为米; + /// 上传方式为 0x0B 时,单位为秒; + /// 上传方式为 0x0C 时,单位为米; + /// 上传方式为 0x0D 时,单位为条。 + /// + public const uint JT808_0x8103_0x0095_Type = 0x0095; + /// + /// CAN 总线通道 1 采集时间间隔(ms),0 表示不采集 + /// + public const uint JT808_0x8103_0x0100_Type = 0x0100; + /// + /// CAN 总线通道 1 上传时间间隔(s),0 表示不上传 + /// + public const uint JT808_0x8103_0x0101_Type = 0x0101; + /// + /// CAN 总线通道 2 采集时间间隔(ms),0 表示不采集 + /// + public const uint JT808_0x8103_0x0102_Type = 0x0102; + /// + /// CAN 总线通道 2 上传时间间隔(s),0 表示不上传 + /// + public const uint JT808_0x8103_0x0103_Type = 0x0103; + /// + /// CAN 总线 ID 单独采集设置: + /// bit63-bit32 表示此 ID 采集时间间隔(ms),0 表示不采集; + /// bit31 表示 CAN 通道号,0:CAN1,1:CAN2; + /// bit30 表示帧类型,0:标准帧,1:扩展帧; + /// bit29 表示数据采集方式,0:原始数据,1:采集区间的计算值; + /// bit28-bit0 表示 CAN 总线 ID。 + /// + public const uint JT808_0x8103_0x0110_Type = 0x0110; + + public static IDictionary JT808_0x8103Method { get; private set; } + /// + /// 参数 ID + /// + public abstract uint ParamId { get; set; } + + /// + /// 参数长度 + /// + public abstract byte ParamLength { get; set; } + + static JT808_0x8103_BodyBase() + { + JT808_0x8103Method = new Dictionary + { + { JT808_0x8103_0x0001_Type, typeof(JT808_0x8103_0x0001) }, + { JT808_0x8103_0x0002_Type, typeof(JT808_0x8103_0x0002) }, + { JT808_0x8103_0x0003_Type, typeof(JT808_0x8103_0x0003) }, + { JT808_0x8103_0x0004_Type, typeof(JT808_0x8103_0x0004) }, + { JT808_0x8103_0x0005_Type, typeof(JT808_0x8103_0x0005) }, + { JT808_0x8103_0x0006_Type, typeof(JT808_0x8103_0x0006) }, + { JT808_0x8103_0x0007_Type, typeof(JT808_0x8103_0x0007) }, + { JT808_0x8103_0x0010_Type, typeof(JT808_0x8103_0x0010) }, + { JT808_0x8103_0x0011_Type, typeof(JT808_0x8103_0x0011) }, + { JT808_0x8103_0x0012_Type, typeof(JT808_0x8103_0x0012) }, + { JT808_0x8103_0x0013_Type, typeof(JT808_0x8103_0x0013) }, + { JT808_0x8103_0x0014_Type, typeof(JT808_0x8103_0x0014) }, + { JT808_0x8103_0x0015_Type, typeof(JT808_0x8103_0x0015) }, + { JT808_0x8103_0x0016_Type, typeof(JT808_0x8103_0x0016) }, + { JT808_0x8103_0x0017_Type, typeof(JT808_0x8103_0x0017) }, + { JT808_0x8103_0x0018_Type, typeof(JT808_0x8103_0x0018) }, + { JT808_0x8103_0x0019_Type, typeof(JT808_0x8103_0x0019) }, + { JT808_0x8103_0x001A_Type, typeof(JT808_0x8103_0x001A) }, + { JT808_0x8103_0x001B_Type, typeof(JT808_0x8103_0x001B) }, + { JT808_0x8103_0x001C_Type, typeof(JT808_0x8103_0x001C) }, + { JT808_0x8103_0x001D_Type, typeof(JT808_0x8103_0x001D) }, + { JT808_0x8103_0x0020_Type, typeof(JT808_0x8103_0x0020) }, + { JT808_0x8103_0x0021_Type, typeof(JT808_0x8103_0x0021) }, + { JT808_0x8103_0x0022_Type, typeof(JT808_0x8103_0x0022) }, + { JT808_0x8103_0x0027_Type, typeof(JT808_0x8103_0x0027) }, + { JT808_0x8103_0x0028_Type, typeof(JT808_0x8103_0x0028) }, + { JT808_0x8103_0x0029_Type, typeof(JT808_0x8103_0x0029) }, + { JT808_0x8103_0x002C_Type, typeof(JT808_0x8103_0x002C) }, + { JT808_0x8103_0x002D_Type, typeof(JT808_0x8103_0x002D) }, + { JT808_0x8103_0x002E_Type, typeof(JT808_0x8103_0x002E) }, + { JT808_0x8103_0x002F_Type, typeof(JT808_0x8103_0x002F) }, + { JT808_0x8103_0x0030_Type, typeof(JT808_0x8103_0x0030) }, + { JT808_0x8103_0x0031_Type, typeof(JT808_0x8103_0x0031) }, + { JT808_0x8103_0x0040_Type, typeof(JT808_0x8103_0x0040) }, + { JT808_0x8103_0x0041_Type, typeof(JT808_0x8103_0x0041) }, + { JT808_0x8103_0x0042_Type, typeof(JT808_0x8103_0x0042) }, + { JT808_0x8103_0x0043_Type, typeof(JT808_0x8103_0x0043) }, + { JT808_0x8103_0x0044_Type, typeof(JT808_0x8103_0x0044) }, + { JT808_0x8103_0x0045_Type, typeof(JT808_0x8103_0x0045) }, + { JT808_0x8103_0x0046_Type, typeof(JT808_0x8103_0x0046) }, + { JT808_0x8103_0x0047_Type, typeof(JT808_0x8103_0x0047) }, + { JT808_0x8103_0x0048_Type, typeof(JT808_0x8103_0x0048) }, + { JT808_0x8103_0x0049_Type, typeof(JT808_0x8103_0x0049) }, + { JT808_0x8103_0x0050_Type, typeof(JT808_0x8103_0x0050) }, + { JT808_0x8103_0x0051_Type, typeof(JT808_0x8103_0x0051) }, + { JT808_0x8103_0x0052_Type, typeof(JT808_0x8103_0x0052) }, + { JT808_0x8103_0x0053_Type, typeof(JT808_0x8103_0x0053) }, + { JT808_0x8103_0x0054_Type, typeof(JT808_0x8103_0x0054) }, + { JT808_0x8103_0x0055_Type, typeof(JT808_0x8103_0x0055) }, + { JT808_0x8103_0x0056_Type, typeof(JT808_0x8103_0x0056) }, + { JT808_0x8103_0x0057_Type, typeof(JT808_0x8103_0x0057) }, + { JT808_0x8103_0x0058_Type, typeof(JT808_0x8103_0x0058) }, + { JT808_0x8103_0x0059_Type, typeof(JT808_0x8103_0x0059) }, + { JT808_0x8103_0x005A_Type, typeof(JT808_0x8103_0x005A) }, + { JT808_0x8103_0x005B_Type, typeof(JT808_0x8103_0x005B) }, + { JT808_0x8103_0x005C_Type, typeof(JT808_0x8103_0x005C) }, + { JT808_0x8103_0x005D_Type, typeof(JT808_0x8103_0x005D) }, + { JT808_0x8103_0x005E_Type, typeof(JT808_0x8103_0x005E) }, + { JT808_0x8103_0x0064_Type, typeof(JT808_0x8103_0x0064) }, + { JT808_0x8103_0x0065_Type, typeof(JT808_0x8103_0x0065) }, + { JT808_0x8103_0x0070_Type, typeof(JT808_0x8103_0x0070) }, + { JT808_0x8103_0x0071_Type, typeof(JT808_0x8103_0x0081) }, + { JT808_0x8103_0x0072_Type, typeof(JT808_0x8103_0x0072) }, + { JT808_0x8103_0x0073_Type, typeof(JT808_0x8103_0x0073) }, + { JT808_0x8103_0x0074_Type, typeof(JT808_0x8103_0x0074) }, + { JT808_0x8103_0x0080_Type, typeof(JT808_0x8103_0x0080) }, + { JT808_0x8103_0x0081_Type, typeof(JT808_0x8103_0x0081) }, + { JT808_0x8103_0x0082_Type, typeof(JT808_0x8103_0x0082) }, + { JT808_0x8103_0x0083_Type, typeof(JT808_0x8103_0x0083) }, + { JT808_0x8103_0x0084_Type, typeof(JT808_0x8103_0x0084) }, + { JT808_0x8103_0x0090_Type, typeof(JT808_0x8103_0x0090) }, + { JT808_0x8103_0x0091_Type, typeof(JT808_0x8103_0x0091) }, + { JT808_0x8103_0x0092_Type, typeof(JT808_0x8103_0x0092) }, + { JT808_0x8103_0x0093_Type, typeof(JT808_0x8103_0x0093) }, + { JT808_0x8103_0x0094_Type, typeof(JT808_0x8103_0x0094) }, + { JT808_0x8103_0x0095_Type, typeof(JT808_0x8103_0x0095) }, + { JT808_0x8103_0x0100_Type, typeof(JT808_0x8103_0x0100) }, + { JT808_0x8103_0x0101_Type, typeof(JT808_0x8103_0x0101) }, + { JT808_0x8103_0x0102_Type, typeof(JT808_0x8103_0x0102) }, + { JT808_0x8103_0x0103_Type, typeof(JT808_0x8103_0x0103) }, + { JT808_0x8103_0x0110_Type, typeof(JT808_0x8103_0x0110) } + }; + } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8103_CustomBodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x8103_CustomBodyBase.cs new file mode 100644 index 0000000..3617b12 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8103_CustomBodyBase.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + public abstract class JT808_0x8103_CustomBodyBase + { + /// + /// 参数 ID + /// + public abstract uint ParamId { get; set; } + + /// + /// 参数长度 + /// + public abstract byte ParamLength { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8104.cs b/src/JT808.Protocol/MessageBody/JT808_0x8104.cs new file mode 100644 index 0000000..5057bc9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8104.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 查询终端参数 + /// + public class JT808_0x8104 : JT808Bodies + { + /// + /// 跳过数据体序列化 + /// + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8105.cs b/src/JT808.Protocol/MessageBody/JT808_0x8105.cs new file mode 100644 index 0000000..669e2ef --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8105.cs @@ -0,0 +1,153 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 终端控制 + /// + [JT808Formatter(typeof(JT808_0x8105_Formatter))] + public class JT808_0x8105 : JT808Bodies + { + /// + /// 命令字 + /// + public byte CommandWord { get; set; } + /// + /// 命令参数 + /// + public CommandParams CommandValue { get; set; } + } + /// + /// 命令参数 + /// + public class CommandParams + { + /// + /// 连接控制 + /// 0:切换到指定监管平台服务器,连接到该服务器后即进入应急状态, + ///此状态下仅有下发控制指令的监管平台可发送包括短信在内的控制指令; + ///1:切换回原缺省监控平台服务器,并恢复正常状态。 + /// + public byte? ConnectionControl { get; set; } + /// + /// 拨号点名称 + /// 一般为服务器 APN,无线通信拨号访问点,若网络制式为 CDMA,则该值为 PPP 连接拨号号码 + /// + public string DialPointName { get; set; } + /// + /// 拨号用户名 + /// 服务器无线通信拨号用户名 + /// + public string DialUserName { get; set; } + /// + /// 拨号密码 + /// 服务器无线通信拨号密码 + /// + public string DialPwd { get; set; } + /// + /// 服务器地址 + /// 服务器地址;IP 或域名 + /// + public string ServerUrl { get; set; } + /// + /// TCP端口 + /// + public UInt16? TCPPort { get; set; } + /// + /// UDP端口 + /// + public UInt16? UDPPort { get; set; } + /// + /// 制造商 ID BYTE[5] + /// 终端制造商编码 + /// + public long? ManufacturerCode { get; set; } + /// + /// 监管平台鉴权码 + /// 监管平台下发的鉴权码,仅用于终端连接到监管平台之后的鉴权,终端连接回原监控平台还用原鉴权码 + /// + public string MonitoringPlatformAuthenticationCode { get; set; } + /// + /// 硬件版本 + /// 终端的硬件版本号,由制造商自定 + /// + public string HardwareVersion { get; set; } + /// + /// 固件版本 + /// 终端的固件版本号,由制造商自定 + /// + public string FirmwareVersion { get; set; } + /// + /// URL 地址 完整 URL 地址 + /// + public string URL { get; set; } + /// + /// 连接到指定服务器时限 + /// 单位:分(min),值非 0 后的有效期截止前,终端应连回原地址。 + /// 若值为 0,则表示一直连接指 定服务器 + /// + public UInt16? ConnectTimeLimit { get; set; } + public override string ToString() + { + return $"{ConnectionControl};{DialPointName};{DialUserName};{DialPwd};{ServerUrl};{TCPPort};{UDPPort};{ManufacturerCode};{MonitoringPlatformAuthenticationCode};{HardwareVersion};{FirmwareVersion};{URL};{ConnectTimeLimit}"; + } + public void SetCommandParams(string commandValue) + { + var values = commandValue.Split(';'); + if (!string.IsNullOrEmpty(values[0])) + { + ConnectionControl = byte.Parse(values[0]); + } + if (!string.IsNullOrEmpty(values[1])) + { + DialPointName = values[1]; + } + if (!string.IsNullOrEmpty(values[2])) + { + DialUserName = values[2]; + } + if (!string.IsNullOrEmpty(values[3])) + { + DialPwd = values[3]; + } + if (!string.IsNullOrEmpty(values[4])) + { + ServerUrl = values[4]; + } + if (!string.IsNullOrEmpty(values[5])) + { + TCPPort = UInt16.Parse(values[5]); + } + if (!string.IsNullOrEmpty(values[6])) + { + UDPPort = UInt16.Parse(values[6]); + } + if (!string.IsNullOrEmpty(values[7])) + { + ManufacturerCode = long.Parse(values[7]); + } + if (!string.IsNullOrEmpty(values[8])) + { + MonitoringPlatformAuthenticationCode = values[8]; + } + if (!string.IsNullOrEmpty(values[9])) + { + HardwareVersion = values[9]; + } + if (!string.IsNullOrEmpty(values[10])) + { + FirmwareVersion = values[10]; + } + if (!string.IsNullOrEmpty(values[11])) + { + URL = values[11]; + } + if (!string.IsNullOrEmpty(values[12])) + { + ConnectTimeLimit = UInt16.Parse(values[12]); + } + } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8106.cs b/src/JT808.Protocol/MessageBody/JT808_0x8106.cs new file mode 100644 index 0000000..960ab48 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8106.cs @@ -0,0 +1,25 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 查询指定终端参数 + /// 0x8106 + /// + [JT808Formatter(typeof(JT808_0x8106_Formatter))] + public class JT808_0x8106 : JT808Bodies + { + /// + /// 参数总数 + /// 参数总数为 n + /// + public byte ParameterCount { get; set; } + /// + /// 参数 ID 列表 + /// 参数顺序排列,如“参数 ID1 参数 ID2......参数IDn”。 + /// + public UInt32[] Parameters { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8107.cs b/src/JT808.Protocol/MessageBody/JT808_0x8107.cs new file mode 100644 index 0000000..7664602 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8107.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 查询终端属性 + /// + public class JT808_0x8107 : JT808Bodies + { + /// + /// 跳过数据体序列化 + /// + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8108.cs b/src/JT808.Protocol/MessageBody/JT808_0x8108.cs new file mode 100644 index 0000000..350cdfc --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8108.cs @@ -0,0 +1,39 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 下发终端升级包 + /// + [JT808Formatter(typeof(JT808_0x8108_Formatter))] + public class JT808_0x8108 : JT808Bodies + { + /// + /// 升级类型 + /// + public JT808UpgradeType UpgradeType { get; set; } + /// + /// 制造商 ID + /// 5 个字节,终端制造商编码 + /// + public string MakerId { get; set; } + /// + /// 版本号长度 + /// + public byte VersionNumLength { get; set; } + /// + /// 版本号 + /// + public string VersionNum { get; set; } + /// + /// 升级数据包长度 + /// + public int UpgradePackageLength { get; set; } + /// + /// 升级数据包 + /// + public byte[] UpgradePackage { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8201.cs b/src/JT808.Protocol/MessageBody/JT808_0x8201.cs new file mode 100644 index 0000000..201f00e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8201.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 位置信息查询 + /// + public class JT808_0x8201: JT808Bodies + { + /// + /// 跳过数据体序列化 + /// + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8202.cs b/src/JT808.Protocol/MessageBody/JT808_0x8202.cs new file mode 100644 index 0000000..f78630b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8202.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 临时位置跟踪控制 + /// + [JT808Formatter(typeof(JT808_0x8202_Formatter))] + public class JT808_0x8202 : JT808Bodies + { + /// + /// 时间间隔 + /// 单位为秒(s),0 则停止跟踪。停止跟踪无需带后继字段 + /// + public ushort Interval { get; set; } + + /// + /// 位置跟踪有效期 + /// 单位为秒(s),终端在接收到位置跟踪控制消息后,在有效期截止时间之前,依据消息中的时间间隔发送位置汇报 + /// + public int LocationTrackingValidity { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8203.cs b/src/JT808.Protocol/MessageBody/JT808_0x8203.cs new file mode 100644 index 0000000..7392ee8 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8203.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 人工确认报警消息 + /// 0x8203 + /// + [JT808Formatter(typeof(JT808_0x8203_Formatter))] + public class JT808_0x8203 : JT808Bodies + { + /// + /// 报警消息流水号 + /// 需人工确认的报警消息流水号,0 表示该报警类型所有消息 + /// + public ushort AlarmMsgNum { get; set; } + /// + /// 人工确认报警类型 + /// + public uint ManualConfirmAlarmType { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8300.cs b/src/JT808.Protocol/MessageBody/JT808_0x8300.cs new file mode 100644 index 0000000..338553b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8300.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 文本信息下发 + /// + [JT808Formatter(typeof(JT808_0x8300_Formatter))] + public class JT808_0x8300 : JT808Bodies + { + /// + /// 文本信息标志位含义见 表 38 + /// + public byte TextFlag { get; set; } + + /// + /// 文本信息 + /// 最长为 1024 字节,经GBK编码 + /// + public string TextInfo { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8301.cs b/src/JT808.Protocol/MessageBody/JT808_0x8301.cs new file mode 100644 index 0000000..bdf8e82 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8301.cs @@ -0,0 +1,29 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 事件设置 + /// 0x8301 + /// + [JT808Formatter(typeof(JT808_0x8301_Formatter))] + public class JT808_0x8301 : JT808Bodies + { + /// + /// 设置类型 + /// + /// + public byte SettingType { get; set; } + /// + /// 设置总数 + /// + public byte SettingCount { get; set; } + /// + /// 事件项 + /// + public List EventItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8302.cs b/src/JT808.Protocol/MessageBody/JT808_0x8302.cs new file mode 100644 index 0000000..f921f8f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8302.cs @@ -0,0 +1,42 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 提问下发 + /// 0x8302 + /// + [JT808Formatter(typeof(JT808_0x8302_Formatter))] + public class JT808_0x8302 : JT808Bodies + { + /// + /// 标志 + /// 提问下发标志位定义 + /// + public byte Flag { get; set; } + /// + /// 问题内容长度 + /// + public byte IssueContentLength { get; set; } + /// + /// 问题 + /// 问题文本,经 GBK 编码,长度为 N + /// + public string Issue { get; set; } + /// + /// 答案 ID + /// + public byte AnswerId { get; set; } + /// + /// 答案内容长度 + /// 答案内容字段字节长度 + /// + public ushort AnswerContentLength { get; set; } + /// + /// 答案内容 + /// 答案内容,经 GBK 编码 + /// + public string AnswerContent { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8303.cs b/src/JT808.Protocol/MessageBody/JT808_0x8303.cs new file mode 100644 index 0000000..02601a9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8303.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 信息点播菜单设置 + /// 0x8303 + /// + [JT808Formatter(typeof(JT808_0x8303_Formatter))] + public class JT808_0x8303 : JT808Bodies + { + /// + /// 设置类型 + /// + /// + public byte SettingType { get; set; } + /// + /// 信息项总数 + /// + public byte InformationItemCount { get; set; } + /// + /// 信息点播信息项组成数据 + /// 信息项列表 + /// + public List InformationItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8304.cs b/src/JT808.Protocol/MessageBody/JT808_0x8304.cs new file mode 100644 index 0000000..56bfde9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8304.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 信息服务 + /// 0x8304 + /// + [JT808Formatter(typeof(JT808_0x8304_Formatter))] + public class JT808_0x8304 : JT808Bodies + { + /// + /// 信息类型 + /// + public byte InformationType { get; set; } + /// + /// 信息长度 + /// + public ushort InformationLength { get; set; } + /// + /// 信息内容 + /// 经 GBK 编码 + /// + public string InformationContent { get; set; } + + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8400.cs b/src/JT808.Protocol/MessageBody/JT808_0x8400.cs new file mode 100644 index 0000000..40dc535 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8400.cs @@ -0,0 +1,23 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 电话回拨 + /// + [JT808Formatter(typeof(JT808_0x8400_Formatter))] + public class JT808_0x8400 : JT808Bodies + { + /// + /// 0:普通通话;1:监听 + /// + public JT808CallBackType CallBack { get; set; } + /// + /// 电话号码 + /// 最长为 20 字节 + /// + public string PhoneNumber { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8401.cs b/src/JT808.Protocol/MessageBody/JT808_0x8401.cs new file mode 100644 index 0000000..6c5790e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8401.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置电话本 + /// + [JT808Formatter(typeof(JT808_0x8401_Formatter))] + public class JT808_0x8401 : JT808Bodies + { + /// + /// 设置类型 + /// + public JT808SettingTelephoneBook SettingTelephoneBook { get; set; } + /// + /// 联系人总数 + /// + public byte ContactCount { get; set; } + /// + /// 联系人项 + /// + public IList JT808ContactProperties { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8500.cs b/src/JT808.Protocol/MessageBody/JT808_0x8500.cs new file mode 100644 index 0000000..bc70231 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8500.cs @@ -0,0 +1,20 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 车辆控制 + /// + [JT808Formatter(typeof(JT808_0x8500_Formatter))] + public class JT808_0x8500 : JT808Bodies + { + /// + /// 控制标志 + /// 控制指令标志位数据格式 + /// 0:车门解锁;1:车门加锁 + /// 1-7 保留 + /// + public byte ControlFlag { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8600.cs b/src/JT808.Protocol/MessageBody/JT808_0x8600.cs new file mode 100644 index 0000000..4ca1a6b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8600.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置圆形区域 + /// 0x8600 + /// 注:本条消息协议支持周期时间范围,如要限制每天的8:30-18:00,起始/结束时间设为:00-00-00-08-30-00/00-00-00-18-00-00,其他以此类推 + /// + [JT808Formatter(typeof(JT808_0x8600_Formatter))] + public class JT808_0x8600 : JT808Bodies + { + /// + /// 设置属性 + /// + /// + public byte SettingAreaProperty { get; set; } + /// + /// 区域总数 + /// + public byte AreaCount { get; set; } + /// + /// 区域项 + /// + public List AreaItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8601.cs b/src/JT808.Protocol/MessageBody/JT808_0x8601.cs new file mode 100644 index 0000000..260d07f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8601.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 删除圆形区域 + /// 0x8601 + /// + [JT808Formatter(typeof(JT808_0x8601_Formatter))] + public class JT808_0x8601 : JT808Bodies + { + /// + /// 区域数 + /// 本条消息中包含的区域数,不超过 125 个,多于 125个建议用多条消息,0 为删除所有圆形区域 + /// + public byte AreaCount { get; set; } + /// + /// 区域ID集合 + /// + public List AreaIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8602.cs b/src/JT808.Protocol/MessageBody/JT808_0x8602.cs new file mode 100644 index 0000000..c5d9626 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8602.cs @@ -0,0 +1,30 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置矩形区域 + /// 0x8602 + /// + [JT808Formatter(typeof(JT808_0x8602_Formatter))] + public class JT808_0x8602 : JT808Bodies + { + /// + /// 设置属性 + /// + /// + public byte SettingAreaProperty { get; set; } + /// + /// 区域总数 + /// + public byte AreaCount { get; set; } + /// + /// 区域项 + /// + public List AreaItems { get; set; } + + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8603.cs b/src/JT808.Protocol/MessageBody/JT808_0x8603.cs new file mode 100644 index 0000000..f1041a2 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8603.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 删除矩形区域 + /// 0x8603 + /// + [JT808Formatter(typeof(JT808_0x8603_Formatter))] + public class JT808_0x8603 : JT808Bodies + { + /// + /// 区域数 + /// 本条消息中包含的区域数,不超过 125 个,多于 125个建议用多条消息,0 为删除所有圆形区域 + /// + public byte AreaCount { get; set; } + /// + /// 区域ID集合 + /// + public List AreaIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8604.cs b/src/JT808.Protocol/MessageBody/JT808_0x8604.cs new file mode 100644 index 0000000..217f1f8 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8604.cs @@ -0,0 +1,54 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置多边形区域 + /// 0x8604 + /// + [JT808Formatter(typeof(JT808_0x8604_Formatter))] + public class JT808_0x8604 : JT808Bodies + { + /// + /// 区域 ID + /// + public uint AreaId { get; set; } + /// + /// 区域属性 + /// + /// + public ushort AreaProperty { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? EndTime { get; set; } + /// + /// 最高速度 + /// Km/h,若区域属性 1 位为 0 则没有该字段 + /// + public ushort? HighestSpeed { get; set; } + /// + /// 超速持续时间 + /// 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 + /// + public byte? OverspeedDuration { get; set; } + /// + /// 区域总顶点数 + /// + public ushort PeakCount { get; set; } + /// + /// 顶点项 + /// + public List PeakItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8605.cs b/src/JT808.Protocol/MessageBody/JT808_0x8605.cs new file mode 100644 index 0000000..6b98c1b --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8605.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 删除多边形区域 + /// 0x8605 + /// + [JT808Formatter(typeof(JT808_0x8605_Formatter))] + public class JT808_0x8605 : JT808Bodies + { + /// + /// 区域数 + /// 本条消息中包含的区域数,不超过 125 个,多于 125个建议用多条消息,0 为删除所有圆形区域 + /// + public byte AreaCount { get; set; } + /// + /// 区域ID集合 + /// + public List AreaIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8606.cs b/src/JT808.Protocol/MessageBody/JT808_0x8606.cs new file mode 100644 index 0000000..976c61d --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8606.cs @@ -0,0 +1,44 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using JT808.Protocol.Metadata; +using System; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 设置路线 + /// 0x8606 + /// + [JT808Formatter(typeof(JT808_0x8606_Formatter))] + public class JT808_0x8606 : JT808Bodies + { + /// + /// 路线 ID + /// + public uint RouteId { get; set; } + /// + /// 路线属性 + /// 路线属性数据格式见 表 67 + /// + public ushort RouteProperty { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? EndTime { get; set; } + /// + /// 路线总拐点数 + /// + public ushort InflectionPointCount { get; set; } + /// + /// 拐点项 + /// + public List InflectionPointItems { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8607.cs b/src/JT808.Protocol/MessageBody/JT808_0x8607.cs new file mode 100644 index 0000000..d6f506f --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8607.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System.Collections.Generic; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 删除路线 + /// 0x8607 + /// + [JT808Formatter(typeof(JT808_0x8607_Formatter))] + public class JT808_0x8607 : JT808Bodies + { + /// + /// 区域数 + /// 本条消息中包含的区域数,不超过 125 个,多于 125个建议用多条消息,0 为删除所有圆形区域 + /// + public byte AreaCount { get; set; } + /// + /// 区域ID集合 + /// + public List AreaIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8702.cs b/src/JT808.Protocol/MessageBody/JT808_0x8702.cs new file mode 100644 index 0000000..df6eb07 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8702.cs @@ -0,0 +1,13 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 上报驾驶员身份信息请求 + /// + public class JT808_0x8702 : JT808Bodies + { + /// + /// 跳过数据体序列化 + /// + public override bool SkipSerialization { get; set; } = true; + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8800.cs b/src/JT808.Protocol/MessageBody/JT808_0x8800.cs new file mode 100644 index 0000000..6f3d3e0 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8800.cs @@ -0,0 +1,27 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 多媒体数据上传应答 + /// 0x8800 + /// + [JT808Formatter(typeof(JT808_0x8800_Formatter))] + public class JT808_0x8800 : JT808Bodies + { + /// + /// 多媒体ID + /// + public uint MultimediaId { get; set; } + /// + /// 重传包总数 + /// + public byte RetransmitPackageCount { get; set; } + /// + /// 重传包 ID 列表 + /// 重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。 + /// + public byte[] RetransmitPackageIds { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8801.cs b/src/JT808.Protocol/MessageBody/JT808_0x8801.cs new file mode 100644 index 0000000..f061c89 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8801.cs @@ -0,0 +1,70 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 摄像头立即拍摄命令 + /// 0x8801 + /// + [JT808Formatter(typeof(JT808_0x8801_Formatter))] + public class JT808_0x8801 : JT808Bodies + { + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + /// + /// 拍摄命令 + /// 0 表示停止拍摄;0xFFFF 表示录像;其它表示拍照张数 + /// + public ushort ShootingCommand { get; set; } + /// + /// 拍照间隔/录像时间 + /// 秒,0 表示按最小间隔拍照或一直录像 + /// + public ushort VideoTime { get; set; } + /// + /// 保存标志 + /// 1:保存;0:实时上传 + /// + public byte SaveFlag { get; set; } + /// + /// 分辨率 + /// 0x01:320*240; + /// 0x02:640*480; + /// 0x03:800*600; + /// 0x04:1024*768; + /// 0x05:176*144;[Qcif]; + /// 0x06:352*288;[Cif]; + /// 0x07:704*288;[HALF D1]; + /// 0x08:704*576;[D1]; + /// + public byte Resolution { get; set; } + /// + /// 图像/视频质量 + /// 1-10,1 代表质量损失最小,10 表示压缩比最大 + /// + public byte VideoQuality { get; set; } + /// + /// 亮度 + /// 0-255 + /// + public byte Lighting { get; set; } + /// + /// 对比度 + /// 0-127 + /// + public byte Contrast { get; set; } + /// + /// 饱和度 + /// 0-127 + /// + public byte Saturability { get; set; } + /// + /// 色度 + /// 0-255 + /// + public byte Chroma { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8802.cs b/src/JT808.Protocol/MessageBody/JT808_0x8802.cs new file mode 100644 index 0000000..27b5231 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8802.cs @@ -0,0 +1,40 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 存储多媒体数据检索 + /// 0x8802 + /// + [JT808Formatter(typeof(JT808_0x8802_Formatter))] + public class JT808_0x8802 : JT808Bodies + { + /// + /// 多媒体类型 + /// + /// + public byte MultimediaType { get; set; } + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + /// + /// 事件项编码 + /// + /// 0:平台下发指令;1:定时动作;2:抢劫报警触发;3:碰撞侧翻报警触发;其他保留 + /// + public byte EventItemCoding { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss + /// + public DateTime StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss + /// + public DateTime EndTime { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8803.cs b/src/JT808.Protocol/MessageBody/JT808_0x8803.cs new file mode 100644 index 0000000..2fe7a1e --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8803.cs @@ -0,0 +1,46 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; +using System; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 存储多媒体数据上传命令 + /// 0x8803 + /// + [JT808Formatter(typeof(JT808_0x8803_Formatter))] + public class JT808_0x8803 : JT808Bodies + { + /// + /// 多媒体类型 + /// + /// 0:图像;1:音频;2:视频 + /// + public byte MultimediaType { get; set; } + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + /// + /// 事件项编码 + /// + /// 0:平台下发指令;1:定时动作;2:抢劫报警触发;3:碰撞侧翻报警触发;其他保留 + /// + public byte EventItemCoding { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss + /// + public DateTime StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss + /// + public DateTime EndTime { get; set; } + /// + /// 删除标志 + /// + /// + public byte MultimediaDeleted { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8804.cs b/src/JT808.Protocol/MessageBody/JT808_0x8804.cs new file mode 100644 index 0000000..e1c9be0 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8804.cs @@ -0,0 +1,33 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 录音开始命令 + /// + [JT808Formatter(typeof(JT808_0x8804_Formatter))] + public class JT808_0x8804 : JT808Bodies + { + /// + /// 录音命令 + /// 0:停止录音;0x01:开始录音; + /// + public JT808RecordCmd RecordCmd { get; set; } + /// + /// 单位为秒(s),0 表示一直录音 + /// + public ushort RecordTime { get; set; } + /// + /// 保存标志 + /// 0:实时上传;1:保存 + /// + public JT808RecordSave RecordSave { get; set; } + /// + /// 音频采样率 + /// 0:8K;1:11K;2:23K;3:32K;其他保留 + /// + public byte AudioSampleRate { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8805.cs b/src/JT808.Protocol/MessageBody/JT808_0x8805.cs new file mode 100644 index 0000000..46cd5c9 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8805.cs @@ -0,0 +1,22 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 单条存储多媒体数据检索上传命令 + /// + [JT808Formatter(typeof(JT808_0x8805_Formatter))] + public class JT808_0x8805 : JT808Bodies + { + /// + /// 多媒体ID + /// + public uint MultimediaId { get; set; } + /// + /// 删除标志 + /// + /// + public byte MultimediaDeleted { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8900.cs b/src/JT808.Protocol/MessageBody/JT808_0x8900.cs new file mode 100644 index 0000000..baa03d6 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8900.cs @@ -0,0 +1,28 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 数据下行透传 + /// + [JT808Formatter(typeof(JT808_0x8900_Formatter))] + public class JT808_0x8900 : JT808Bodies + { + /// + /// 透传消息类型 + /// 透传消息类型定义见 表 93 + /// + public byte PassthroughType { get; set; } + + /// + /// 数据下行透传数据 + /// + public byte[] PassthroughData { get; set; } + + /// + /// 透传消息内容 + /// + public JT808_0x8900_BodyBase JT808_0X8900_BodyBase { get; set; } + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8900_BodyBase.cs b/src/JT808.Protocol/MessageBody/JT808_0x8900_BodyBase.cs new file mode 100644 index 0000000..9f62c87 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8900_BodyBase.cs @@ -0,0 +1,10 @@ +namespace JT808.Protocol.MessageBody +{ + /// + /// 数据下行透传 + /// + public abstract class JT808_0x8900_BodyBase + { + + } +} diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8A00.cs b/src/JT808.Protocol/MessageBody/JT808_0x8A00.cs new file mode 100644 index 0000000..2cc7739 --- /dev/null +++ b/src/JT808.Protocol/MessageBody/JT808_0x8A00.cs @@ -0,0 +1,24 @@ +using JT808.Protocol.Attributes; +using JT808.Protocol.Formatters.MessageBodyFormatters; + +namespace JT808.Protocol.MessageBody +{ + /// + /// 平台RSA公钥 + /// 0x8A00 + /// + [JT808Formatter(typeof(JT808_0x8A00_Formatter))] + public class JT808_0x8A00 : JT808Bodies + { + /// + /// e + /// 平台 RSA 公钥{e,n}中的 e + /// + public uint E { get; set; } + /// + /// n + /// RSA 公钥{e,n}中的 n + /// + public byte[] N { get; set; } + } +} diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs new file mode 100644 index 0000000..e41b59c --- /dev/null +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs @@ -0,0 +1,381 @@ +using JT808.Protocol.Buffers; +using JT808.Protocol.Extensions; +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + + +namespace JT808.Protocol.MessagePack +{ + public ref struct JT808MessagePackReader + { + public ReadOnlySpan Reader { get; private set; } + public ReadOnlySpan SrcBuffer { get; } + public int ReaderCount { get; private set; } + private byte _calculateCheckXorCode; + private byte _realCheckXorCode; + private bool _checkXorCodeVali; + /// + /// 是否进行解码操作 + /// 若进行解码操作,则对应的是一个正常的包 + /// 若不进行解码操作,则对应的是一个非正常的包(头部包,数据体包等等) + /// 主要用来一次性读取所有数据体内容操作 + /// + private bool _decoded; + private static byte[] decode7d01 = new byte[] { 0x7d, 0x01 }; + private static byte[] decode7d02 = new byte[] { 0x7d, 0x02 }; + /// + /// 解码(转义还原),计算校验和 + /// + /// + public JT808MessagePackReader(ReadOnlySpan srcBuffer) + { + SrcBuffer = srcBuffer; + ReaderCount = 0; + _realCheckXorCode = 0x00; + _calculateCheckXorCode = 0x00; + _checkXorCodeVali = false; + _decoded = false; + Reader = srcBuffer; + } + /// + /// 在解码的时候把校验和也计算出来,避免在循环一次进行校验 + /// + /// + public void Decode() + { + Span span = new byte[SrcBuffer.Length]; + Decode(span); + _decoded = true; + } + /// + /// 在解码的时候把校验和也计算出来,避免在循环一次进行校验 + /// + /// + public void Decode(Span allocateBuffer) + { + int i = 0; + int offset = 0; + int len = SrcBuffer.Length; + _realCheckXorCode = 0; + allocateBuffer[offset++] = SrcBuffer[0]; + // 取出校验码看是否需要转义 + ReadOnlySpan checkCodeBufferSpan = SrcBuffer.Slice(len - 3,2); + int checkCodeLen = 1; + if (checkCodeBufferSpan.SequenceEqual(decode7d01)) + { + _realCheckXorCode = 0x7d; + checkCodeLen += 1; + } + else if (checkCodeBufferSpan.SequenceEqual(decode7d02)) + { + _realCheckXorCode = 0x7e; + checkCodeLen += 1; + } + else + { + _realCheckXorCode = checkCodeBufferSpan[1]; + } + len = len - checkCodeLen - 1 - 1; + ReadOnlySpan tmpBufferSpan = SrcBuffer.Slice(1, len); + while (i < len) + { + if (tmpBufferSpan[i] == 0x7d) + { + if (len > i + 1) + { + if (tmpBufferSpan[i + 1] == 0x01) + { + allocateBuffer[offset++] = 0x7d; + _calculateCheckXorCode = (byte)(_calculateCheckXorCode ^ 0x7d); + i++; + } + else if (tmpBufferSpan[i + 1] == 0x02) + { + allocateBuffer[offset++] = 0x7e; + _calculateCheckXorCode = (byte)(_calculateCheckXorCode ^ 0x7e); + i++; + } + else + { + allocateBuffer[offset++] = tmpBufferSpan[i]; + _calculateCheckXorCode = (byte)(_calculateCheckXorCode ^ tmpBufferSpan[i]); + } + } + } + else + { + allocateBuffer[offset++] = tmpBufferSpan[i]; + _calculateCheckXorCode = (byte)(_calculateCheckXorCode ^ tmpBufferSpan[i]); + } + i++; + } + allocateBuffer[offset++] = _realCheckXorCode; + allocateBuffer[offset++] = SrcBuffer[SrcBuffer.Length- 1]; + _checkXorCodeVali = (_calculateCheckXorCode == _realCheckXorCode); + Reader = allocateBuffer.Slice(0, offset); + _decoded = true; + } + public byte CalculateCheckXorCode => _calculateCheckXorCode; + public byte RealCheckXorCode => _realCheckXorCode; + public bool CheckXorCodeVali => _checkXorCodeVali; + public byte ReadStart()=> ReadByte(); + public byte ReadEnd()=> ReadByte(); + public ushort ReadUInt16() + { + var readOnlySpan = GetReadOnlySpan(2); + ushort value = (ushort)((readOnlySpan[0] << 8) | (readOnlySpan[1])); + return value; + } + public uint ReadUInt32() + { + var readOnlySpan = GetReadOnlySpan(4); + uint value = (uint)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); + return value; + } + public int ReadInt32() + { + var readOnlySpan = GetReadOnlySpan(4); + int value = (int)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); + return value; + } + public ulong ReadUInt64() + { + var readOnlySpan = GetReadOnlySpan(8); + ulong value = (ulong)( + (readOnlySpan[0] << 56) | + (readOnlySpan[1] << 48) | + (readOnlySpan[2] << 40) | + (readOnlySpan[3] << 32) | + (readOnlySpan[4] << 24) | + (readOnlySpan[5] << 16) | + (readOnlySpan[6] << 8) | + readOnlySpan[7]); + return value; + } + public byte ReadByte() + { + var readOnlySpan = GetReadOnlySpan(1); + return readOnlySpan[0]; + } + public byte ReadVirtualByte() + { + var readOnlySpan = GetVirtualReadOnlySpan(1); + return readOnlySpan[0]; + } + public ushort ReadVirtualUInt16() + { + var readOnlySpan = GetVirtualReadOnlySpan(2); + return (ushort)((readOnlySpan[0] << 8) | (readOnlySpan[1])); + } + public uint ReadVirtualUInt32() + { + var readOnlySpan = GetVirtualReadOnlySpan(4); + return (uint)((readOnlySpan[0] << 24) | (readOnlySpan[1] << 16) | (readOnlySpan[2] << 8) | readOnlySpan[3]); + } + public ulong ReadVirtualUInt64() + { + var readOnlySpan = GetVirtualReadOnlySpan(8); + return (ulong)( + (readOnlySpan[0] << 56) | + (readOnlySpan[1] << 48) | + (readOnlySpan[2] << 40) | + (readOnlySpan[3] << 32) | + (readOnlySpan[4] << 24) | + (readOnlySpan[5] << 16) | + (readOnlySpan[6] << 8) | + readOnlySpan[7]); + } + + /// + /// 数字编码 大端模式、高位在前 + /// + /// + public string ReadBigNumber(int len) + { + ulong result = 0; + var readOnlySpan = GetReadOnlySpan(len); + for (int i = 0; i < len; i++) + { + ulong currentData = (ulong)readOnlySpan[i] << (8 * (len - i - 1)); + result += currentData; + } + return result.ToString(); + } + public ReadOnlySpan ReadArray(int len) + { + var readOnlySpan = GetReadOnlySpan(len); + return readOnlySpan.Slice(0, len); + } + public ReadOnlySpan ReadArray(int start,int end) + { + return Reader.Slice(start,end); + } + public string ReadString(int len) + { + var readOnlySpan = GetReadOnlySpan(len); + string value = JT808Constants.Encoding.GetString(readOnlySpan.Slice(0, len).ToArray()); + return value.Trim('\0'); + } + public string ReadRemainStringContent() + { + var readOnlySpan = ReadContent(0); + string value = JT808Constants.Encoding.GetString(readOnlySpan.ToArray()); + return value.Trim('\0'); + } + public string ReadHex(int len) + { + var readOnlySpan = GetReadOnlySpan(len); + string hex = HexUtil.DoHexDump(readOnlySpan, 0, len); + return hex; + } + /// + /// yyMMddHHmmss + /// + /// >D2: 10 X2:16 + public DateTime ReadDateTime6(string format = "X2") + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(6); + int year = Convert.ToInt32(readOnlySpan[0].ToString(format)) + JT808Constants.DateLimitYear; + int month = Convert.ToInt32(readOnlySpan[1].ToString(format)); + int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); + int hour = Convert.ToInt32(readOnlySpan[3].ToString(format)); + int minute = Convert.ToInt32(readOnlySpan[4].ToString(format)); + int second = Convert.ToInt32(readOnlySpan[5].ToString(format)); + d = new DateTime(year, month, day, hour, minute, second); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// + /// HH-mm-ss-msms + /// HH-mm-ss-fff + /// + /// D2: 10 X2:16 + public DateTime ReadDateTime5(string format = "X2") + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(5); + d = new DateTime( + DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + Convert.ToInt32(readOnlySpan[0].ToString(format)), + Convert.ToInt32(readOnlySpan[1].ToString(format)), + Convert.ToInt32(readOnlySpan[2].ToString(format)), + Convert.ToInt32(((readOnlySpan[3] << 8) + readOnlySpan[4]))); + } + catch + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// + /// YYYYMMDD + /// + /// D2: 10 X2:16 + public DateTime ReadDateTime4(string format = "X2") + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(4); + d = new DateTime( + (Convert.ToInt32(readOnlySpan[0].ToString(format)) << 8) + Convert.ToByte(readOnlySpan[1]), + Convert.ToInt32(readOnlySpan[2].ToString(format)), + Convert.ToInt32(readOnlySpan[3].ToString(format))); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + public DateTime ReadUTCDateTime() + { + DateTime d; + try + { + ulong result = 0; + var readOnlySpan = GetReadOnlySpan(8); + for (int i = 0; i < 8; i++) + { + ulong currentData = (ulong)readOnlySpan[i] << (8 * (8 - i - 1)); + result += currentData; + } + d = JT808Constants.UTCBaseTime.AddSeconds(result).AddHours(8); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + public string ReadBCD(int len) + { + int count = len / 2; + var readOnlySpan = GetReadOnlySpan(count); + StringBuilder bcdSb = new StringBuilder(count); + for (int i = 0; i < count; i++) + { + bcdSb.Append(readOnlySpan[i].ToString("X2")); + } + // todo:对于协议来说这个0是有意义的,下个版本在去掉 + return bcdSb.ToString().TrimStart('0'); + } + private ReadOnlySpan GetReadOnlySpan(int count) + { + ReaderCount += count; + return Reader.Slice(ReaderCount - count); + } + public ReadOnlySpan GetVirtualReadOnlySpan(int count) + { + return Reader.Slice(ReaderCount, count); + } + public ReadOnlySpan ReadContent(int count=0) + { + if (_decoded) + { + //内容长度=总长度-读取的长度-2(校验码1位+终止符1位) + int totalContent = Reader.Length - ReaderCount - 2; + //实际读取内容长度 + int realContent = totalContent - count; + int tempReaderCount = ReaderCount; + ReaderCount += realContent; + return Reader.Slice(tempReaderCount, realContent); + } + else + { + return Reader.Slice(ReaderCount); + } + } + public int ReadCurrentRemainContentLength() + { + if (_decoded) + { + //内容长度=总长度-读取的长度-2(校验码1位+终止符1位) + return Reader.Length - ReaderCount - 2; + } + else + { + return Reader.Length - ReaderCount; + } + } + public void Skip(int count=1) + { + ReaderCount += count; + } + } +} diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs new file mode 100644 index 0000000..f871ac8 --- /dev/null +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs @@ -0,0 +1,393 @@ +using JT808.Protocol.Buffers; +using System; +using System.Buffers; +using System.Buffers.Binary; + +namespace JT808.Protocol.MessagePack +{ + public ref struct JT808MessagePackWriter + { + private JT808BufferWriter writer; + public JT808MessagePackWriter(Span buffer) + { + this.writer = new JT808BufferWriter(buffer); + } + public byte[] FlushAndGetEncodingArray() + { + return writer.Written.Slice(writer.BeforeCodingWrittenPosition).ToArray(); + } + public byte[] FlushAndGetRealArray() + { + return writer.Written.ToArray(); + } + public void WriteStart()=> WriteByte(JT808Package.BeginFlag); + public void WriteEnd() => WriteByte(JT808Package.EndFlag); + public void Nil(out int position) + { + position = writer.WrittenCount; + var span = writer.Free; + span[0] = 0x00; + writer.Advance(1); + } + public void Skip(int count, out int position) + { + position = writer.WrittenCount; + var span = writer.Free; + for (var i = 0; i < count; i++) + { + span[i] = 0x00; + } + writer.Advance(count); + } + public void Skip(int count,out int position, byte fullValue = 0x00) + { + position = writer.WrittenCount; + var span = writer.Free; + for (var i = 0; i < count; i++) + { + span[i] = fullValue; + } + writer.Advance(count); + } + public void WriteByte(byte value) + { + var span = writer.Free; + span[0] = value; + writer.Advance(1); + } + public void WriteUInt16(ushort value) + { + var span = writer.Free; + span[0] = (byte)(value >> 8); + span[1] = (byte)value; + writer.Advance(2); + } + public void WriteInt32(int value) + { + var span = writer.Free; + span[0] = (byte)(value >> 24); + span[1] = (byte)(value >> 16); + span[2] = (byte)(value >> 8); + span[3] = (byte)value; + writer.Advance(4); + } + public void WriteUInt64(ulong value) + { + var span = writer.Free; + span[0] = (byte)(value >> 56); + span[1] = (byte)(value >> 48); + span[2] = (byte)(value >> 40); + span[3] = (byte)(value >> 32); + span[4] = (byte)(value >> 24); + span[5] = (byte)(value >> 16); + span[6] = (byte)(value >> 8); + span[7] = (byte)value; + writer.Advance(8); + } + public void WriteUInt32(uint value) + { + var span = writer.Free; + span[0] = (byte)(value >> 24); + span[1] = (byte)(value >> 16); + span[2] = (byte)(value >> 8); + span[3] = (byte)value; + writer.Advance(4); + } + public void WriteString(string value) + { + byte[] codeBytes = JT808Constants.Encoding.GetBytes(value); + codeBytes.CopyTo(writer.Free); + writer.Advance(codeBytes.Length); + } + public void WriteArray(ReadOnlySpan src) + { + src.CopyTo(writer.Free); + writer.Advance(src.Length); + } + public void WriteUInt16Return(ushort value, int position) + { + writer.Written[position] = (byte)(value >> 8); + writer.Written[position + 1] = (byte)value; + } + public void WriteInt32Return(int value, int position) + { + writer.Written[position] = (byte)(value >> 24); + writer.Written[position + 1] = (byte)(value >> 16); + writer.Written[position + 2] = (byte)(value >> 8); + writer.Written[position + 3] = (byte)value; + } + public void WriteUInt32Return(uint value, int position) + { + writer.Written[position] = (byte)(value >> 24); + writer.Written[position + 1] = (byte)(value >> 16); + writer.Written[position + 2] = (byte)(value >> 8); + writer.Written[position + 3] = (byte)value; + } + public void WriteByteReturn(byte value, int position) + { + writer.Written[position] = value; + } + public void WriteBCDReturn(string value,int len, int position) + { + string bcdText = value ?? ""; + int startIndex = 0; + int noOfZero = len - bcdText.Length; + if (noOfZero > 0) + { + bcdText = bcdText.Insert(startIndex, new string('0', noOfZero)); + } + int byteIndex = 0; + int count = len / 2; + var bcdSpan = bcdText.AsSpan(); + while (startIndex < bcdText.Length && byteIndex < count) + { + writer.Written[position+(byteIndex++)] = Convert.ToByte(bcdSpan.Slice(startIndex, 2).ToString(), 16); + startIndex += 2; + } + } + public void WriteStringReturn(string value, int position) + { + byte[] codeBytes = JT808Constants.Encoding.GetBytes(value); + for (var i = 0; i < codeBytes.Length; i++) + { + writer.Written[position + i] = codeBytes[i]; + } + } + public void WriteArrayReturn(ReadOnlySpan src, int position) + { + foreach (var item in src) + { + writer.Written[position] = item; + position++; + } + } + /// + /// yyMMddHHmmss + /// + /// + /// + public void WriteDateTime6(DateTime value, int fromBase = 16) + { + var span = writer.Free; + span[0] = Convert.ToByte(value.ToString("yy"), fromBase); + span[1] = Convert.ToByte(value.ToString("MM"), fromBase); + span[2] = Convert.ToByte(value.ToString("dd"), fromBase); + span[3] = Convert.ToByte(value.ToString("HH"), fromBase); + span[4] = Convert.ToByte(value.ToString("mm"), fromBase); + span[5] = Convert.ToByte(value.ToString("ss"), fromBase); + writer.Advance(6); + } + /// + /// HH-mm-ss-msms + /// HH-mm-ss-fff + /// + /// + /// + public void WriteDateTime5(DateTime value, int fromBase = 16) + { + var span = writer.Free; + span[0] = Convert.ToByte(value.ToString("HH"), fromBase); + span[1] = Convert.ToByte(value.ToString("mm"), fromBase); + span[2] = Convert.ToByte(value.ToString("ss"), fromBase); + span[3] = (byte)(value.Millisecond >> 8); + span[4] = (byte)(value.Millisecond); + writer.Advance(5); + } + public void WriteUTCDateTime(DateTime value) + { + ulong totalSecends = (ulong)(value.AddHours(-8) - JT808Constants.UTCBaseTime).TotalSeconds; + var span = writer.Free; + //高位在前 + for (int i = 7; i >= 0; i--) + { + span[i] = (byte)(totalSecends & 0xFF); //取低8位 + totalSecends >>= 8; + } + writer.Advance(8); + } + /// + /// YYYYMMDD + /// + /// + /// + public void WriteDateTime4(DateTime value, int fromBase = 16) + { + var span = writer.Free; + span[0] = (byte)(value.Year >> 8); + span[1] = (byte)(value.Year); + span[2] = Convert.ToByte(value.ToString("MM"), fromBase); + span[3] = Convert.ToByte(value.ToString("dd"), fromBase); + writer.Advance(4); + } + public void WriteXor(int start, int end) + { + if (start > end) + { + throw new ArgumentOutOfRangeException($"start>end:{start}>{end}"); + } + var xorSpan = writer.Written.Slice(start, end); + byte result = xorSpan[0]; + for (int i = start + 1; i < end; i++) + { + result = (byte)(result ^ xorSpan[i]); + } + var span = writer.Free; + span[0] = result; + writer.Advance(1); + } + public void WriteXor(int start) + { + if(writer.WrittenCount< start) + { + throw new ArgumentOutOfRangeException($"Written{start}"); + } + var xorSpan = writer.Written.Slice(start); + byte result = xorSpan[0]; + for (int i = start + 1; i < xorSpan.Length; i++) + { + result = (byte)(result ^ xorSpan[i]); + } + var span = writer.Free; + span[0] = result; + writer.Advance(1); + } + public void WriteXor() + { + if (writer.WrittenCount < 1) + { + throw new ArgumentOutOfRangeException($"Written{1}"); + } + //从第1位开始 + var xorSpan = writer.Written.Slice(1); + byte result = xorSpan[0]; + for (int i = 1; i < xorSpan.Length; i++) + { + result = (byte)(result ^ xorSpan[i]); + } + var span = writer.Free; + span[0] = result; + writer.Advance(1); + } + public void WriteBCD(string value, int len) + { + string bcdText = value ?? ""; + int startIndex = 0; + int noOfZero = len - bcdText.Length; + if (noOfZero > 0) + { + bcdText = bcdText.Insert(startIndex, new string('0', noOfZero)); + } + int byteIndex = 0; + int count = len / 2; + var bcdSpan = bcdText.AsSpan(); + var spanFree = writer.Free; + while (startIndex < bcdText.Length && byteIndex < count) + { + spanFree[byteIndex++] = Convert.ToByte(bcdSpan.Slice(startIndex, 2).ToString(), 16); + startIndex += 2; + } + writer.Advance(byteIndex); + } + public void WriteHex(string value, int len) + { + value = value ?? ""; + value = value.Replace(" ", ""); + int startIndex = 0; + if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) + { + startIndex = 2; + } + int length = len; + if (length == -1) + { + length = (value.Length - startIndex) / 2; + } + int noOfZero = length * 2 + startIndex - value.Length; + if (noOfZero > 0) + { + value = value.Insert(startIndex, new string('0', noOfZero)); + } + int byteIndex = 0; + var hexSpan = value.AsSpan(); + var spanFree = writer.Free; + while (startIndex < value.Length && byteIndex < length) + { + spanFree[byteIndex++] = Convert.ToByte(hexSpan.Slice(startIndex, 2).ToString(), 16); + startIndex += 2; + } + writer.Advance(byteIndex); + } + public void WriteFullEncode() + { + var tmpSpan = writer.Written; + writer.BeforeCodingWrittenPosition = writer.WrittenCount; + var spanFree = writer.Free; + int tempOffset = 0; + for (int i = 0; i < tmpSpan.Length; i++) + { + if (tmpSpan[i] == 0x7e) + { + spanFree[tempOffset++] = 0x7d; + spanFree[tempOffset++] = 0x02; + } + else if (tmpSpan[i] == 0x7d) + { + spanFree[tempOffset++] = 0x7d; + spanFree[tempOffset++] = 0x01; + } + else + { + spanFree[tempOffset++] = tmpSpan[i]; + } + } + writer.Advance(tempOffset); + } + internal void WriteEncode() + { + var tmpSpan = writer.Written; + writer.BeforeCodingWrittenPosition = writer.WrittenCount; + var spanFree = writer.Free; + int tempOffset = 0; + spanFree[tempOffset++] = tmpSpan[0]; + for (int i = 1; i < tmpSpan.Length - 1; i++) + { + if (tmpSpan[i] == 0x7e) + { + spanFree[tempOffset++] = 0x7d; + spanFree[tempOffset++] = 0x02; + } + else if (tmpSpan[i] == 0x7d) + { + spanFree[tempOffset++] = 0x7d; + spanFree[tempOffset++] = 0x01; + } + else + { + spanFree[tempOffset++] = tmpSpan[i]; + } + } + spanFree[tempOffset++] = tmpSpan[tmpSpan.Length - 1]; + writer.Advance(tempOffset); + } + /// + /// 数字编码 大端模式、高位在前 + /// + /// + /// + public void WriteBigNumber(string value, int len) + { + var spanFree = writer.Free; + ulong number = string.IsNullOrEmpty(value) ? 0 : (ulong)double.Parse(value); + for (int i = len - 1; i >= 0; i--) + { + spanFree[i] = (byte)(number & 0xFF); //取低8位 + number = number >> 8; + } + writer.Advance(len); + } + public int GetCurrentPosition() + { + return writer.WrittenCount; + } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808AlarmProperty.cs b/src/JT808.Protocol/Metadata/JT808AlarmProperty.cs new file mode 100644 index 0000000..3f4bc8a --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808AlarmProperty.cs @@ -0,0 +1,237 @@ +using System; + +namespace JT808.Protocol.Metadata +{ + /// + /// 报警标志位定义 + /// + public class JT808AlarmProperty + { + private const int bitCount = 32; + /// + /// 初始化读取报警标志位 + /// + /// + public JT808AlarmProperty(string alarmStr) + { + Bit0 = alarmStr[0]; + Bit1 = alarmStr[1]; + Bit2 = alarmStr[2]; + Bit3 = alarmStr[3]; + Bit4 = alarmStr[4]; + Bit5 = alarmStr[5]; + Bit6 = alarmStr[6]; + Bit7 = alarmStr[7]; + Bit8 = alarmStr[8]; + Bit9 = alarmStr[9]; + Bit10 = alarmStr[10]; + Bit11 = alarmStr[11]; + Bit12 = alarmStr[12]; + Bit13 = alarmStr[13]; + Bit14 = alarmStr[14]; + Bit15 = alarmStr[15]; + Bit16 = alarmStr[16]; + Bit17 = alarmStr[17]; + Bit18 = alarmStr[18]; + Bit19 = alarmStr[19]; + Bit20 = alarmStr[20]; + Bit21 = alarmStr[21]; + Bit22 = alarmStr[22]; + Bit23 = alarmStr[23]; + Bit24 = alarmStr[24]; + Bit25 = alarmStr[25]; + Bit26 = alarmStr[26]; + Bit27 = alarmStr[27]; + Bit28 = alarmStr[28]; + Bit29 = alarmStr[29]; + Bit30 = alarmStr[30]; + Bit31 = alarmStr[31]; + } + + /// + /// 写入报警标志位 + /// 从左开始写入,不满32位自动补'0' + /// + /// + public JT808AlarmProperty(params char[] alarmChar) + { + alarmChar = alarmChar ?? new char[32]; + ReadOnlySpan span = alarmChar.ToString().PadRight(32, '0').AsSpan(); + Bit0 = span[0]; + Bit1 = span[1]; + Bit2 = span[2]; + Bit3 = span[3]; + Bit4 = span[4]; + Bit5 = span[5]; + Bit6 = span[6]; + Bit7 = span[7]; + Bit8 = span[8]; + Bit9 = span[9]; + Bit10 = span[10]; + Bit11 = span[11]; + Bit12 = span[12]; + Bit13 = span[13]; + Bit14 = span[14]; + Bit15 = span[15]; + Bit16 = span[16]; + Bit17 = span[17]; + Bit18 = span[18]; + Bit19 = span[19]; + Bit20 = span[20]; + Bit21 = span[21]; + Bit22 = span[22]; + Bit23 = span[23]; + Bit24 = span[24]; + Bit25 = span[25]; + Bit26 = span[26]; + Bit27 = span[27]; + Bit28 = span[28]; + Bit29 = span[29]; + Bit30 = span[30]; + Bit31 = span[31]; + } + + /// + /// 1:紧急报警,触动报警开关后触发 收到应答后清零 + /// + public char Bit0 { get; set; } + /// + /// 1:超速报警 标志维持至报警条件解除 + /// + public char Bit1 { get; set; } + /// + /// 1:疲劳驾驶 标志维持至报警条件解除 + /// + public char Bit2 { get; set; } + /// + /// 1:危险预警 收到应答后清零 + /// + public char Bit3 { get; set; } + /// + /// GNSS模块发生故障 标志维持至报警条件解除 + /// + public char Bit4 { get; set; } + /// + /// GNSS天线未接或被剪断 标志维持至报警条件解除 + /// + public char Bit5 { get; set; } + /// + /// GNSS天线短路 标志维持至报警条件解除 + /// + public char Bit6 { get; set; } + /// + /// 终端主电源欠压 标志维持至报警条件解除 + /// + public char Bit7 { get; set; } + /// + /// 终端主电源掉电 标志维持至报警条件解除 + /// + public char Bit8 { get; set; } + /// + /// 终端LCD或显示器故障 标志维持至报警条件解除 + /// + public char Bit9 { get; set; } + /// + /// TTS模块故障 标志维持至报警条件解除 + /// + public char Bit10 { get; set; } + /// + /// 摄像头故障 标志维持至报警条件解除 + /// + public char Bit11 { get; set; } + /// + /// 道路运输证IC卡模块故障 标志维持至报警条件解除 + /// + public char Bit12 { get; set; } + /// + /// 超速预警 标志维持至报警条件解除 + /// + public char Bit13 { get; set; } + /// + /// 疲劳驾驶预警 标志维持至报警条件解除 + /// + public char Bit14 { get; set; } + /// + /// 保留15 + /// + public char Bit15 { get; set; } + /// + /// 保留16 + /// + public char Bit16 { get; set; } + /// + /// 保留17 + /// + public char Bit17 { get; set; } + /// + /// 当天累计驾驶超时 标志维持至报警条件解除 + /// + public char Bit18 { get; set; } + /// + /// 超时停车 标志维持至报警条件解除 + /// + public char Bit19 { get; set; } + /// + /// 进出区域 收到应答后清零 + /// + public char Bit20 { get; set; } + /// + /// 进出路线 收到应答后清零 + /// + public char Bit21 { get; set; } + /// + /// 路段行驶时间不足或过长 收到应答后清零 + /// + public char Bit22 { get; set; } + /// + /// 路线偏离报警 标志维持至报警条件解除 + /// + public char Bit23 { get; set; } + /// + /// 车辆VSS故障 标志维持至报警条件解除 + /// + public char Bit24 { get; set; } + /// + /// 车辆油量异常 标志维持至报警条件解除 + /// + public char Bit25 { get; set; } + /// + /// 车辆被盗通过车辆防盗器 标志维持至报警条件解除 + /// + public char Bit26 { get; set; } + /// + /// 车辆非法点火 + /// + public char Bit27 { get; set; } + /// + /// 车辆非法位移 收到应答后清零 + /// + public char Bit28 { get; set; } + /// + /// 碰撞预警 标志维持至报警条件解除 + /// + public char Bit29 { get; set; } + /// + /// 侧翻预警 标志维持至报警条件解除 + /// + public char Bit30 { get; set; } + /// + /// 非法开门报警 (终端未设置区域时,不判断非法开门)收到应答后清零 + /// + public char Bit31 { get; set; } + + /// + /// 报警标志位 + /// + /// + public override string ToString() + { + Span span = new char[bitCount]; + for (int i = 0; i < span.Length; i++) + { + span[i] = (char)this.GetType().GetProperty("Bit" + i.ToString()).GetValue(this); + } + return span.ToString(); + } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808CanProperty.cs b/src/JT808.Protocol/Metadata/JT808CanProperty.cs new file mode 100644 index 0000000..6129081 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808CanProperty.cs @@ -0,0 +1,19 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// Can属性 + /// + public struct JT808CanProperty + { + /// + /// CAN ID + /// 4 + /// + public byte[] CanId { get; set; } + /// + /// CAN 数据 + /// 8 + /// + public byte[] CanData { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs b/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs new file mode 100644 index 0000000..d635883 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808CircleAreaProperty.cs @@ -0,0 +1,54 @@ +using System; + +namespace JT808.Protocol.Metadata +{ + /// + /// 圆形区域属性 + /// + public struct JT808CircleAreaProperty + { + /// + /// 区域 ID + /// + public uint AreaId { get; set; } + /// + /// 区域属性 + /// + public ushort AreaProperty { get; set; } + /// + /// 中心点纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint CenterPointLat { get; set; } + /// + /// 中心点经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint CenterPointLng { get; set; } + /// + /// 半径 + /// 单位为米(m),路段为该拐点到下一拐点 + /// + public uint Radius { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? EndTime { get; set; } + /// + /// 最高速度 + /// Km/h,若区域属性 1 位为 0 则没有该字段 + /// + public ushort? HighestSpeed { get; set; } + /// + /// 超速持续时间 + /// 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 + /// + public byte? OverspeedDuration { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808ContactProperty.cs b/src/JT808.Protocol/Metadata/JT808ContactProperty.cs new file mode 100644 index 0000000..e1940c2 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808ContactProperty.cs @@ -0,0 +1,31 @@ +using JT808.Protocol.Enums; + +namespace JT808.Protocol.Metadata +{ + /// + /// 电话本联系人项数据 + /// + public struct JT808ContactProperty + { + /// + /// 标志 1:呼入;2:呼出;3:呼入/呼出 + /// + public JT808TelephoneBookContactType TelephoneBookContactType { get; set; } + /// + /// 号码长度 + /// + public byte PhoneNumberLength { get; set; } + /// + /// 电话号码 + /// + public string PhoneNumber { get; set; } + /// + /// 联系人长度 + /// + public byte ContactLength { get; set; } + /// + /// 经 GBK 编码 + /// + public string Contact { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808EventProperty.cs b/src/JT808.Protocol/Metadata/JT808EventProperty.cs new file mode 100644 index 0000000..2517db6 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808EventProperty.cs @@ -0,0 +1,24 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// 事件属性 + /// + public struct JT808EventProperty + { + /// + /// 事件 ID + /// 若终端已有同 ID 的事件,则被覆盖 + /// + public byte EventId { get; set; } + /// + /// 事件内容长度 + /// 后继事件内容字段字节长度 + /// + public byte EventContentLength { get; set; } + /// + /// 事件内容 + /// 事件内容,经 GBK 编码 + /// + public string EventContent { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808InflectionPointProperty.cs b/src/JT808.Protocol/Metadata/JT808InflectionPointProperty.cs new file mode 100644 index 0000000..0747ad3 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808InflectionPointProperty.cs @@ -0,0 +1,56 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// 拐点属性 + /// + public struct JT808InflectionPointProperty + { + /// + /// 拐点 ID + /// + public uint InflectionPointId { get; set; } + /// + /// 路段 ID + /// + public uint SectionId { get; set; } + /// + /// 拐点纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint InflectionPointLat { get; set; } + /// + /// 拐点经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint InflectionPointLng { get; set; } + /// + /// 路段宽度 + /// 单位为米(m),路段为该拐点到下一拐点 + /// + public byte SectionWidth { get; set; } + /// + /// 路段属性 + /// + public byte SectionProperty { get; set; } + /// + /// 路段行驶过长阈值 + /// 单位为秒(s),若路段属性 0 位为 0 则没有该字段 + /// + public ushort? SectionLongDrivingThreshold { get; set; } + /// + /// 路段行驶不足阈值 + /// 单位为秒(s),若路段属性 0 位为 0 则没有该字段 + /// + public ushort? SectionDrivingUnderThreshold { get; set; } + /// + /// 路段最高速度 + /// 单位为公里每小时(km/h),若路段属性 1 位为 0 则没有该字段 + /// + public ushort? SectionHighestSpeed { get; set; } + /// + /// 超速持续时间 + /// 单位为秒(s),若路段属性 1 位为 0 则没有该字段 + /// + public byte? SectionOverspeedDuration { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808InformationItemProperty.cs b/src/JT808.Protocol/Metadata/JT808InformationItemProperty.cs new file mode 100644 index 0000000..082bd17 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808InformationItemProperty.cs @@ -0,0 +1,24 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// 信息点播属性 + /// + public struct JT808InformationItemProperty + { + /// + /// 信息类型 + /// 若终端已有同类型的信息项,则被覆盖 + /// + public byte InformationType { get; set; } + /// + /// 信息名称长度 + /// 信息名称字段字节长度 + /// + public ushort InformationLength { get; set; } + /// + /// 信息名称 + /// 经 GBK 编码处理 + /// + public string InformationName { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808MultimediaSearchProperty.cs b/src/JT808.Protocol/Metadata/JT808MultimediaSearchProperty.cs new file mode 100644 index 0000000..d83ac3e --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808MultimediaSearchProperty.cs @@ -0,0 +1,34 @@ +using JT808.Protocol.MessageBody; + +namespace JT808.Protocol.Metadata +{ + /// + /// 存储多媒体数据检索应答 + /// + public class JT808MultimediaSearchProperty + { + /// + /// 多媒体 ID + /// + public uint MultimediaId { get; set; } + /// + /// 多媒体类型 + /// + /// + public byte MultimediaType { get; set; } + /// + /// 通道 ID + /// + public byte ChannelId { get; set; } + /// + /// 事件项编码 + /// + /// + public byte EventItemCoding { get; set; } + /// + /// 位置信息汇报(0x0200)消息体 + /// 表示拍摄或录制的起始时刻的位置基本信息数据 + /// + public JT808_0x0200 Position { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808PeakProperty.cs b/src/JT808.Protocol/Metadata/JT808PeakProperty.cs new file mode 100644 index 0000000..48488ed --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808PeakProperty.cs @@ -0,0 +1,19 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// 顶点项 + /// + public struct JT808PeakProperty + { + /// + /// 顶点纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint Lat { get; set; } + /// + /// 顶点经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint Lng { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs b/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs new file mode 100644 index 0000000..2d31c3a --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808RectangleAreaProperty.cs @@ -0,0 +1,59 @@ +using System; + +namespace JT808.Protocol.Metadata +{ + /// + /// 矩形区域属性 + /// + public struct JT808RectangleAreaProperty + { + /// + /// 区域 ID + /// + public uint AreaId { get; set; } + /// + /// 区域属性 + /// + public ushort AreaProperty { get; set; } + /// + /// 左上点纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint UpLeftPointLat { get; set; } + /// + /// 左上点经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint UpLeftPointLng { get; set; } + /// + /// 右下点纬度 + /// 以度为单位的纬度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint LowRightPointLat { get; set; } + /// + /// 右下点经度 + /// 以度为单位的经度值乘以 10 的 6 次方,精确到百万分之一度 + /// + public uint LowRightPointLng { get; set; } + /// + /// 起始时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? StartTime { get; set; } + /// + /// 结束时间 + /// YY-MM-DD-hh-mm-ss,若区域属性 0 位为 0 则没有该字段 + /// + public DateTime? EndTime { get; set; } + /// + /// 最高速度 + /// Km/h,若区域属性 1 位为 0 则没有该字段 + /// + public ushort? HighestSpeed { get; set; } + /// + /// 超速持续时间 + /// 单位为秒(s)(类似表述,同前修改),若区域属性 1 位为 0 则没有该字段 + /// + public byte? OverspeedDuration { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808SplitPackageProperty.cs b/src/JT808.Protocol/Metadata/JT808SplitPackageProperty.cs new file mode 100644 index 0000000..959953b --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808SplitPackageProperty.cs @@ -0,0 +1,14 @@ +namespace JT808.Protocol.Metadata +{ + /// + /// 分包属性 + /// + public struct JT808SplitPackageProperty + { + public int PackgeIndex { get; set; } + + public int PackgeCount { get; set; } + + public byte[] Data { get; set; } + } +} diff --git a/src/JT808.Protocol/Metadata/JT808StatusProperty.cs b/src/JT808.Protocol/Metadata/JT808StatusProperty.cs new file mode 100644 index 0000000..9598219 --- /dev/null +++ b/src/JT808.Protocol/Metadata/JT808StatusProperty.cs @@ -0,0 +1,236 @@ +using System; + +namespace JT808.Protocol.Metadata +{ + /// + /// 状态位 + /// + public struct JT808StatusProperty + { + /// + /// 初始化读取状态位 + /// + /// + public JT808StatusProperty(string alarmStr) + { + Bit0 = alarmStr[0]; + Bit1 = alarmStr[1]; + Bit2 = alarmStr[2]; + Bit3 = alarmStr[3]; + Bit4 = alarmStr[4]; + Bit5 = alarmStr[5]; + Bit6 = alarmStr[6]; + Bit7 = alarmStr[7]; + Bit8 = alarmStr[8]; + Bit9 = alarmStr[9]; + Bit10 = alarmStr[10]; + Bit11 = alarmStr[11]; + Bit12 = alarmStr[12]; + Bit13 = alarmStr[13]; + Bit14 = alarmStr[14]; + Bit15 = alarmStr[15]; + Bit16 = alarmStr[16]; + Bit17 = alarmStr[17]; + Bit18 = alarmStr[18]; + Bit19 = alarmStr[19]; + Bit20 = alarmStr[20]; + Bit21 = alarmStr[21]; + Bit22 = alarmStr[22]; + Bit23 = alarmStr[23]; + Bit24 = alarmStr[24]; + Bit25 = alarmStr[25]; + Bit26 = alarmStr[26]; + Bit27 = alarmStr[27]; + Bit28 = alarmStr[28]; + Bit29 = alarmStr[29]; + Bit30 = alarmStr[30]; + Bit31 = alarmStr[31]; + } + + /// + /// 写入状态位 + /// 从左开始写入,不满32位自动补'0' + /// + /// + public JT808StatusProperty(params char[] alarmChar) + { + alarmChar = alarmChar ?? new char[32]; + ReadOnlySpan span = alarmChar.ToString().PadRight(32, '0').AsSpan(); + Bit0 = span[0]; + Bit1 = span[1]; + Bit2 = span[2]; + Bit3 = span[3]; + Bit4 = span[4]; + Bit5 = span[5]; + Bit6 = span[6]; + Bit7 = span[7]; + Bit8 = span[8]; + Bit9 = span[9]; + Bit10 = span[10]; + Bit11 = span[11]; + Bit12 = span[12]; + Bit13 = span[13]; + Bit14 = span[14]; + Bit15 = span[15]; + Bit16 = span[16]; + Bit17 = span[17]; + Bit18 = span[18]; + Bit19 = span[19]; + Bit20 = span[20]; + Bit21 = span[21]; + Bit22 = span[22]; + Bit23 = span[23]; + Bit24 = span[24]; + Bit25 = span[25]; + Bit26 = span[26]; + Bit27 = span[27]; + Bit28 = span[28]; + Bit29 = span[29]; + Bit30 = span[30]; + Bit31 = span[31]; + } + + /// + /// 0:ACC 关;1: ACC 开 + /// + public char Bit0 { get; set; } + /// + /// 0:未定位;1:定位 + /// + public char Bit1 { get; set; } + /// + /// 0:北纬;1:南纬 + /// + public char Bit2 { get; set; } + /// + /// 0:东经;1:西经 + /// + public char Bit3 { get; set; } + /// + /// 0:运营状态;1:停运状态 + /// + public char Bit4 { get; set; } + /// + /// 0:经纬度未经保密插件加密;1:经纬度已经保密插件加密 + /// + public char Bit5 { get; set; } + /// + /// 保留 + /// + public char Bit6 { get; set; } + /// + /// 保留 + /// + public char Bit7 { get; set; } + /// + /// 00:空车;01:半载;10:保留;11:满载(可用于客车的空、重车及货车的空载、满载状态表示,人工输入或传感器获取) + /// + public char Bit8 { get; set; } + /// + /// 00:空车;01:半载;10:保留;11:满载(可用于客车的空、重车及货车的空载、满载状态表示,人工输入或传感器获取) + /// + public char Bit9 { get; set; } + /// + /// 0:车辆油路正常;1:车辆油路断开 + /// + public char Bit10 { get; set; } + /// + /// 0:车辆电路正常;1:车辆电路断开 + /// + public char Bit11 { get; set; } + /// + /// 0:车门解锁;1:车门加锁 + /// + public char Bit12 { get; set; } + /// + /// 0:门 1 关;1:门 1 开(前门) + /// + public char Bit13 { get; set; } + /// + /// 0:门 2 关;1:门 2 开(中门) + /// + public char Bit14 { get; set; } + /// + /// 0:门 3 关;1:门 3 开(后门) + /// + public char Bit15 { get; set; } + /// + /// 0:门 4 关;1:门 4 开(驾驶席门) + /// + public char Bit16 { get; set; } + /// + /// 0:门 5 关;1:门 5 开(自定义) + /// + public char Bit17 { get; set; } + /// + /// 0:未使用 GPS 卫星进行定位;1:使用 GPS 卫星进行定位 + /// + public char Bit18 { get; set; } + /// + /// 0:未使用北斗卫星进行定位;1:使用北斗卫星进行定位 + /// + public char Bit19 { get; set; } + /// + /// 0:未使用 GLONASS 卫星进行定位;1:使用 GLONASS 卫星进行定位 + /// + public char Bit20 { get; set; } + /// + /// 0:未使用 Galileo 卫星进行定位;1:使用 Galileo 卫星进行定位 + /// + public char Bit21 { get; set; } + /// + /// 保留 + /// + public char Bit22 { get; set; } + /// + /// 保留 + /// + public char Bit23 { get; set; } + /// + /// 保留 + /// + public char Bit24 { get; set; } + /// + /// 保留 + /// + public char Bit25 { get; set; } + /// + /// 保留 + /// + public char Bit26 { get; set; } + /// + /// 保留 + /// + public char Bit27 { get; set; } + /// + /// 保留 + /// + public char Bit28 { get; set; } + /// + /// 保留 + /// + public char Bit29 { get; set; } + /// + /// 保留 + /// + public char Bit30 { get; set; } + /// + /// 保留 + /// + public char Bit31 { get; set; } + + /// + /// 状态位 + /// + /// + public override string ToString() + { + Span span = new char[32]; + for (int i = 0; i < span.Length; i++) + { + span[i] = (char)this.GetType().GetProperty("Bit" + i.ToString()).GetValue(this); + } + return span.ToString(); + } + } +}