diff --git a/src/JT1078.Protocol.Test/Extensions/JT1078PackageExtensionsTest.cs b/src/JT1078.Protocol.Test/Extensions/JT1078PackageExtensionsTest.cs
new file mode 100644
index 0000000..4d1f2c5
--- /dev/null
+++ b/src/JT1078.Protocol.Test/Extensions/JT1078PackageExtensionsTest.cs
@@ -0,0 +1,39 @@
+using JT1078.Protocol.Extensions;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace JT1078.Protocol.Test.Extensions
+{
+ public class JT1078PackageExtensionsTest
+ {
+ [Fact]
+ public void Test()
+ {
+ var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078.txt"));
+ JT1078Package merge = null;
+ int mergeBodyLength = 0;
+ foreach (var line in lines)
+ {
+ var data = line.Split(',');
+ var bytes = data[5].ToHexBytes();
+ JT1078Package package = JT1078Serializer.Deserialize(bytes);
+ mergeBodyLength += package.DataBodyLength;
+ merge = JT1078Serializer.Merge(package);
+ }
+ var packages = merge.Bodies.ConvertVideo(merge.SIM, merge.LogicChannelNumber, merge.Label2.PT, merge.Label3.DataType,
+ merge.Timestamp, merge.LastFrameInterval, merge.LastFrameInterval);
+ for(int i=0;i< packages.Count;i++)
+ {
+ var data = lines[i].Split(',');
+ var bytes1 = data[5].ToHexBytes();
+ var bytes2 = JT1078Serializer.Serialize(packages[i]);
+ Assert.Equal(bytes1, bytes2);
+ }
+ }
+ }
+}
diff --git a/src/JT1078.Protocol/Extensions/JT1078PackageExtensions.cs b/src/JT1078.Protocol/Extensions/JT1078PackageExtensions.cs
new file mode 100644
index 0000000..6ec4a76
--- /dev/null
+++ b/src/JT1078.Protocol/Extensions/JT1078PackageExtensions.cs
@@ -0,0 +1,289 @@
+using JT1078.Protocol.Enums;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT1078.Protocol
+{
+ ///
+ /// 1078扩展类
+ ///
+ public static class JT1078PackageExtensions
+ {
+ ///
+ /// 将音频数据包转换到1078包
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List ConvertAudio(this byte[] value,string sim,int channelNo, JT1078AVType jT1078AVType, ulong timestamp)
+ {
+ List jT1078Packages = new List();
+ var buffer=Slice(value);
+ if (buffer.Count == 1)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Timestamp = timestamp;
+ jT1078Package.Label2 = new JT1078Label2(1, jT1078AVType);
+ jT1078Package.Label3 = new JT1078Label3(JT1078DataType.音频帧, JT1078SubPackageType.原子包_不可被拆分);
+ jT1078Package.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package);
+ }
+ else if(buffer.Count == 2)
+ {
+ JT1078Package jT1078Package1 = new JT1078Package();
+ jT1078Package1.SIM = sim;
+ jT1078Package1.LogicChannelNumber = (byte)channelNo;
+ jT1078Package1.SN = SeqUtil.Increment(sim);
+ jT1078Package1.Timestamp = timestamp;
+ jT1078Package1.Label2 = new JT1078Label2(0, jT1078AVType);
+ jT1078Package1.Label3 = new JT1078Label3(JT1078DataType.音频帧, JT1078SubPackageType.分包处理时的第一个包);
+ jT1078Package1.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package1);
+ JT1078Package jT1078Package2= new JT1078Package();
+ jT1078Package2.SIM = sim;
+ jT1078Package2.LogicChannelNumber = (byte)channelNo;
+ jT1078Package2.SN = SeqUtil.Increment(sim);
+ jT1078Package2.Timestamp = timestamp;
+ jT1078Package2.Label2 = new JT1078Label2(1, jT1078AVType);
+ jT1078Package2.Label3 = new JT1078Label3(JT1078DataType.音频帧, JT1078SubPackageType.分包处理时的最后一个包);
+ jT1078Package2.Bodies = buffer[1];
+ jT1078Packages.Add(jT1078Package2);
+ }
+ else
+ {
+ for (var i = 0; i < buffer.Count; i++)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Timestamp = timestamp;
+ jT1078Package.Label2 = new JT1078Label2(0, jT1078AVType);
+ jT1078Package.Label3 = new JT1078Label3(JT1078DataType.音频帧);
+ jT1078Package.Bodies = buffer[i];
+ if (i == 0)
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的第一个包;
+ }
+ else if (i == (buffer.Count - 1))
+ {
+ jT1078Package.Label2.M = 1;
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的最后一个包;
+ }
+ else
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的中间包;
+ }
+ jT1078Packages.Add(jT1078Package);
+ }
+ }
+ return jT1078Packages;
+ }
+
+ ///
+ /// 将视频数据包转换到1078包
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List ConvertVideo(this byte[] value, string sim,
+ int channelNo,
+ JT1078AVType jT1078AVType,
+ JT1078DataType jT1078DataType,
+ ulong timestamp,
+ int lastIFrameInterval,
+ int lastFrameInterval)
+ {
+ List jT1078Packages = new List();
+ var buffer = Slice(value);
+ if (buffer.Count == 1)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Timestamp = timestamp;
+ jT1078Package.LastIFrameInterval = (ushort)lastIFrameInterval;
+ jT1078Package.LastFrameInterval = (ushort)lastFrameInterval;
+ jT1078Package.Label2 = new JT1078Label2(1, jT1078AVType);
+ jT1078Package.Label3 = new JT1078Label3(jT1078DataType, JT1078SubPackageType.原子包_不可被拆分);
+ jT1078Package.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package);
+ }
+ else if (buffer.Count == 2)
+ {
+ JT1078Package jT1078Package1 = new JT1078Package();
+ jT1078Package1.SIM = sim;
+ jT1078Package1.LogicChannelNumber = (byte)channelNo;
+ jT1078Package1.SN = SeqUtil.Increment(sim);
+ jT1078Package1.Timestamp = timestamp;
+ jT1078Package1.LastIFrameInterval = (ushort)lastIFrameInterval;
+ jT1078Package1.LastFrameInterval = (ushort)lastFrameInterval;
+ jT1078Package1.Label2 = new JT1078Label2(0, jT1078AVType);
+ jT1078Package1.Label3 = new JT1078Label3(jT1078DataType, JT1078SubPackageType.分包处理时的第一个包);
+ jT1078Package1.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package1);
+ JT1078Package jT1078Package2 = new JT1078Package();
+ jT1078Package2.SIM = sim;
+ jT1078Package2.LogicChannelNumber = (byte)channelNo;
+ jT1078Package2.SN = SeqUtil.Increment(sim);
+ jT1078Package2.Timestamp = timestamp;
+ jT1078Package2.LastIFrameInterval = (ushort)lastIFrameInterval;
+ jT1078Package2.LastFrameInterval = (ushort)lastFrameInterval;
+ jT1078Package2.Label2 = new JT1078Label2(1, jT1078AVType);
+ jT1078Package2.Label3 = new JT1078Label3(jT1078DataType, JT1078SubPackageType.分包处理时的最后一个包);
+ jT1078Package2.Bodies = buffer[1];
+ jT1078Packages.Add(jT1078Package2);
+ }
+ else
+ {
+ for (var i = 0; i < buffer.Count; i++)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Timestamp = timestamp;
+ jT1078Package.LastIFrameInterval = (ushort)lastIFrameInterval;
+ jT1078Package.LastFrameInterval = (ushort)lastFrameInterval;
+ jT1078Package.Label2 = new JT1078Label2(0, jT1078AVType);
+ jT1078Package.Label3 = new JT1078Label3(jT1078DataType);
+ jT1078Package.Bodies = buffer[i];
+ if (i == 0)
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的第一个包;
+ }
+ else if (i == (buffer.Count - 1))
+ {
+ jT1078Package.Label2.M = 1;
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的最后一个包;
+ }
+ else
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的中间包;
+ }
+ jT1078Packages.Add(jT1078Package);
+ }
+ }
+ return jT1078Packages;
+ }
+
+ ///
+ /// 将透传数据包转换到1078包
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List ConvertPassthrough(this byte[] value, string sim, int channelNo)
+ {
+ List jT1078Packages = new List();
+ var buffer = Slice(value);
+ if (buffer.Count == 1)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Label2 = new JT1078Label2(1, JT1078AVType.透传);
+ jT1078Package.Label3 = new JT1078Label3(JT1078DataType.透传数据, JT1078SubPackageType.原子包_不可被拆分);
+ jT1078Package.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package);
+ }
+ else if (buffer.Count == 2)
+ {
+ JT1078Package jT1078Package1 = new JT1078Package();
+ jT1078Package1.SIM = sim;
+ jT1078Package1.LogicChannelNumber = (byte)channelNo;
+ jT1078Package1.SN = SeqUtil.Increment(sim);
+ jT1078Package1.Label2 = new JT1078Label2(0, JT1078AVType.透传);
+ jT1078Package1.Label3 = new JT1078Label3(JT1078DataType.透传数据, JT1078SubPackageType.分包处理时的第一个包);
+ jT1078Package1.Bodies = buffer[0];
+ jT1078Packages.Add(jT1078Package1);
+ JT1078Package jT1078Package2 = new JT1078Package();
+ jT1078Package2.SIM = sim;
+ jT1078Package2.LogicChannelNumber = (byte)channelNo;
+ jT1078Package2.SN = SeqUtil.Increment(sim);
+ jT1078Package2.Label2 = new JT1078Label2(1, JT1078AVType.透传);
+ jT1078Package2.Label3 = new JT1078Label3(JT1078DataType.透传数据, JT1078SubPackageType.分包处理时的最后一个包);
+ jT1078Package2.Bodies = buffer[1];
+ jT1078Packages.Add(jT1078Package2);
+ }
+ else
+ {
+ for (var i = 0; i < buffer.Count; i++)
+ {
+ JT1078Package jT1078Package = new JT1078Package();
+ jT1078Package.SIM = sim;
+ jT1078Package.LogicChannelNumber = (byte)channelNo;
+ jT1078Package.SN = SeqUtil.Increment(sim);
+ jT1078Package.Label2 = new JT1078Label2(0, JT1078AVType.透传);
+ jT1078Package.Label3 = new JT1078Label3(JT1078DataType.透传数据);
+ jT1078Package.Bodies = buffer[i];
+ if (i == 0)
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的第一个包;
+ }
+ else if (i == (buffer.Count - 1))
+ {
+ jT1078Package.Label2.M = 1;
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的最后一个包;
+ }
+ else
+ {
+ jT1078Package.Label3.SubpackageType = JT1078SubPackageType.分包处理时的中间包;
+ }
+ jT1078Packages.Add(jT1078Package);
+ }
+ }
+ return jT1078Packages;
+ }
+
+ ///
+ /// 切分数据包
+ ///
+ ///
+ ///
+ public static List Slice(byte[] value)
+ {
+ const int MAXCONTENTLENGTH = 950;
+ if (value.Length <= MAXCONTENTLENGTH)
+ {
+ return new List() { value };
+ }
+ List s = new List();
+ var quotient = value.Length / MAXCONTENTLENGTH;
+ var remainder = value.Length % MAXCONTENTLENGTH;
+ if (remainder != 0)
+ {
+ quotient = quotient + 1;
+ }
+ ReadOnlySpan valueReadOnlySpan = value;
+ for (int i = 1; i <= quotient; i++)
+ {
+ if (i == quotient)
+ {
+ s.Add(valueReadOnlySpan.Slice((i - 1) * MAXCONTENTLENGTH).ToArray());
+ }
+ else
+ {
+ s.Add(valueReadOnlySpan.Slice((i - 1) * MAXCONTENTLENGTH, MAXCONTENTLENGTH).ToArray());
+ }
+ }
+ return s;
+ }
+ }
+}
diff --git a/src/JT1078.Protocol/JT1078.Protocol.xml b/src/JT1078.Protocol/JT1078.Protocol.xml
index 96d7779..b73d231 100644
--- a/src/JT1078.Protocol/JT1078.Protocol.xml
+++ b/src/JT1078.Protocol/JT1078.Protocol.xml
@@ -67,6 +67,52 @@
+
+
+ 1078扩展类
+
+
+
+
+ 将音频数据包转换到1078包
+
+
+
+
+
+
+
+
+
+
+ 将视频数据包转换到1078包
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将透传数据包转换到1078包
+
+
+
+
+
+
+
+
+ 切分数据包
+
+
+
+
diff --git a/src/JT1078.Protocol/JT1078Label3.cs b/src/JT1078.Protocol/JT1078Label3.cs
index 79b5b21..dbfdf31 100644
--- a/src/JT1078.Protocol/JT1078Label3.cs
+++ b/src/JT1078.Protocol/JT1078Label3.cs
@@ -21,6 +21,10 @@ namespace JT1078.Protocol
DataType = dataType;
SubpackageType = subpackageType;
}
+ public JT1078Label3(JT1078DataType dataType)
+ {
+ DataType = dataType;
+ }
///
/// 数据类型
///
diff --git a/src/JT1078.Protocol/JT1078Serializer.cs b/src/JT1078.Protocol/JT1078Serializer.cs
index a5d8e54..819d727 100644
--- a/src/JT1078.Protocol/JT1078Serializer.cs
+++ b/src/JT1078.Protocol/JT1078Serializer.cs
@@ -46,6 +46,7 @@ namespace JT1078.Protocol
JT1078ArrayPool.Return(buffer);
}
}
+
public static JT1078Package Deserialize(ReadOnlySpan bytes)
{
JT1078Package jT1078Package = new JT1078Package();
diff --git a/src/JT1078.Protocol/SeqUtil.cs b/src/JT1078.Protocol/SeqUtil.cs
new file mode 100644
index 0000000..229cf3b
--- /dev/null
+++ b/src/JT1078.Protocol/SeqUtil.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT1078.Protocol
+{
+ public static class SeqUtil
+ {
+ static readonly ConcurrentDictionary counterDict;
+ static SeqUtil()
+ {
+ counterDict = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
+ }
+ public static ushort Increment(string terminalPhoneNo)
+ {
+ return (ushort)counterDict.AddOrUpdate(terminalPhoneNo, 0, (id, count) => count + 1);
+ }
+ public static ushort Reset(string terminalPhoneNo)
+ {
+ return (ushort)counterDict.AddOrUpdate(terminalPhoneNo, 0, (id, count) => 0);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Extensions.JT1078/JT808.Protocol.Extensions.JT1078.csproj b/src/JT808.Protocol.Extensions.JT1078/JT808.Protocol.Extensions.JT1078.csproj
index 1586341..adc1152 100644
--- a/src/JT808.Protocol.Extensions.JT1078/JT808.Protocol.Extensions.JT1078.csproj
+++ b/src/JT808.Protocol.Extensions.JT1078/JT808.Protocol.Extensions.JT1078.csproj
@@ -15,7 +15,7 @@
https://github.com/SmallChi/JT1078/blob/master/LICENSE
https://github.com/SmallChi/JT1078/blob/master/LICENSE
false
- 2.3.4
+ 2.3.5
LICENSE
JT808.Protocol.Extensions.JT1078.xml
@@ -28,7 +28,7 @@
-
+
diff --git a/src/JT808.Protocol.Extensions.JT1078/MessageBody/JT808_0x0200_0x14.cs b/src/JT808.Protocol.Extensions.JT1078/MessageBody/JT808_0x0200_0x14.cs
index c0e7289..b06c751 100644
--- a/src/JT808.Protocol.Extensions.JT1078/MessageBody/JT808_0x0200_0x14.cs
+++ b/src/JT808.Protocol.Extensions.JT1078/MessageBody/JT808_0x0200_0x14.cs
@@ -34,7 +34,7 @@ namespace JT808.Protocol.Extensions.JT1078.MessageBody
writer.WriteNumber($"[{value.AttachInfoLength.ReadNumber()}]附加信息长度", value.AttachInfoLength);
value.VideoRelateAlarm = reader.ReadUInt32();
writer.WriteNumber($"[{value.VideoRelateAlarm.ReadNumber()}]视频相关报警", value.VideoRelateAlarm);
- var videoRelateAlarmFlags = JT808EnumExtensions.GetEnumTypes((int)value.VideoRelateAlarm, 32);
+ var videoRelateAlarmFlags = JT808EnumExtensions.GetEnumTypes(value.VideoRelateAlarm, 32);
if (videoRelateAlarmFlags.Any())
{
writer.WriteStartArray("视频报警集合");