diff --git a/langguanApi.xml b/langguanApi.xml
index adaa7b4..0e9e02d 100644
--- a/langguanApi.xml
+++ b/langguanApi.xml
@@ -9,6 +9,12 @@
缓存管理
+
+
+ 构造函数
+
+
+
缓存数据
@@ -19,11 +25,53 @@
缓存时间秒,0=int.max ,
+
+
+ gps 协议解析器
+
+
+
+
+ 解析消息头
+
+
+
+
+
+
+
+ 解析位置信息
+
+
+
+
+
+
+ 解析终端注册消息
+
+
+
+
+
+
+
+ 解析位置上报消息
+
+
+
+
+
http
+
+
+ 构造函数
+
+
+
获取数据
@@ -47,6 +95,11 @@
sub
+
+
+ 构造函数
+
+
缓存天气信息
diff --git a/langguanApi/Common/CacheManager.cs b/langguanApi/Common/CacheManager.cs
index 4a7637d..0c04069 100644
--- a/langguanApi/Common/CacheManager.cs
+++ b/langguanApi/Common/CacheManager.cs
@@ -12,6 +12,10 @@ namespace langguanApi.Common
public class CacheManager
{
private readonly IDatabase _redisDatabase;
+ ///
+ /// 构造函数
+ ///
+ ///
public CacheManager(RedisHelper redisHelper)
{
_redisDatabase = redisHelper._database;
diff --git a/langguanApi/Common/Gps/MessageHeader.cs b/langguanApi/Common/Gps/MessageHeader.cs
new file mode 100644
index 0000000..8f25af6
--- /dev/null
+++ b/langguanApi/Common/Gps/MessageHeader.cs
@@ -0,0 +1,31 @@
+namespace langguanApi.Common.Gps
+{
+ public class MessageHeader
+ {
+ public ushort MessageId { get; set; }
+ public ushort MessageBodyProperty { get; set; }
+ public string TerminalId { get; set; }
+ public ushort MessageSerialNumber { get; set; }
+ }
+ public class TerminalRegisterMessage
+ {
+ public ushort ProvinceId { get; set; }
+ public ushort CityId { get; set; }
+ public byte[] ManufacturerId { get; set; }
+ public byte[] TerminalType { get; set; }
+ public byte[] TerminalId { get; set; }
+ public byte LicensePlateColor { get; set; }
+ public string LicensePlate { get; set; }
+ }
+ public class LocationReportMessage
+ {
+ public uint AlarmFlag { get; set; }
+ public uint Status { get; set; }
+ public uint Latitude { get; set; }
+ public uint Longitude { get; set; }
+ public ushort Altitude { get; set; }
+ public ushort Speed { get; set; }
+ public ushort Direction { get; set; }
+ public DateTime Time { get; set; }
+ }
+}
diff --git a/langguanApi/Common/Gps/ProtocolParser.cs b/langguanApi/Common/Gps/ProtocolParser.cs
new file mode 100644
index 0000000..b113aa0
--- /dev/null
+++ b/langguanApi/Common/Gps/ProtocolParser.cs
@@ -0,0 +1,110 @@
+using System.Text;
+
+namespace langguanApi.Common.Gps
+{
+ ///
+ /// gps 协议解析器
+ ///
+ public class ProtocolParser
+ {
+ ///
+ /// 解析消息头
+ ///
+ ///
+ ///
+ ///
+ public static MessageHeader ParseHeader(byte[] data, ref int offset)
+ {
+ var header = new MessageHeader
+ {
+ MessageId = BitConverter.ToUInt16(data, offset),
+ MessageBodyProperty = BitConverter.ToUInt16(data, offset + 2),
+ TerminalId = Encoding.ASCII.GetString(data, offset + 4, 6),
+ MessageSerialNumber = BitConverter.ToUInt16(data, offset + 10)
+ };
+
+ offset += 12;
+ return header;
+ }
+ public struct Position
+ {
+ public double Latitude;
+ public double Longitude;
+ public double Altitude;
+ }
+ ///
+ /// 解析位置信息
+ ///
+ ///
+ ///
+ public static Position ParsePosition(byte[] data)
+ {
+ // 根据协议中的位置信息的偏移量和长度进行解析
+ int positionOffset = 21; // 位置信息在数据中的偏移量
+ int latitudeOffset = positionOffset + 0;
+ int longitudeOffset = positionOffset + 8;
+ int altitudeOffset = positionOffset + 16;
+
+ double latitude = BitConverter.ToDouble(data, latitudeOffset);
+ double longitude = BitConverter.ToDouble(data, longitudeOffset);
+ double altitude = BitConverter.ToDouble(data, altitudeOffset);
+
+ return new Position
+ {
+ Latitude = latitude,
+ Longitude = longitude,
+ Altitude = altitude
+ };
+ }
+
+ ///
+ /// 解析终端注册消息
+ ///
+ ///
+ ///
+ ///
+ public static TerminalRegisterMessage ParseTerminalRegisterMessage(byte[] data, ref int offset)
+ {
+ var message = new TerminalRegisterMessage
+ {
+ ProvinceId = BitConverter.ToUInt16(data, offset),
+ CityId = BitConverter.ToUInt16(data, offset + 2),
+ ManufacturerId = data.Skip(offset + 4).Take(5).ToArray(),
+ TerminalType = data.Skip(offset + 9).Take(8).ToArray(),
+ TerminalId = data.Skip(offset + 17).Take(7).ToArray(),
+ LicensePlateColor = data[offset + 24],
+ LicensePlate = Encoding.ASCII.GetString(data, offset + 25, data.Length - offset - 25)
+ };
+
+ offset += 25 + message.LicensePlate.Length;
+ return message;
+ }
+ ///
+ /// 解析位置上报消息
+ ///
+ ///
+ ///
+ ///
+ public static LocationReportMessage ParseLocationReportMessage(byte[] data, ref int offset)
+ {
+ var message = new LocationReportMessage
+ {
+ AlarmFlag = BitConverter.ToUInt32(data, offset),
+ Status = BitConverter.ToUInt32(data, offset + 4),
+ Latitude = BitConverter.ToUInt32(data, offset + 8),
+ Longitude = BitConverter.ToUInt32(data, offset + 12),
+ Altitude = BitConverter.ToUInt16(data, offset + 16),
+ Speed = BitConverter.ToUInt16(data, offset + 18),
+ Direction = BitConverter.ToUInt16(data, offset + 20),
+ Time = DateTime.ParseExact(
+ Encoding.ASCII.GetString(data, offset + 22, 6),
+ "yyMMddHHmmss",
+ null
+ )
+ };
+
+ offset += 28;
+ return message;
+ }
+ }
+}
diff --git a/langguanApi/Common/Proxy/HttpProxy.cs b/langguanApi/Common/Proxy/HttpProxy.cs
index 3a323ff..8532d4a 100644
--- a/langguanApi/Common/Proxy/HttpProxy.cs
+++ b/langguanApi/Common/Proxy/HttpProxy.cs
@@ -10,6 +10,10 @@ namespace langguanApi.Common.Proxy
public class HttpProxy
{
private readonly IHttpClientFactory _httpClientFactory;
+ ///
+ /// 构造函数
+ ///
+ ///
public HttpProxy(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
diff --git a/langguanApi/Common/Redis/RedisHelper.cs b/langguanApi/Common/Redis/RedisHelper.cs
index 22fa2b4..4442479 100644
--- a/langguanApi/Common/Redis/RedisHelper.cs
+++ b/langguanApi/Common/Redis/RedisHelper.cs
@@ -9,6 +9,9 @@ namespace langguanApi.Common.Redis
/// sub
///
public ISubscriber _subscriber;
+ ///
+ /// 构造函数
+ ///
public RedisHelper()
{
// var con = RedisOptions.Default.GetConnect();
diff --git a/langguanApi/Controllers/HomeController.cs b/langguanApi/Controllers/HomeController.cs
index c1797f2..cbcd0c7 100644
--- a/langguanApi/Controllers/HomeController.cs
+++ b/langguanApi/Controllers/HomeController.cs
@@ -1,9 +1,17 @@
-using langguanApi.Model;
+using JT808.Protocol.MessageBody;
+using JT808.Protocol;
+using langguanApi.Model;
using langguanApi.Service;
using langguanApi.Service.HJ212;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Org.BouncyCastle.Utilities;
using System.Text;
+using JT808.Protocol.Extensions;
+using static langguanApi.Service.WeatherService;
+using langguanApi.Common.Gps;
+using NPOI.SS.Formula.Functions;
+using static langguanApi.Common.Gps.ProtocolParser;
namespace langguanApi.Controllers
{
@@ -23,7 +31,7 @@ namespace langguanApi.Controllers
[HttpGet("view")]
public async Task View()
{
- return Ok( await _homeService.View() );
+ return Ok(await _homeService.View());
}
[HttpGet("test")]
@@ -35,11 +43,128 @@ namespace langguanApi.Controllers
///
public async Task test(int num = 1, string key = "")
{
- // string rawText = "数据报:##0250QN=20240424224800000;ST=22;CN=2011;PW=123456;MN=LGYC022024690001;Flag=5;CP=&&DataTime=20240424224800;a34001-Rtd=356.2";
+ // 示例数据(需替换为实际接收到的协议数据)
+ string hexData = "787811010868120321167279808D3202001AB12F0D0A";
+ byte[] protocolData = HexStringToByteArray(hexData);
+ // 进行转义还原
+ byte[] restoredData = RestoreEscape(protocolData);
+
+ // 验证校验码
+ if (!VerifyChecksum(restoredData))
+ {
+ Console.WriteLine("Checksum verification failed.");
+ }
+ Position? position = ParsePosition(restoredData);
+
+ if (position.HasValue)
+ {
+ Console.WriteLine($"Latitude: {position.Value.Latitude}");
+ Console.WriteLine($"Longitude: {position.Value.Longitude}");
+ Console.WriteLine($"Altitude: {position.Value.Altitude}");
+ }
+ else
+ {
+ Console.WriteLine("Failed to parse position.");
+ }
+ // Console.WriteLine("经度:" + lon + " 纬度:" + lat);
+
+ // string rawText = "数据报:##0250QN=20240424224800000;ST=22;CN=2011;PW=123456;MN=LGYC022024690001;Flag=5;CP=&&DataTime=20240424224800;a34001-Rtd=356.2";
//NetPackage netPackage = NetPackage.Parse(rawText, null);
//((NetServer)Server).RaiseReceivedData(this, netPackage, rawText);
return Ok();
}
+ public static Position? ParsePosition(byte[] data)
+ {
+ // 根据协议中的位置信息的偏移量和长度进行解析
+ int positionOffset = 21; // 位置信息在数据中的偏移量
+ int latitudeOffset = positionOffset + 0;
+ int longitudeOffset = positionOffset + 4;
+ int altitudeOffset = positionOffset + 8;
+ // 检查数组长度是否足够长
+ if (data.Length < altitudeOffset + 2)
+ {
+ Console.WriteLine("Data array is not long enough to contain position information.");
+ return null;
+ }
+
+ // 解析纬度(单位:百万分之一度)
+ int rawLatitude = BitConverter.ToInt32(data, latitudeOffset);
+ double latitude = rawLatitude / 1000000.0;
+
+ // 解析经度(单位:百万分之一度)
+ int rawLongitude = BitConverter.ToInt32(data, longitudeOffset);
+ double longitude = rawLongitude / 1000000.0;
+
+ // 解析高度(单位:米)
+ int rawAltitude = BitConverter.ToInt16(data, altitudeOffset);
+ double altitude = rawAltitude;
+
+ return new Position
+ {
+ Latitude = latitude,
+ Longitude = longitude,
+ Altitude = altitude
+ };
+ }
+
+ private static bool VerifyChecksum(byte[] data)
+ {
+ // 校验码在数据包的倒数第二个字节
+ byte receivedChecksum = data[data.Length - 2];
+ byte calculatedChecksum = 0;
+
+ // 校验范围是从第一个字节到倒数第三个字节
+ for (int i = 0; i < data.Length - 2; i++)
+ {
+ calculatedChecksum ^= data[i];
+ }
+
+ return receivedChecksum == calculatedChecksum;
+ }
+ private static byte[] RestoreEscape(byte[] data)
+ {
+ List result = new List();
+ for (int i = 0; i < data.Length; i++)
+ {
+ if (data[i] == 0x7D)
+ {
+ if (i + 1 < data.Length)
+ {
+ if (data[i + 1] == 0x02)
+ {
+ result.Add(0x7E);
+ i++;
+ }
+ else if (data[i + 1] == 0x01)
+ {
+ result.Add(0x7D);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ result.Add(data[i]);
+ }
+ }
+ return result.ToArray();
+ }
+ private static byte[] HexStringToByteArray(string hex)
+ {
+ int NumberChars = hex.Length;
+ byte[] bytes = new byte[NumberChars / 2];
+ for (int i = 0; i < NumberChars; i += 2)
+ {
+ bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
+ }
+ return bytes;
+ }
+ public struct Position
+ {
+ public double Latitude;
+ public double Longitude;
+ public double Altitude;
+ }
}
}
diff --git a/langguanApi/Extensions/SocketExtension.cs b/langguanApi/Extensions/SocketExtension.cs
index 62f34f7..b48eda5 100644
--- a/langguanApi/Extensions/SocketExtension.cs
+++ b/langguanApi/Extensions/SocketExtension.cs
@@ -12,10 +12,12 @@ namespace langguanApi.Extensions
{
// services.AddSingleton();
services.AddTransient();
+ services.AddSingleton(); // 808协议
services.AddTransient();
IServiceProvider serviceProvider = services.BuildServiceProvider();
_ = serviceProvider.GetService().Start();
+ _ = serviceProvider.GetService().Start();
serviceProvider.GetService().CreatTask();
}
}
diff --git a/langguanApi/Model/FactorCode.cs b/langguanApi/Model/FactorCode.cs
index b8975e8..7fa4758 100644
--- a/langguanApi/Model/FactorCode.cs
+++ b/langguanApi/Model/FactorCode.cs
@@ -416,6 +416,8 @@
a34040,
a99010,
a99049,
+
+ LA,
a99054
//a99051,
#endregion
diff --git a/langguanApi/Service/HJ212/NetSession.cs b/langguanApi/Service/HJ212/NetSession.cs
index 95c4a2e..8dc7407 100644
--- a/langguanApi/Service/HJ212/NetSession.cs
+++ b/langguanApi/Service/HJ212/NetSession.cs
@@ -1,6 +1,13 @@
using IceCoffee.FastSocket.Tcp;
+using JT808.Protocol;
+using JT808.Protocol.Extensions;
+using JT808.Protocol.MessageBody;
+using langguanApi.Common.Gps;
using langguanApi.Model;
+using Npoi.Mapper;
+using NPOI.SS.Formula.Functions;
using System.Text;
+using static langguanApi.Common.Gps.ProtocolParser;
namespace langguanApi.Service.HJ212
{
@@ -31,11 +38,12 @@ namespace langguanApi.Service.HJ212
///
protected override void OnReceived()
{
- if (ReadBuffer.IndexOf(35) != 0L)// '#'
- {
- return;
- // throw new Exception("异常TCP连接 IP: " + RemoteIPEndPoint);
- }
+
+ //if (ReadBuffer.IndexOf(35) != 0L)// '#'
+ //{
+ // return;
+ // // throw new Exception("异常TCP连接 IP: " + RemoteIPEndPoint);
+ //}
string rawText = null;
while (ReadBuffer.CanReadLine)
@@ -43,6 +51,41 @@ namespace langguanApi.Service.HJ212
try
{
byte[] data = ReadBuffer.ReadLine();
+
+ Console.WriteLine($"原始数据:{data}----------");
+ Console.WriteLine($"原始数据HexString:{data.ToHexString()}--------------------");
+ Console.WriteLine($"原始数据ASCII:{Encoding.ASCII.GetString(data)}-");
+
+ Position position = ParsePosition(data);
+
+ Console.WriteLine($"Latitude: {position.Latitude}");
+ Console.WriteLine($"Longitude: {position.Longitude}");
+ Console.WriteLine($"Altitude: {position.Altitude}");
+ int offset = 0;
+ // 解析消息头
+ var header = ProtocolParser.ParseHeader(data, ref offset);
+ Console.WriteLine($"Message ID: {header.MessageId}, Terminal ID: {header.TerminalId}");
+
+ // 解析终端注册消息
+ var registerMessage = ProtocolParser.ParseTerminalRegisterMessage(data, ref offset);
+ Console.WriteLine($"Province ID: {registerMessage.ProvinceId}, City ID: {registerMessage.CityId}");
+ Console.WriteLine($"License Plate: {registerMessage.LicensePlate}");
+
+ offset = 0;
+ // 解析位置信息汇报消息
+ var locationReportMessage = ProtocolParser.ParseLocationReportMessage(data, ref offset);
+ Console.WriteLine($"Latitude: {locationReportMessage.Latitude}, Longitude: {locationReportMessage.Longitude}");
+ Console.WriteLine($"Speed: {locationReportMessage.Speed}, Time: {locationReportMessage.Time}");
+
+
+
+
+ var jT808Package = new JT808Serializer().Deserialize(data);
+ //4.数据包体
+ JT808_0x0200 jT808_0x0200 = (JT808_0x0200)jT808Package.Bodies;
+ var lon = jT808_0x0200.Lat;
+ var lat = jT808_0x0200.Lng;
+ Console.WriteLine("经度:" + lon + " 纬度:" + lat);
rawText = Encoding.UTF8.GetString(data);
NetPackage netPackage = NetPackage.Parse(rawText, GetUnpackCache);
((NetServer)Server).RaiseReceivedData(this, netPackage, rawText);
diff --git a/langguanApi/Service/HJ212SocketServer.cs b/langguanApi/Service/HJ212SocketServer.cs
index 2110bd5..8a3196a 100644
--- a/langguanApi/Service/HJ212SocketServer.cs
+++ b/langguanApi/Service/HJ212SocketServer.cs
@@ -35,7 +35,7 @@ namespace langguanApi.Service
///
/// 服务端口号
///
- private int port => 5001;
+ private int port => 5003;
// 编码
// private string code;
///