You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.1 KiB

using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Utils;
using log4net;
using Service.Car.Common;
using Service.Car.Msg;
using Service.Car.Msg.Car.Req;
using Service.Car.Msg.Car.Resp;
namespace Service.Car.Codec;
public class Decoder : ByteToMessageDecoder
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Decoder));
private readonly IByteBuffer[] _delimiters = { Unpooled.CopiedBuffer(CarConst.StartChar) };
protected override void Decode(IChannelHandlerContext context, IByteBuffer buffer, List<object> output)
{
IByteBuffer? delimiter = FindDelimiter(buffer);
if (delimiter != null)
{
//分隔符索引
int delimiterIndex = IndexOf(buffer, delimiter);
//帧长索引
int frameLengthIndex = delimiterIndex + CarConst.StartChar.Length;
if (delimiterIndex > 0)
{
buffer.SkipBytes(delimiterIndex);
return;
}
if (buffer.ReadableBytes < frameLengthIndex)
{
// 数据不足,等待更多数据
return;
}
// 读取长度字段
int frameLength = buffer.GetUnsignedShortLE(buffer.ReaderIndex + frameLengthIndex);
if (buffer.ReadableBytes < frameLength)
{
// 数据不足,等待更多数据
return;
}
var msg = Parse(buffer, frameLength);
output.Add(msg);
buffer.Clear();
}
}
private BaseMsg Parse(IByteBuffer buffer, int length)
{
byte[] data = new byte[length];
buffer.ReadBytes(data);
return data[5] switch
{
0x01 => ModelConvert.Decode<ElecMsg>(data),
0x03 => ModelConvert.Decode<HeartBeatMsg>(data),
0x06 => ModelConvert.Decode<LockMsgResp>(data),
0x08 => ModelConvert.Decode<UnLockMsgResp>(data),
0x10 => ModelConvert.Decode<SettleConfirmMsgResp>(data),
0x12 => ModelConvert.Decode<SetParamMsgResp>(data),
_ => new BaseMsg()
};
}
private IByteBuffer? FindDelimiter(IByteBuffer buffer)
{
foreach (IByteBuffer delimiter in _delimiters)
{
int delimiterIndex = IndexOf(buffer, delimiter);
if (delimiterIndex >= 0)
{
return delimiter;
}
}
return null;
}
private static int IndexOf(IByteBuffer haystack, IByteBuffer needle)
{
for (int i = haystack.ReaderIndex; i < haystack.WriterIndex; i++)
{
int num = i;
int j;
for (j = 0; j < needle.Capacity && haystack.GetByte(num) == needle.GetByte(j); j++)
{
num++;
if (num == haystack.WriterIndex && j != needle.Capacity - 1)
{
return -1;
}
}
if (j == needle.Capacity)
{
return i - haystack.ReaderIndex;
}
}
return -1;
}
}