using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.InteropServices;
using TouchSocket.Core.ByteManager;
using TouchSocket.Sockets;
namespace Rdh.SocketServer.Client.Models
{
public class RfidUdpDataHandlingAdapter : UdpDataHandlingAdapter
{
public override bool CanSendRequestInfo => false;
public override bool CanSplicingSend => false;
public int HeaderLength => 5;
///
/// 临时包,此包仅当前实例储存
///
private ByteBlock tempByteBlock;
///
/// 包剩余长度
///
private byte surPlusLength;
protected override void PreviewReceived(EndPoint remoteEndPoint, ByteBlock byteBlock)
{
byte[] buffer = byteBlock.Buffer;
int r = byteBlock.Len;
if (this.tempByteBlock == null)//如果没有临时包,则直接分包。
{
SplitPackage(remoteEndPoint, buffer, 0, r);
}
else
{
if (surPlusLength == r)//接收长度正好等于剩余长度,组合完数据以后直接处理数据。
{
this.tempByteBlock.Write(buffer, 0, surPlusLength);
PreviewHandle(remoteEndPoint, this.tempByteBlock);
this.tempByteBlock = null;
surPlusLength = 0;
}
else if (surPlusLength < r)//接收长度大于剩余长度,先组合包,然后处理包,然后将剩下的分包。
{
this.tempByteBlock.Write(buffer, 0, surPlusLength);
PreviewHandle(remoteEndPoint, this.tempByteBlock);
this.tempByteBlock = null;
SplitPackage(remoteEndPoint, buffer, surPlusLength, r);
}
else//接收长度小于剩余长度,无法处理包,所以必须先组合包,然后等下次接收。
{
this.tempByteBlock.Write(buffer, 0, r);
surPlusLength -= (byte)r;
}
}
}
///
/// 分解包
///
///
///
///
private void SplitPackage(EndPoint remoteEndPoint, byte[] dataBuffer, int index, int r)
{
while (index < r)
{
byte length = dataBuffer[index];
int recedSurPlusLength = r - index - 1;
if (recedSurPlusLength >= length)
{
ByteBlock byteBlock = BytePool.GetByteBlock(length);
byteBlock.Write(dataBuffer, index + 1, length);
PreviewHandle(remoteEndPoint, byteBlock);
surPlusLength = 0;
}
else//半包
{
this.tempByteBlock = BytePool.GetByteBlock(length);
surPlusLength = (byte)(length - recedSurPlusLength);
this.tempByteBlock.Write(dataBuffer, index + 1, recedSurPlusLength);
}
index += length + 1;
}
}
///
/// 处理数据
///
///
private void PreviewHandle(EndPoint remoteEndPoint, ByteBlock byteBlock)
{
try
{
var requestInfo = new RfidFixedHeaderRequestInfo();
byteBlock.Read(out byte[] header, this.HeaderLength);
requestInfo.OnParsingHeader(header);
byteBlock.Read(out byte[] body, requestInfo.BodyLength);
requestInfo.OnParsingBody(body);
this.GoReceived(remoteEndPoint, byteBlock, requestInfo);
}
finally
{
byteBlock.Dispose();//在框架里面将内存块释放
}
}
protected override void Reset()
{
}
protected override void PreviewSend(EndPoint endPoint, byte[] buffer, int offset, int length, bool isAsync)
{
this.GoSend(endPoint, buffer, offset, length, isAsync);
}
protected override void PreviewSend(IRequestInfo requestInfo, bool isAsync)
{
}
protected override void PreviewSend(EndPoint endPoint, IList> transferBytes, bool isAsync)
{
throw new System.NotImplementedException();
}
}
public class RfidFixedHeaderRequestInfo : IFixedHeaderRequestInfo
{
private const int head = 0xA5;
///
/// 数据包头
///
public static int Head { get { return head; } }
private int bodyLength;
public int BodyLength
{
get { return bodyLength; }
}
private byte[] reserved;
///
/// 485地址码
///
public byte[] Reserved { get { return reserved; } }
private int cmd;
///
/// 指令码
///
public int CMD { get { return cmd; } }
private byte[] header;
public byte[] Header { get { return header; } }
private byte[] body;
public byte[] Body
{
get { return body; }
}
public bool OnParsingBody(byte[] body)
{
this.bodyLength = body.Length;
this.body = body;
return true;
}
public bool OnParsingHeader(byte[] header)
{
if (header.Length == 5 && header[0] == 0xA5)
{
this.bodyLength = header[1];
this.reserved = new byte[2];
Buffer.BlockCopy(header, 2, this.reserved, 0, 2);
this.cmd = header[4];
this.header = header;
return true;
}
return false;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MtBarcodeResponseProtocol
{
#region Properties
///
/// 起始位
///
public Byte Head { get { return 0xA5; } }
///
/// Length(不含)之后的数据长度
///
public Byte Length { get; set; }
///
/// 低字节在前,高字节在后
///
public UInt16 Password { get; set; }
///
/// 指令码
///
public Byte Command { get; set; }
///
/// 0x01:数据包标识
///
public Byte Flags { get; set; }
///
/// 读取的频点
///
public Byte Frequency { get; set; }
///
/// 天线号
///
public Byte Anntennea { get; set; }
///
/// 标签的 PC 协议控制字,固定 2Byte
///
public UInt16 PC { get; set; }
///
/// 标签的 EPC 号(条码),长度可变化
///
public String EPC { get; set; }
///
/// 标签的 CRC,固定 2Byte
///
public UInt16 CRC { get; set; }
///
/// 标签的实时 RSSI,固定 2Byte
///
public UInt16 RSSI { get; set; }
///
/// 校验和(除校验本身以外所有字节求和后,按位取反,再加 1)
///
public Byte Check { get; set; }
#endregion
public Byte[] GetBytes()
{
return StructToBytes(this);
}
public override string ToString()
{
return ToString(" ");
}
public String ToString(String seperator)
{
return String.Join(seperator, GetBytes());
}
public static MtBarcodeResponseProtocol? ReadFromBytes(Byte[] source, Int32 dataLength)
{
if (dataLength < 16 || source.Length < 16)
{
return null;
}
MtBarcodeResponseProtocol rlt = new MtBarcodeResponseProtocol();
rlt.Length = source[1];
rlt.Password = (UInt16)(source[2] | (source[3] << 8));
rlt.Command = source[4];
rlt.Flags = source[5];
rlt.Frequency = source[6];
rlt.Anntennea = source[7];
rlt.PC = (UInt16)(source[8] | (source[9] << 8));
Int32 epcDataLength = rlt.Length - 13;
for (Int32 i = 0; i < epcDataLength; i++)
{
rlt.EPC += source[10 + i].ToString("X2");
}
rlt.Check = source[dataLength - 1];
rlt.RSSI = (UInt16)(source[dataLength - 2] << 8 | source[dataLength - 3]);
rlt.CRC = (UInt16)(source[dataLength - 4] | source[dataLength - 5]);
return rlt;
}
public static MtBarcodeResponseProtocol? ReadFromBytes(Byte[] source)
{
var dataLength = source.Length;
if (dataLength < 16 || source.Length < 16)
{
return null;
}
MtBarcodeResponseProtocol rlt = new MtBarcodeResponseProtocol();
rlt.Length = source[1];
rlt.Password = (UInt16)(source[2] | (source[3] << 8));
rlt.Command = source[4];
rlt.Flags = source[5];
rlt.Frequency = source[6];
rlt.Anntennea = source[7];
rlt.PC = (UInt16)(source[8] | (source[9] << 8));
Int32 epcDataLength = rlt.Length - 13;
for (Int32 i = 0; i < epcDataLength; i++)
{
rlt.EPC += source[10 + i].ToString("X2");
}
rlt.Check = source[dataLength - 1];
rlt.RSSI = (UInt16)(source[dataLength - 2] << 8 | source[dataLength - 3]);
rlt.CRC = (UInt16)(source[dataLength - 4] | source[dataLength - 5]);
return rlt;
}
public static byte[] StructToBytes(T structObj)
{
int size = Marshal.SizeOf(structObj);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structObj, buffer, false);
byte[] bytes = new byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
}
}