diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs
new file mode 100644
index 0000000..b61c2a8
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs
@@ -0,0 +1,12 @@
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ ///
+ /// 包计数器服务
+ ///
+ public class JT808AtomicCounterDto
+ {
+ public long MsgSuccessCount { get; set; }
+
+ public long MsgFailCount { get; set; }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs
new file mode 100644
index 0000000..7faf2ee
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ public class JT808DefaultResultDto: JT808ResultDto
+ {
+ public JT808DefaultResultDto()
+ {
+ Data = "Hello,JT808 WebAPI";
+ Code = JT808ResultCode.Ok;
+ }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs
new file mode 100644
index 0000000..6978e87
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Text;
+
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ public class JT808IPAddressDto
+ {
+ public string Host { get; set; }
+
+ public int Port { get; set; }
+
+ private EndPoint endPoint;
+
+ public EndPoint EndPoint
+ {
+ get
+ {
+ if (endPoint == null)
+ {
+ if (IPAddress.TryParse(Host, out IPAddress ip))
+ {
+ endPoint = new IPEndPoint(ip, Port);
+ }
+ else
+ {
+ endPoint = new DnsEndPoint(Host, Port);
+ }
+ }
+ return endPoint;
+ }
+ }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs
new file mode 100644
index 0000000..97f00b9
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ public class JT808ResultDto
+ {
+ public string Message { get; set; }
+
+ public int Code { get; set; }
+
+ public T Data { get; set; }
+ }
+
+ public class JT808ResultCode
+ {
+ public const int Ok = 200;
+ public const int Empty = 201;
+ public const int NotFound = 404;
+ public const int Fail = 400;
+ public const int Error = 500;
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808SourcePackageChannelInfoDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808SourcePackageChannelInfoDto.cs
new file mode 100644
index 0000000..6ff0c37
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808SourcePackageChannelInfoDto.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ ///
+ /// 原包通道信息
+ ///
+ public class JT808SourcePackageChannelInfoDto
+ {
+ ///
+ /// 远程地址
+ ///
+ public string RemoteAddress { get; set; }
+ ///
+ /// 本地地址
+ ///
+ public string LocalAddress { get; set; }
+ ///
+ /// 是否注册
+ ///
+ public bool Registered { get; set; }
+ ///
+ /// 是否活动
+ ///
+ public bool Active { get; set; }
+ ///
+ /// 是否打开
+ ///
+ public bool Open { get; set; }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs
new file mode 100644
index 0000000..4a71a69
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ public class JT808TcpSessionInfoDto
+ {
+ ///
+ /// 最后上线时间
+ ///
+ public DateTime LastActiveTime { get; set; }
+ ///
+ /// 上线时间
+ ///
+ public DateTime StartTime { get; set; }
+ ///
+ /// 终端手机号
+ ///
+ public string TerminalPhoneNo { get; set; }
+ ///
+ /// 远程ip地址
+ ///
+ public string RemoteAddressIP { get; set; }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs
new file mode 100644
index 0000000..8f32473
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs
@@ -0,0 +1,11 @@
+namespace JT808.DotNetty.Abstractions.Dtos
+{
+ ///
+ /// 统一下发请求参数
+ ///
+ public class JT808UnificationSendRequestDto
+ {
+ public string TerminalPhoneNo { get; set; }
+ public byte[] Data { get; set; }
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/IJT808SessionPublishing.cs b/src/JT808.DotNetty.Abstractions/IJT808SessionPublishing.cs
new file mode 100644
index 0000000..13968c6
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/IJT808SessionPublishing.cs
@@ -0,0 +1,12 @@
+using System.Threading.Tasks;
+
+namespace JT808.DotNetty.Abstractions
+{
+ ///
+ /// 会话通知(在线/离线)
+ ///
+ public interface IJT808SessionPublishing
+ {
+ Task PublishAsync(string topicName, string key, string value);
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/IJT808SourcePackageDispatcher.cs b/src/JT808.DotNetty.Abstractions/IJT808SourcePackageDispatcher.cs
new file mode 100644
index 0000000..f3fa1dd
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/IJT808SourcePackageDispatcher.cs
@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+
+namespace JT808.DotNetty.Abstractions
+{
+ ///
+ /// 源包分发器
+ /// 自定义源包分发器业务
+ /// ConfigureServices:
+ /// services.Replace(new ServiceDescriptor(typeof(IJT808SourcePackageDispatcher),typeof(JT808SourcePackageDispatcherDefaultImpl),ServiceLifetime.Singleton));
+ ///
+ public interface IJT808SourcePackageDispatcher
+ {
+ Task SendAsync(byte[] data);
+ }
+}
diff --git a/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj b/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj
new file mode 100644
index 0000000..3993216
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netstandard2.0
+ 7.1
+
+
+
diff --git a/src/JT808.DotNetty.Abstractions/JT808Constants.cs b/src/JT808.DotNetty.Abstractions/JT808Constants.cs
new file mode 100644
index 0000000..4f591d5
--- /dev/null
+++ b/src/JT808.DotNetty.Abstractions/JT808Constants.cs
@@ -0,0 +1,9 @@
+namespace JT808.DotNetty.Abstractions
+{
+ public static class JT808Constants
+ {
+ public const string SessionOnline= "JT808SessionOnline";
+
+ public const string SessionOffline = "JT808SessionOffline";
+ }
+}
diff --git a/src/JT808.DotNetty.Codecs/JT808.DotNetty.Codecs.csproj b/src/JT808.DotNetty.Codecs/JT808.DotNetty.Codecs.csproj
new file mode 100644
index 0000000..19d837a
--- /dev/null
+++ b/src/JT808.DotNetty.Codecs/JT808.DotNetty.Codecs.csproj
@@ -0,0 +1,14 @@
+
+
+
+ netstandard2.0
+ 7.1
+
+
+
+
+
+
+
+
+
diff --git a/src/JT808.DotNetty.Codecs/JT808TcpDecoder.cs b/src/JT808.DotNetty.Codecs/JT808TcpDecoder.cs
new file mode 100644
index 0000000..376194e
--- /dev/null
+++ b/src/JT808.DotNetty.Codecs/JT808TcpDecoder.cs
@@ -0,0 +1,20 @@
+using DotNetty.Buffers;
+using DotNetty.Codecs;
+using System.Collections.Generic;
+using JT808.Protocol;
+using DotNetty.Transport.Channels;
+
+namespace JT808.DotNetty.Codecs
+{
+ public class JT808TcpDecoder : ByteToMessageDecoder
+ {
+ protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List