|
|
using System;
|
|
|
using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Configuration;
|
|
|
using System.Linq;
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
//using System.Threading.Tasks;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using TouchSocket.Core;
|
|
|
using TouchSocket.Sockets;
|
|
|
|
|
|
namespace Mesnac.DeviceAdapter.RFly_I160
|
|
|
{
|
|
|
[ClassInterface(ClassInterfaceType.None)]
|
|
|
public class RFly_I160Adapter : IDeviceAdapter
|
|
|
{
|
|
|
public log4net.ILog LogInfo = log4net.LogManager.GetLogger("RollingLogFileAppender"); //Logging 名字要在 App.config 中能找到
|
|
|
|
|
|
#region 全局变量声明
|
|
|
private DeviceType m_iDeviceType = DeviceType.RFly_I160;
|
|
|
ICommunicateService m_ICommunicateService = null;
|
|
|
public event RecvIdentifyData RecvIdentifyDataEvent = null;
|
|
|
public event RecvIdentifyData RecvIdentifyData_ToMES_Event;
|
|
|
|
|
|
public UInt16 m_iDeviceId = 0;
|
|
|
private string m_strIp; //读写器IP或串口号
|
|
|
private int m_iPort; //读写器端口号或波特率
|
|
|
private readonly string m_ReadDbm = ConfigurationManager.AppSettings["ReadDbm"];
|
|
|
private readonly string m_WriteDbm = ConfigurationManager.AppSettings["WriteDbm"];
|
|
|
private readonly string m_AnalysisFlag = ConfigurationManager.AppSettings["AnalysisFlag"]; //1:按照次数最多返回条码;2:按照平均功率最大返回条码
|
|
|
//private Mutex mut = new Mutex();
|
|
|
private ManualResetEvent BeginEvent = new ManualResetEvent(true);
|
|
|
|
|
|
public bool TagInventory_Lable = true;//连续盘点标签标志
|
|
|
|
|
|
private Semaphore m_GlobalSem = new Semaphore(1, 1);
|
|
|
private bool m_GetHeartSuccessful = false;
|
|
|
private Semaphore m_GetHeartSem = new Semaphore(0, 100000);
|
|
|
|
|
|
//private ManualResetEvent m_GetHeartSem = new ManualResetEvent(false);
|
|
|
|
|
|
private Semaphore m_MulEpcSem = new Semaphore(0, 100000);
|
|
|
private Semaphore m_StopSem = new Semaphore(0, 100000);
|
|
|
|
|
|
private bool m_OneEpcSemSuccessful = false;
|
|
|
private Semaphore m_OneEpcSem = new Semaphore(0, 100000);
|
|
|
|
|
|
private bool m_WriteAlarmSemSuccessful = false;
|
|
|
private Semaphore m_WriteAlarmSem = new Semaphore(0, 100000);
|
|
|
|
|
|
private bool m_ReadDataSuccessful = false;
|
|
|
private bool m_Device_ReadSuccessful = false;
|
|
|
private byte m_ReadDataLen = 0;
|
|
|
private byte[] m_ReadData = null;
|
|
|
private Semaphore m_ReadSem = new Semaphore(0, 100000);
|
|
|
|
|
|
private int m_BarcodeGroupCount = 0;
|
|
|
private byte[] m_MulAllData = null;
|
|
|
private byte[] m_AutoReadEPC = null;
|
|
|
private int m_readEPCDataLen = 0;
|
|
|
private byte m_OneEpcDataLen = 0;
|
|
|
private byte m_OneEpcAntenna = 254;
|
|
|
private byte[] m_OneEpcData = null;
|
|
|
private bool m_GetReadNoDataSuccessful;
|
|
|
public readonly TouchSocket.Sockets.TcpClient _tcpClient = new TouchSocket.Sockets.TcpClient();
|
|
|
List<TagInfo> tagInfos = null;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
public int AutoReport
|
|
|
{
|
|
|
get { return AutoReport; }
|
|
|
set { AutoReport = value; }
|
|
|
}
|
|
|
|
|
|
public int Filter
|
|
|
{
|
|
|
get { return Filter; }
|
|
|
set { Filter = value; }
|
|
|
}
|
|
|
|
|
|
#region 设备连接部分
|
|
|
public bool Device_Init(CommType iCommType, string pUrl, DeviceType iDeviceType)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
m_iDeviceType = iDeviceType;
|
|
|
// LogInfo.Info("函数调用:Device_Init Start: ");
|
|
|
//if (iDeviceType == DeviceType.Mesnac_GRUV100)
|
|
|
{
|
|
|
if (iCommType == CommType.RJ45) //网口
|
|
|
{
|
|
|
if (m_ICommunicateService == null)
|
|
|
{
|
|
|
m_ICommunicateService = new BgTcpClient();
|
|
|
}
|
|
|
|
|
|
string[] split = pUrl.Split(new Char[] { ':' });
|
|
|
m_strIp = split[0];
|
|
|
string strTemp = split[1];
|
|
|
m_iPort = Convert.ToInt32(strTemp);
|
|
|
//m_ICommunicateService.Init(m_strIp, m_iPort, this, m_iDeviceId);
|
|
|
// LogInfo.Info("设备初始化成功,IP:" + m_strIp + "端口号:" + m_iPort);
|
|
|
}
|
|
|
else //串口,代用串口号和波特率
|
|
|
{
|
|
|
if (m_ICommunicateService == null)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
string[] split = pUrl.Split(new Char[] { ':' });
|
|
|
m_strIp = split[0];
|
|
|
string strTemp = split[1];
|
|
|
m_iPort = Convert.ToInt32(strTemp);
|
|
|
//m_ICommunicateService.Init(m_strIp, m_iPort, this, m_iDeviceId);
|
|
|
LogInfo.Info("设备初始化成功,串口号:" + m_strIp + "波特率:" + m_iPort);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Fatal("IP:" + m_strIp + "端口号:" + m_iPort + "连接读写器异常:" + ex.Message);
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
public bool Device_Init_Id(CommType iCommType, string pUrl, ushort iDeviceId)
|
|
|
{
|
|
|
m_iDeviceId = iDeviceId;
|
|
|
Device_Init(iCommType, pUrl, (DeviceType)1);
|
|
|
return true;
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 获取设备在线状态
|
|
|
/// </summary>
|
|
|
/// <param name="ip"></param>
|
|
|
/// <param name="port"></param>
|
|
|
/// <returns></returns>
|
|
|
public bool GetOnlineStatus()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
return _tcpClient.Online;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public bool Device_Connect()
|
|
|
{
|
|
|
byte bAntana = 0; //读写器天线号 默认0x04
|
|
|
UInt16 iReadCount = 0; //标签读取次数
|
|
|
UInt16 iRSSI = 0; //标签信号强度
|
|
|
byte[] bResultEPC_Data = new byte[12];
|
|
|
byte[] bNoData = new byte[12];
|
|
|
try
|
|
|
{
|
|
|
_tcpClient.Setup(new TouchSocketConfig().SetRemoteIPHost($"{m_strIp}:{m_iPort}"));
|
|
|
_tcpClient.Connect();
|
|
|
|
|
|
_tcpClient.Received = (client, e) =>
|
|
|
{
|
|
|
//从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
|
|
|
var mes = e.ByteBlock.Span.ToArray();
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(mes, mes.Length));
|
|
|
byte[] ValidData = PareReceiveData(mes, mes.Length);
|
|
|
switch (ValidData[3])
|
|
|
{
|
|
|
//GPIO
|
|
|
case 0x51:
|
|
|
m_WriteAlarmSemSuccessful = true;
|
|
|
m_WriteAlarmSem.Release();
|
|
|
break;
|
|
|
}
|
|
|
if (ValidData[0] == 0XBB && ValidData[1] == 0XDD && ValidData[2] == 0X00 && ValidData[3] == 0x02) //超时 02 4E 6F 52 65 61 64 03
|
|
|
{
|
|
|
// LogInfo.Info("----函数调用:Device_DealValidPack:NoRead!");
|
|
|
m_BarcodeGroupCount = 0;
|
|
|
m_GetReadNoDataSuccessful = true;
|
|
|
|
|
|
if (m_GetReadNoDataSuccessful && m_ReadDataSuccessful == false)
|
|
|
{
|
|
|
bAntana = 1;
|
|
|
m_AutoReadEPC = null;
|
|
|
m_GetReadNoDataSuccessful = false;
|
|
|
this.RecvIdentifyDataEvent(0, null, bAntana, m_iDeviceId, m_strIp, "1");
|
|
|
}
|
|
|
}
|
|
|
if (ValidData[0] == 0XBB && ValidData[1] == 0XDD && ValidData[2] != 0X00 && ValidData[3] != 0XBF) //正常有数据
|
|
|
{
|
|
|
m_BarcodeGroupCount = Convert.ToInt32(ValidData[5].ToString("X2")); //标签组数TagCount
|
|
|
m_MulAllData = new byte[ValidData.Length];
|
|
|
Array.Clear(m_MulAllData, 0, ValidData.Length);
|
|
|
Array.Copy(ValidData, 0, m_MulAllData, 0, ValidData.Length);
|
|
|
|
|
|
Array.Copy(m_MulAllData, 11, bResultEPC_Data, 0, 12);
|
|
|
|
|
|
|
|
|
|
|
|
bAntana = ValidData[8];
|
|
|
m_OneEpcAntenna = ValidData[8];
|
|
|
iReadCount = ValidData[6];
|
|
|
iRSSI = ValidData[7];
|
|
|
|
|
|
//Device_AutoDealContent(m_MulAllData);
|
|
|
tagInfos = GetTagInfos(m_MulAllData);
|
|
|
m_ReadDataLen = (byte)tagInfos.Count;
|
|
|
m_OneEpcDataLen = (byte)tagInfos.Count;
|
|
|
//m_OneEpcData = new byte[m_OneEpcDataLen];
|
|
|
if (RecvIdentifyDataEvent != null)
|
|
|
{
|
|
|
if (m_ReadDataSuccessful == false)
|
|
|
{
|
|
|
this.RecvIdentifyDataEvent.Invoke(Convert.ToUInt16(Convert.ToUInt16(tagInfos.Count)), tagInfos, bAntana, m_iDeviceId, m_strIp, "1");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcSem.Release();
|
|
|
m_ReadSem.Release();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return EasyTask.CompletedTask;
|
|
|
};
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
if (m_ICommunicateService != null)
|
|
|
{
|
|
|
if (m_ICommunicateService.Connect())
|
|
|
{
|
|
|
// LogInfo.Info("Device_Connect:连接成功");
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//LogInfo.Info("设备初始化成功,IP:" + m_strIp + "端口号:" + m_iPort);
|
|
|
LogInfo.Fatal("IP:" + m_strIp + "端口号: " + m_iPort + ",Device_Connect:连接失败");
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Fatal("IP:" + m_strIp + "端口号: " + m_iPort + ",Device_Connect:连接失败,"+ex.Message);
|
|
|
//LogInfo.Info("Device_Connect异常:" + ex.Message);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void Device_Destroy()
|
|
|
{
|
|
|
m_ICommunicateService.DisConnect();
|
|
|
}
|
|
|
|
|
|
public bool Device_GetState()
|
|
|
{
|
|
|
return m_ICommunicateService.GetState();
|
|
|
}
|
|
|
|
|
|
public bool Device_ReConnect()
|
|
|
{
|
|
|
LogInfo.Fatal("IP:" + m_strIp + "端口号: " + m_iPort + ",Device_ReConnect:调用重连函数");
|
|
|
return Device_Connect();
|
|
|
}
|
|
|
#endregion
|
|
|
public bool Device_DealValidPack(byte[] ValidData)
|
|
|
{
|
|
|
byte bAntana = 0; //读写器天线号 默认0x04
|
|
|
UInt16 iReadCount = 0; //标签读取次数
|
|
|
UInt16 iRSSI = 0; //标签信号强度
|
|
|
byte[] bResultEPC_Data = new byte[12];
|
|
|
byte[] bNoData = new byte[12];
|
|
|
// LogInfo.Info("----函数调用:Device_DealValidPack 开始!");
|
|
|
try
|
|
|
{
|
|
|
switch (ValidData[3]) //心跳
|
|
|
{
|
|
|
case 0X00:
|
|
|
if (ValidData[2] == 0X01 && ValidData[3] == 0X00) //成功
|
|
|
{
|
|
|
m_GetHeartSuccessful = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_GetHeartSuccessful = false;
|
|
|
}
|
|
|
m_GetHeartSem.Release();
|
|
|
break;
|
|
|
//GPIO返回
|
|
|
case 0X51:
|
|
|
m_WriteAlarmSemSuccessful = true;
|
|
|
m_WriteAlarmSem.Release();
|
|
|
//this.RecvIdentifyDataEvent(1, null, bAntana, m_iDeviceId, m_strIp, "1");
|
|
|
break;
|
|
|
}
|
|
|
if (ValidData[0] == 0XBB && ValidData[1] == 0XDD && ValidData[2] == 0X00 && ValidData[3] == 0x02) //超时 02 4E 6F 52 65 61 64 03
|
|
|
{
|
|
|
// LogInfo.Info("----函数调用:Device_DealValidPack:NoRead!");
|
|
|
m_BarcodeGroupCount = 0;
|
|
|
m_GetReadNoDataSuccessful = true;
|
|
|
|
|
|
//m_MulEpcSem.Release();
|
|
|
if (m_GetReadNoDataSuccessful && m_ReadDataSuccessful == false)
|
|
|
{
|
|
|
bAntana = 4;
|
|
|
m_AutoReadEPC = null;
|
|
|
m_GetReadNoDataSuccessful = false;
|
|
|
this.RecvIdentifyDataEvent(0, null, bAntana, m_iDeviceId, m_strIp,"1");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcSem.Release();
|
|
|
}
|
|
|
}
|
|
|
if (ValidData[0] == 0XBB && ValidData[1] == 0XDD && ValidData[2] != 0X00 && ValidData[3] != 0XBF) //正常有数据
|
|
|
{
|
|
|
|
|
|
// LogInfo.Info("----函数调用:Device_DealValidPack 有数据!");
|
|
|
|
|
|
m_BarcodeGroupCount = Convert.ToInt32(ValidData[5].ToString("X2")); //标签组数TagCount
|
|
|
m_MulAllData = new byte[ValidData.Length];
|
|
|
Array.Clear(m_MulAllData, 0, ValidData.Length);
|
|
|
Array.Copy(ValidData, 0, m_MulAllData, 0, ValidData.Length);
|
|
|
|
|
|
Array.Copy(m_MulAllData, 11, bResultEPC_Data, 0, 12);
|
|
|
|
|
|
|
|
|
|
|
|
bAntana = ValidData[8];
|
|
|
m_OneEpcAntenna = ValidData[8];
|
|
|
iReadCount = ValidData[6];
|
|
|
iRSSI = ValidData[7];
|
|
|
|
|
|
//Device_AutoDealContent(m_MulAllData);
|
|
|
tagInfos = GetTagInfos(m_MulAllData);
|
|
|
m_ReadDataLen = (byte)tagInfos.Count;
|
|
|
m_OneEpcDataLen = (byte)tagInfos.Count;
|
|
|
//m_OneEpcData = new byte[m_OneEpcDataLen];
|
|
|
if (RecvIdentifyDataEvent != null)
|
|
|
{
|
|
|
if (m_ReadDataSuccessful == false)
|
|
|
{
|
|
|
|
|
|
//this.RecvIdentifyDataEvent.Invoke(Convert.ToUInt16(Convert.ToUInt16(m_readEPCDataLen)), tagInfos, bAntana, m_iDeviceId, m_strIp,"1");
|
|
|
this.RecvIdentifyDataEvent.Invoke(Convert.ToUInt16(Convert.ToUInt16(tagInfos.Count)), tagInfos, bAntana, m_iDeviceId, m_strIp,"1");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcSem.Release();
|
|
|
m_ReadSem.Release();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_DealValidPack异常:" + ex.Message);
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
public async Task<byte> Device_SendHeartPackAsync(CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
|
|
|
// 使用 ManualResetEventSlim 替代 SemaphoreSlim,支持异步等待
|
|
|
await Task.Factory.StartNew(
|
|
|
() => m_GlobalSem.WaitOne(),
|
|
|
cancellationToken,
|
|
|
TaskCreationOptions.None,
|
|
|
TaskScheduler.Default
|
|
|
);
|
|
|
|
|
|
// 创建心跳包
|
|
|
var messagePack = new MessagePack
|
|
|
{
|
|
|
m_pData = new byte[9] { 0xAA, 0x55, 0x00, 0x90, 0x90, 0x0D, 0x00, 0x00, 0x0D }
|
|
|
};
|
|
|
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
|
|
|
{
|
|
|
FilterFunc = response =>
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
});
|
|
|
byte[] reciveBuffer = waitClient.SendThenReturn(messagePack.m_pData, 2000);
|
|
|
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(reciveBuffer, reciveBuffer.Length));
|
|
|
byte[] message = PareReceiveData(reciveBuffer, reciveBuffer.Length);
|
|
|
|
|
|
return 1;
|
|
|
// 检查通信服务
|
|
|
if (m_ICommunicateService == null)
|
|
|
{
|
|
|
LogInfo.Error("Communication service is not initialized.");
|
|
|
return 2; // 通讯连接器失败或网络故障
|
|
|
}
|
|
|
|
|
|
// 发送心跳包
|
|
|
bool sendSuccess = await Task.Factory.StartNew(
|
|
|
() => m_ICommunicateService.SendMessage(messagePack),
|
|
|
cancellationToken,
|
|
|
TaskCreationOptions.None,
|
|
|
TaskScheduler.Default
|
|
|
);
|
|
|
|
|
|
if (!sendSuccess)
|
|
|
{
|
|
|
LogInfo.Warn("Failed to send heartbeat message.");
|
|
|
return 2; // 通讯连接器失败或网络故障
|
|
|
}
|
|
|
// 使用 WaitHandle.WaitOne 的超时机制
|
|
|
var waitTask = Task.Factory.StartNew(
|
|
|
() => m_GetHeartSem.WaitOne(2000, false),
|
|
|
cancellationToken,
|
|
|
TaskCreationOptions.None,
|
|
|
TaskScheduler.Default
|
|
|
);
|
|
|
|
|
|
// 不需要第二个超时,直接等待任务完成
|
|
|
await waitTask;
|
|
|
|
|
|
if (waitTask.Result)
|
|
|
{
|
|
|
LogInfo.Debug("Heartbeat response received successfully.");
|
|
|
return 1; // 通讯连接和读写器都正常
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 处理超时的情况
|
|
|
LogInfo.Warn("Heartbeat response timed out after 2000ms.");
|
|
|
return 2; // 或者抛出异常,取决于你的需求
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
catch (OperationCanceledException)
|
|
|
{
|
|
|
LogInfo.Info("Heartbeat operation was canceled.");
|
|
|
return 2;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Error($"Exception in Device_SendHeartPackAsync: {ex.Message}");
|
|
|
return 2; // 发生异常,返回通讯故障
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
// 确保信号量总是被释放
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
catch (ApplicationException ex)
|
|
|
{
|
|
|
LogInfo.Error("Global semaphore was already released.");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
public byte Device_SendHeartPack()
|
|
|
{
|
|
|
byte iResult = 0;
|
|
|
try
|
|
|
{
|
|
|
// LogInfo.Info("函数调用:Device_SendHeartPack");
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
pMessagePack.m_pData = new byte[9];
|
|
|
Array.Clear(pMessagePack.m_pData, 0, 1);//清空为0
|
|
|
//获取温度
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x00;
|
|
|
pMessagePack.m_pData[3] = 0x90;
|
|
|
pMessagePack.m_pData[4] = 0x90;
|
|
|
pMessagePack.m_pData[5] = 0x0D;
|
|
|
//pMessagePack.m_pData[0] = 0xAA;
|
|
|
//pMessagePack.m_pData[1] = 0x55;
|
|
|
//pMessagePack.m_pData[2] = 0x03;
|
|
|
//pMessagePack.m_pData[3] = 0xBF;
|
|
|
//pMessagePack.m_pData[4] = 0x01;
|
|
|
//pMessagePack.m_pData[5] = 0x0A;
|
|
|
//pMessagePack.m_pData[6] = 0x01;
|
|
|
//pMessagePack.m_pData[7] = 0xB6;
|
|
|
//pMessagePack.m_pData[8] = 0x0D;
|
|
|
m_GetHeartSem.WaitOne(1, false);
|
|
|
if (m_ICommunicateService != null)
|
|
|
{
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
if (m_GetHeartSem.WaitOne(2000, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
// LogInfo.Info("发送心跳报文正常。");
|
|
|
iResult = 1; //通讯连接和读写器都正常
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
//LogInfo.Info("发送心跳报文超时。");
|
|
|
iResult = 2; //通讯连接器正常,读写器故障
|
|
|
};
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//通讯连接器失败或网络故障
|
|
|
//LogInfo.Info("发送心跳报文失败,通讯故障。");
|
|
|
iResult = 3;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return 3;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_SendHeartPack:" + ex.Message);
|
|
|
iResult = 3;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return iResult;
|
|
|
}
|
|
|
public ushort Device_GetReportData(ref byte[] pReadData, Byte Antenna, UInt32 Timedout)
|
|
|
{
|
|
|
byte[] pTemp = null;
|
|
|
byte iReadLen = 0;
|
|
|
if ((iReadLen = Device_GetOneIdentifyData(ref pTemp, Antenna, (UInt16)Timedout,0)) > 0)
|
|
|
{
|
|
|
LogInfo.Info("Device_GetReportData获取自报数据" + "数据长度" + iReadLen);
|
|
|
pReadData = new byte[iReadLen + 1];
|
|
|
pReadData[0] = iReadLen;
|
|
|
Array.Copy(pTemp, 0, pReadData, 1, iReadLen);
|
|
|
return (ushort)(iReadLen + 1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据天线号识别单个标签EPC数据,只返回读到的第一条数据
|
|
|
/// </summary>
|
|
|
/// <returns>识别的标签EPC长度,0为识别失败</returns>
|
|
|
/// <param name="pReadData">识别到的数据缓存区</param>
|
|
|
/// <param name="Antenna">天线号,0为本机,255为所有天线</param>
|
|
|
/// <param name="Timedout">超时时间,单位毫秒,识别到立即返回,未识别到等待超时返回</param>
|
|
|
public Byte Device_GetOneIdentifyData(ref Byte[] pReadData, Byte Antenna, UInt16 Timedout, int ReadCounts)
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte iResult = 0;
|
|
|
byte[] bCRC = new byte[4];
|
|
|
string s_CompareData1 = "";
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
// LogInfo.Info("函数调用:Device_GetOneIdentifyData");
|
|
|
if (Antenna == 0) //此版本4为主机
|
|
|
{
|
|
|
Antenna = (byte)(Antenna + 4);
|
|
|
}
|
|
|
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
|
|
|
//A5 5A 00 0A 80 00 64 EE 0D 0A //100毫秒的示例
|
|
|
pMessagePack.m_pData = new byte[8];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x02;
|
|
|
pMessagePack.m_pData[3] = 0x02;
|
|
|
//pMessagePack.m_pData[4] = 0x03;
|
|
|
//pMessagePack.m_pData[5] = 0xE8;
|
|
|
u16byte = BitConverter.GetBytes(Timedout); //超时时间
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
// LogInfo.Info("u16byte:" + u16byte);
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2);
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4);
|
|
|
pMessagePack.m_pData[6] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[7] = 0x0D;
|
|
|
// LogInfo.Info("pMessagePack.m_pData:" + pMessagePack.m_pData);
|
|
|
//int i = m_OneEpcSem.Release(1);
|
|
|
m_OneEpcSem.WaitOne(1, false);
|
|
|
m_OneEpcDataLen = 0;
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
m_ReadDataSuccessful = true;
|
|
|
if (m_OneEpcSem.WaitOne(Timedout + 500, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
if (m_OneEpcDataLen > 0) //有数据,正常
|
|
|
{
|
|
|
pReadData = new byte[m_OneEpcDataLen];
|
|
|
Array.Copy(m_AutoReadEPC, 0, pReadData, 0, m_OneEpcDataLen);
|
|
|
// LogInfo.Info("Device_GetOneIdentifyData:" + StringChange.bytesToHexStr(pReadData, pReadData.Length));
|
|
|
iResult = m_OneEpcDataLen;
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
//开始对比过滤数据
|
|
|
//s_CompareData1 = Encoding.ASCII.GetString(pReadData, 0, FilterData.Length);
|
|
|
|
|
|
//if (s_CompareData1 == FilterData)
|
|
|
//{
|
|
|
// iResult = m_OneEpcDataLen;
|
|
|
// m_OneEpcDataLen = 0;
|
|
|
// m_OneEpcAntenna = 254;
|
|
|
// m_ReadDataSuccessful = false;
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// LogInfo.Info("Device_GetOneIdentifyData对比数据不匹配");
|
|
|
// iResult = 0;
|
|
|
// m_OneEpcDataLen = 0;
|
|
|
// m_OneEpcAntenna = 254;
|
|
|
// m_ReadDataSuccessful = false;
|
|
|
//}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//LogInfo.Info("Device_GetOneIdentifyData长度不正确");
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
iResult = 0;
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
//LogInfo.Info("Device_GetOneIdentifyData超时");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
LogInfo.Info("Device_GetOneIdentifyData发送识别单条EPC命令失败:");
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_GetOneIdentifyData识别单条EPC数据异常:" + ex.Message);
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return iResult;
|
|
|
}
|
|
|
|
|
|
public List<TagInfo> Device_GetAllIdentifyData(Byte Antenna, UInt16 Timedout, int ReadCounts)
|
|
|
{
|
|
|
List<TagInfo> tagInfo = new List<TagInfo>();
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte iResult = 0;
|
|
|
byte[] bCRC = new byte[4];
|
|
|
string s_CompareData1 = "";
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
// LogInfo.Info("函数调用:Device_GetOneIdentifyData");
|
|
|
if (Antenna == 0) //此版本4为主机
|
|
|
{
|
|
|
Antenna = (byte)(Antenna + 4);
|
|
|
}
|
|
|
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
|
|
|
//A5 5A 00 0A 80 00 64 EE 0D 0A //100毫秒的示例
|
|
|
pMessagePack.m_pData = new byte[8];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x02;
|
|
|
pMessagePack.m_pData[3] = 0x02;
|
|
|
//pMessagePack.m_pData[4] = 0x03;
|
|
|
//pMessagePack.m_pData[5] = 0xE8;
|
|
|
u16byte = BitConverter.GetBytes(Timedout); //超时时间
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
// LogInfo.Info("u16byte:" + u16byte);
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2);
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4);
|
|
|
pMessagePack.m_pData[6] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[7] = 0x0D;
|
|
|
// LogInfo.Info("pMessagePack.m_pData:" + pMessagePack.m_pData);
|
|
|
//int i = m_OneEpcSem.Release(1);
|
|
|
m_OneEpcSem.WaitOne(1, false);
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_ReadDataSuccessful = true;
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",发送原始报文:" + bytesToHexStr(pMessagePack.m_pData, pMessagePack.m_pData.Length));
|
|
|
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
|
|
|
{
|
|
|
FilterFunc = response =>
|
|
|
{
|
|
|
// 检查响应数据是否符合预期
|
|
|
if (response.ByteBlock != null && response.ByteBlock.Length > 0)
|
|
|
{
|
|
|
// 可以根据实际情况添加更多的检查逻辑
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(response.ByteBlock.ToArray(0, response.ByteBlock.Length), response.ByteBlock.Length));
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
});
|
|
|
byte[] reciveBuffer = waitClient.SendThenReturn(pMessagePack.m_pData, 1000 * 2);//设置10秒超时
|
|
|
//Console.WriteLine($"收到回应消息:{bytesToHexStr(reciveBuffer, reciveBuffer.Length)}");
|
|
|
|
|
|
byte[] message = PareReceiveData(reciveBuffer, reciveBuffer.Length);
|
|
|
List<TagInfo> tags = GetTagInfos(message);
|
|
|
if (tags != null && tags.Count > 0)
|
|
|
{
|
|
|
return tags;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return new List<TagInfo>();
|
|
|
}
|
|
|
|
|
|
//_tcpClient.Send(pMessagePack.m_pData);
|
|
|
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
m_ReadDataSuccessful = true;
|
|
|
if (m_OneEpcSem.WaitOne(Timedout + 500, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
if (m_OneEpcDataLen > 0) //有数据,正常
|
|
|
{
|
|
|
tagInfo = tagInfos;
|
|
|
//Array.Copy(m_AutoReadEPC, 0, pReadData, 0, m_OneEpcDataLen);
|
|
|
// LogInfo.Info("Device_GetOneIdentifyData:" + StringChange.bytesToHexStr(pReadData, pReadData.Length));
|
|
|
iResult = m_OneEpcDataLen;
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
return tagInfo;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//LogInfo.Info("Device_GetOneIdentifyData长度不正确");
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
iResult = 0;
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
LogInfo.Info("Device_GetOneIdentifyData超时");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
LogInfo.Info("Device_GetOneIdentifyData发送识别单条EPC命令失败:");
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_GetOneIdentifyData识别单条EPC数据异常:" + m_iDeviceId + ",IP:" + m_strIp +","+ ex.Message);
|
|
|
iResult = 0;
|
|
|
m_ReadDataSuccessful = false;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_ReadDataSuccessful = false;
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return tagInfo;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public UInt16 Device_Read(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
|
|
|
G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, ref Byte[] pReadData, byte Antenna, int ReadCounts)
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte iResult = 0;
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
LogInfo.Info("函数调用:Device_Read");
|
|
|
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
pMessagePack.m_pData = new byte[8];
|
|
|
Array.Clear(pMessagePack.m_pData, 0, pMessagePack.m_pData.Length);//清空为0
|
|
|
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x02;
|
|
|
pMessagePack.m_pData[3] = 0x02;
|
|
|
pMessagePack.m_pData[4] = 0x03;
|
|
|
pMessagePack.m_pData[5] = 0xE8;
|
|
|
pMessagePack.m_pData[6] = 0xEB;
|
|
|
pMessagePack.m_pData[7] = 0x0D;
|
|
|
//m_ReadSem.Release(1);
|
|
|
m_ReadSem.WaitOne(1, false);
|
|
|
m_ReadDataLen = 0;
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
m_ReadDataSuccessful = true;
|
|
|
if (m_ReadSem.WaitOne(2000, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
if (m_ReadDataLen > 0) //有数据,正常
|
|
|
{
|
|
|
pReadData = new byte[m_ReadDataLen];
|
|
|
Array.Copy(m_OneEpcData, 0, pReadData, 0, m_ReadDataLen);
|
|
|
iResult = m_ReadDataLen;
|
|
|
LogInfo.Info("Device_Read:" + StringChange.bytesToHexStr(pReadData, pReadData.Length));
|
|
|
|
|
|
m_ReadDataLen = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_ReadDataLen = 0;
|
|
|
LogInfo.Info("Device_Read失败,返回长度为0");
|
|
|
iResult = 0;
|
|
|
}
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
LogInfo.Info("Device_Read失败,超时未返回");
|
|
|
iResult = 0;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
LogInfo.Info("发送读取命令失败");
|
|
|
iResult = 0;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("读取数据异常:" + ex.Message);
|
|
|
iResult = 0;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return iResult;
|
|
|
|
|
|
}
|
|
|
public UInt16 Device_Write(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
|
|
|
G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, Byte[] pWriteData, byte Antenna)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
public bool Device_WriteAlarmLight(int port, UInt16 Timedout)
|
|
|
{
|
|
|
bool iflag = false;
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte iResult = 0;
|
|
|
byte[] bCRC = new byte[6];
|
|
|
string s_CompareData1 = "";
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
// LogInfo.Info("函数调用:Device_GetOneIdentifyData");
|
|
|
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
|
|
|
//AA 55 04 51 02 00 00 00 57 0D //100毫秒的示例
|
|
|
pMessagePack.m_pData = new byte[10];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x04;
|
|
|
pMessagePack.m_pData[3] = 0x51;
|
|
|
pMessagePack.m_pData[4] = (byte)port;
|
|
|
pMessagePack.m_pData[5] = 0x00;
|
|
|
u16byte = BitConverter.GetBytes(Timedout); //超时时间
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
// LogInfo.Info("u16byte:" + u16byte);
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 6, 2);
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 6);
|
|
|
pMessagePack.m_pData[8] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[9] = 0x0D;
|
|
|
m_WriteAlarmSem.WaitOne(1, false);
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",发送原始报文:" + bytesToHexStr(pMessagePack.m_pData, pMessagePack.m_pData.Length));
|
|
|
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
|
|
|
{
|
|
|
FilterFunc = response =>
|
|
|
{
|
|
|
// 检查响应数据是否符合预期
|
|
|
if (response.ByteBlock != null && response.ByteBlock.Length > 0)
|
|
|
{
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(response.ByteBlock.ToArray(0, response.ByteBlock.Length), response.ByteBlock.Length));
|
|
|
// 可以根据实际情况添加更多的检查逻辑
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
});
|
|
|
byte[] bytes = waitClient.SendThenReturn(pMessagePack.m_pData, 1000 * 10);//设置10秒超时
|
|
|
//Console.WriteLine($"收到回应消息:{bytesToHexStr(bytes, bytes.Length)}");
|
|
|
if (bytes[2] == 0X00)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
//_tcpClient.Send(pMessagePack.m_pData);
|
|
|
if (m_WriteAlarmSem.WaitOne(500, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
if (m_WriteAlarmSemSuccessful)
|
|
|
{
|
|
|
iflag = true;
|
|
|
}
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
LogInfo.Info("超时");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info(m_iDeviceId + ",IP:" + m_strIp + "数据异常:" + ex.Message);
|
|
|
m_WriteAlarmSemSuccessful = false;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return iflag;
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 返回读写器获取的条码中最好的一条 1:按照读取次数最多返回条码;2:按照功率最大返回条码
|
|
|
/// </summary>
|
|
|
/// <param name="cBarcodeObjList">要处理的数据</param>
|
|
|
/// <param name="iFlag">1:按照读取次数最多返回条码;2:按照平均功率最大返回条码</param>
|
|
|
/// <param name="iPrintLogFlag">1:打印log;0:不打印Log</param>
|
|
|
/// <returns></returns>
|
|
|
public byte[] CommandAnalysisBarcode(List<TagInfo> cBarcodeObjList, int iFlag, int iPrintLogFlag)
|
|
|
{
|
|
|
byte[] tempBarcode = null;
|
|
|
if (iFlag == 1) //按次数最多获取
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("----调用通用函数:CommandAnalysisBarcode Flag=1 按照最大次数选择条码,如果次数相同 ,按照平均功率最大的选择条码:");
|
|
|
}
|
|
|
#region 按照最大次数选择条码,如果次数相同 ,按照平均功率最大的选择条码
|
|
|
#region 求出最大次数
|
|
|
int iOrderMaxCount = cBarcodeObjList[0].Count;
|
|
|
for (int i = 0; i < cBarcodeObjList.Count; i++)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
#region 打印所有条码 次数和平均功率
|
|
|
LogInfo.Info("条码:[ " + StringChange.bytesToHexStr(cBarcodeObjList[i].EPC, cBarcodeObjList[i].EPC.Length) + " ] 次数:[ " + cBarcodeObjList[i].Count.ToString() + " ] 平均最大功率: [" + cBarcodeObjList[i].RSSI.ToString() + " ]");
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
if (cBarcodeObjList[i].Count > iOrderMaxCount)
|
|
|
{
|
|
|
iOrderMaxCount = cBarcodeObjList[i].Count;
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("按照次数优先,最大次数为:" + iOrderMaxCount.ToString());
|
|
|
}
|
|
|
#endregion
|
|
|
#region 求出等于最大次数的所有条码对象
|
|
|
List<TagInfo> cBarcodeObjListCount = new List<TagInfo>();
|
|
|
foreach (TagInfo itemMax in cBarcodeObjList)
|
|
|
{
|
|
|
if (itemMax.Count == iOrderMaxCount)
|
|
|
{
|
|
|
cBarcodeObjListCount.Add(itemMax);
|
|
|
LogInfo.Info("按照次数优先,等于最大次数条码为:" + StringChange.bytesToHexStr(itemMax.EPC, itemMax.EPC.Length));
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("按照次数优先,等于最大次数条码数量为:" + cBarcodeObjListCount.Count.ToString());
|
|
|
}
|
|
|
#endregion
|
|
|
#region 求出最优条码
|
|
|
|
|
|
if (cBarcodeObjListCount.Count == 1) //如果只有一条
|
|
|
{
|
|
|
|
|
|
foreach (TagInfo itemCount in cBarcodeObjListCount)
|
|
|
{
|
|
|
if (itemCount.Count == iOrderMaxCount)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("---- 取出的最优条码是: " + StringChange.bytesToHexStr(itemCount.EPC, itemCount.EPC.Length));
|
|
|
}
|
|
|
tempBarcode = new byte[itemCount.EPC.Length];
|
|
|
Array.Copy(itemCount.EPC, 0, tempBarcode, 0, itemCount.EPC.Length);
|
|
|
}
|
|
|
}
|
|
|
//Add By baogq 2019年5月24日 15:29:20
|
|
|
//tempBarcode = new byte[cBarcodeObjListCount[0].EPC.Length];
|
|
|
//tempBarcode = cBarcodeObjListCount[0].EPC;
|
|
|
//Array.Copy(cBarcodeObjListCount[0].EPC, 0, tempBarcode, 0, cBarcodeObjListCount[0].EPC.Length);
|
|
|
cBarcodeObjListCount.Clear();
|
|
|
return tempBarcode;
|
|
|
}
|
|
|
else //如果有多条
|
|
|
{
|
|
|
#region 求出最大次数相同下条码的强度最强的条码
|
|
|
#region 求出最大次数相同的条码中,强度的最大值
|
|
|
float iOrderAvgMaxPower = cBarcodeObjListCount[0].RSSI;
|
|
|
for (int i = 0; i < cBarcodeObjListCount.Count; i++)
|
|
|
{
|
|
|
if (cBarcodeObjListCount[i].RSSI > iOrderAvgMaxPower)
|
|
|
{
|
|
|
iOrderAvgMaxPower = cBarcodeObjListCount[i].RSSI;
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("按照次数优先,等于最大次数条码中平均功率最大值为:" + iOrderAvgMaxPower.ToString());
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
foreach (TagInfo itemAvg in cBarcodeObjListCount)
|
|
|
{
|
|
|
if (itemAvg.RSSI == iOrderAvgMaxPower)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("---- 取出的最优条码是: " + StringChange.bytesToHexStr(itemAvg.EPC, itemAvg.EPC.Length));
|
|
|
}
|
|
|
|
|
|
tempBarcode = new byte[itemAvg.EPC.Length];
|
|
|
Array.Copy(itemAvg.EPC, 0, tempBarcode, 0, itemAvg.EPC.Length);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
#endregion
|
|
|
#endregion
|
|
|
return tempBarcode;
|
|
|
}
|
|
|
else if (iFlag == 2)//按照功率最大获取
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("----调用通用函数:CommandAnalysisBarcode Flag=2 按照最大平均功率取出条码,如果最大平均功率相同,则按照次数最大取值最优条码:");
|
|
|
}
|
|
|
#region 按照最大平均功率取出条码,如果最大功率相同,则按照次数最大取值最优条码
|
|
|
#region 求出最大功率
|
|
|
int iMaxAvgPow = cBarcodeObjList[0].RSSI;
|
|
|
for (int i = 0; i < cBarcodeObjList.Count; i++)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
#region 打印所有条码 次数和平均功率
|
|
|
LogInfo.Info("条码:[ " + StringChange.bytesToHexStr(cBarcodeObjList[i].EPC, cBarcodeObjList[i].EPC.Length) + " ] 平均最大功率: [" + cBarcodeObjList[i].RSSI.ToString() + " ] 次数:[ " + cBarcodeObjList[i].Count.ToString() + " ] ");
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
if (cBarcodeObjList[i].RSSI > iMaxAvgPow)
|
|
|
{
|
|
|
iMaxAvgPow = cBarcodeObjList[i].RSSI;
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("按照平均功率最大,最大平均功率为:" + iMaxAvgPow.ToString());
|
|
|
}
|
|
|
#endregion
|
|
|
#region 求出等于最大功率的所有条码对象
|
|
|
List<TagInfo> cBarcodeObjListCount = new List<TagInfo>();
|
|
|
foreach (TagInfo itemMax in cBarcodeObjList)
|
|
|
{
|
|
|
if (itemMax.RSSI == iMaxAvgPow)
|
|
|
{
|
|
|
cBarcodeObjListCount.Add(itemMax);
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("按照平均功率最大,最大平均功率相同的条码数量为:" + cBarcodeObjListCount.Count.ToString());
|
|
|
}
|
|
|
#endregion
|
|
|
#region 求出最优条码
|
|
|
//如果只有一条
|
|
|
if (cBarcodeObjListCount.Count == 1)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("---- 取出的最优条码是: " + StringChange.bytesToHexStr(cBarcodeObjList[0].EPC, cBarcodeObjList[0].EPC.Length));
|
|
|
}
|
|
|
|
|
|
tempBarcode = new byte[cBarcodeObjListCount[0].EPC.Length];
|
|
|
Array.Copy(cBarcodeObjListCount[0].EPC, 0, tempBarcode, 0, cBarcodeObjListCount[0].EPC.Length);
|
|
|
}
|
|
|
else //如果有多条
|
|
|
{
|
|
|
#region 求出平均功率最大相同时,条码读到次数最多的一个条码
|
|
|
#region 求出平均功率最大相同条码中,最大的次数
|
|
|
int iReadMaxCount = cBarcodeObjListCount[0].Count;
|
|
|
for (int i = 0; i < cBarcodeObjListCount.Count; i++)
|
|
|
{
|
|
|
if (cBarcodeObjListCount[i].Count > iReadMaxCount)
|
|
|
{
|
|
|
iReadMaxCount = cBarcodeObjListCount[i].Count;
|
|
|
}
|
|
|
}
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("在最大平均功率相同的条码中,读取次数最多为:" + iReadMaxCount.ToString());
|
|
|
}
|
|
|
#endregion
|
|
|
foreach (TagInfo itemReadCount in cBarcodeObjListCount)
|
|
|
{
|
|
|
if (itemReadCount.Count == iReadMaxCount)
|
|
|
{
|
|
|
if (iPrintLogFlag == 1)
|
|
|
{
|
|
|
LogInfo.Info("---- 取出的最优条码是: " + StringChange.bytesToHexStr(itemReadCount.EPC, itemReadCount.EPC.Length));
|
|
|
}
|
|
|
|
|
|
tempBarcode = new byte[itemReadCount.EPC.Length];
|
|
|
Array.Copy(itemReadCount.EPC, 0, tempBarcode, 0, itemReadCount.EPC.Length);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
#endregion
|
|
|
#endregion
|
|
|
return tempBarcode;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return tempBarcode;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#region 处理自动上传的函数
|
|
|
private Mutex mutauto = new Mutex();
|
|
|
private List<TagInfo> GetTagInfos(byte[] AutoDealReportData)
|
|
|
{
|
|
|
List<TagInfo> tagInfoList = new List<TagInfo>();
|
|
|
try
|
|
|
{
|
|
|
//mutauto.WaitOne();
|
|
|
int iFirstCountPos = 6; //第一次读取标签次数位置
|
|
|
int iFirstRSSIPos = 7; //第一次读取标签强度位置
|
|
|
int iFirstAnt = 8;
|
|
|
int iFirstPC = 9; //第一次读取标签天线位置
|
|
|
int iFirstLeftBarcketPos = 11;//EPC数据起始位置
|
|
|
UInt16 tempDataCount = 0;
|
|
|
int tempDataRSSI = 0;
|
|
|
UInt16 tempDataANT = 0;
|
|
|
int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString()); //标签组数
|
|
|
int iBarcodeLength = 16; //标签长度
|
|
|
int iCommonSecondFlag = 0;
|
|
|
int dataLength = Convert.ToInt32(AutoDealReportData[2].ToString());
|
|
|
for (int j = 0; j < iBarcodeGroupCount; j++)
|
|
|
{
|
|
|
//int EPCLength = dataLength - (6 * iBarcodeGroupCount);
|
|
|
|
|
|
TagInfo tag = new TagInfo();
|
|
|
byte[] tempPCByte = new byte[2]; //取出PC
|
|
|
Array.Clear(tempPCByte, 0, 2);
|
|
|
Array.Copy(AutoDealReportData, iFirstPC, tempPCByte, 0, 2);
|
|
|
|
|
|
//PC转二进制取前五位转十进制
|
|
|
int epcLength = Convert.ToInt32(Convert.ToString(Convert.ToInt64(tempPCByte[0].ToString("X"), 16), 2).PadLeft(8, '0').Substring(0, 5), 2) * 2;
|
|
|
|
|
|
//int pc = Convert.ToInt32(tempPCByte[0].ToString());
|
|
|
//int epcLength = EPCLengthByPC(pc);
|
|
|
iBarcodeLength = epcLength;
|
|
|
|
|
|
byte[] tempDataByte = new byte[epcLength];
|
|
|
Array.Clear(tempDataByte, 0, iBarcodeLength);
|
|
|
Array.Copy(AutoDealReportData, iFirstLeftBarcketPos, tempDataByte, 0, iBarcodeLength);
|
|
|
|
|
|
byte[] tempCountByte = new byte[1]; //取出标签次数
|
|
|
Array.Clear(tempCountByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstCountPos, tempCountByte, 0, 1);
|
|
|
tempDataCount = tempCountByte[0];
|
|
|
|
|
|
byte[] tempRSSIByte = new byte[1]; //取出标签强度
|
|
|
Array.Clear(tempRSSIByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstRSSIPos, tempRSSIByte, 0, 1);
|
|
|
|
|
|
tempDataRSSI = StringChange.HexStringToNegative(StringChange.bytesToHexStr(tempRSSIByte, 1));
|
|
|
|
|
|
#region add by wenjy 20220829 取出天线号
|
|
|
byte[] tempAntByte = new byte[1]; //取出天线号
|
|
|
Array.Clear(tempAntByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstAnt, tempAntByte, 0, 1);
|
|
|
tempDataANT = tempAntByte[0];
|
|
|
#endregion
|
|
|
|
|
|
tag.Count = tempDataCount;
|
|
|
tag.RSSI = tempDataRSSI;
|
|
|
tag.EPC = tempDataByte;
|
|
|
|
|
|
//if (pc == 24)
|
|
|
//{
|
|
|
// tag.EPCstring = StringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0, 7);
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// tag.EPCstring = System.Text.Encoding.ASCII.GetString(tempDataByte);
|
|
|
//}
|
|
|
tag.EPCstring = StringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0, 8);
|
|
|
|
|
|
tag.PC = tempPCByte;
|
|
|
tag.Antana = tempDataANT;
|
|
|
tagInfoList.Add(tag);
|
|
|
int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据
|
|
|
|
|
|
iFirstCountPos = iFirstCountPos + iBarcodeLength + 5; //次数
|
|
|
iFirstRSSIPos = iFirstCountPos + 1; //强度
|
|
|
iFirstAnt = iFirstRSSIPos + 1; //天线
|
|
|
iFirstPC = iFirstAnt + 1;
|
|
|
iFirstLeftBarcketPos = iFirstLeftBarcketPos + iBarcodeLength + 5;
|
|
|
|
|
|
LogInfo.Info("----函数调用:Device_AutoDealContent 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + StringChange.bytesToHexStr(tempDataByte, tempDataByte.Length) + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
|
|
|
iCommonSecondFlag++;
|
|
|
if (iCommonSecondFlag == iBarcodeGroupCount)
|
|
|
{
|
|
|
//mutauto.ReleaseMutex();
|
|
|
return tagInfoList;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("----函数调用:Device_AutoDealContent 自动处理函数异常:" + ex.ToString());
|
|
|
//mutauto.ReleaseMutex();
|
|
|
}
|
|
|
return tagInfoList;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public byte[] Device_AutoDealContent(byte[] AutoDealReportData)
|
|
|
{
|
|
|
List<TagInfo> tagInfoList = new List<TagInfo>();
|
|
|
|
|
|
byte[] bResultEPC_Data = new byte[12];
|
|
|
m_AutoReadEPC = null;
|
|
|
m_readEPCDataLen = 0;
|
|
|
// LogInfo.Info("----函数调用:Device_AutoDealContent 开始!");
|
|
|
try
|
|
|
{
|
|
|
mutauto.WaitOne();
|
|
|
int iFirstCountPos = 6; //第一次读取标签次数位置
|
|
|
int iFirstRSSIPos = 7; //第一次读取标签强度位置
|
|
|
int iFirstAnt = 8; //第一次读取标签天线位置
|
|
|
int iFirstLeftBarcketPos = 11;//EPC数据起始位置
|
|
|
UInt16 tempDataCount = 0;
|
|
|
UInt16 tempDataRSSI = 0;
|
|
|
UInt16 tempDataANT = 0;
|
|
|
int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString("X2")); //标签组数
|
|
|
int iBarcodeLength = 12; //标签长度
|
|
|
int iCommonSecondFlag = 0;
|
|
|
for (int j = 0; j < iBarcodeGroupCount; j++)
|
|
|
{
|
|
|
TagInfo tag = new TagInfo();
|
|
|
|
|
|
byte[] tempDataByte = new byte[iBarcodeLength];
|
|
|
Array.Clear(tempDataByte, 0, iBarcodeLength);
|
|
|
Array.Copy(AutoDealReportData, iFirstLeftBarcketPos, tempDataByte, 0, iBarcodeLength);
|
|
|
|
|
|
byte[] tempCountByte = new byte[1]; //取出标签次数
|
|
|
Array.Clear(tempCountByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstCountPos, tempCountByte, 0, 1);
|
|
|
tempDataCount = tempCountByte[0];
|
|
|
|
|
|
byte[] tempRSSIByte = new byte[1]; //取出标签强度
|
|
|
Array.Clear(tempRSSIByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstRSSIPos, tempRSSIByte, 0, 1);
|
|
|
tempDataRSSI = tempRSSIByte[0];
|
|
|
|
|
|
byte[] tempAntByte = new byte[1]; //取出天线号
|
|
|
Array.Clear(tempAntByte, 0, 1);
|
|
|
Array.Copy(AutoDealReportData, iFirstAnt, tempAntByte, 0, 1);
|
|
|
tempDataANT = tempAntByte[0];
|
|
|
|
|
|
tag.Count = tempDataCount;
|
|
|
tag.RSSI = tempDataRSSI;
|
|
|
tag.EPC = tempDataByte;
|
|
|
tag.EPCstring = StringChange.bytesToHexStr(tempDataByte, tempDataByte.Length);
|
|
|
tag.Antana = tempDataANT;
|
|
|
tagInfoList.Add(tag);
|
|
|
int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据
|
|
|
|
|
|
iFirstCountPos = iFirstCountPos + 17;
|
|
|
iFirstRSSIPos = iFirstCountPos + 1;
|
|
|
iFirstAnt = iFirstRSSIPos + 1;
|
|
|
iFirstLeftBarcketPos = iFirstLeftBarcketPos + 17;
|
|
|
|
|
|
LogInfo.Info("----函数调用:Device_AutoDealContent 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + StringChange.bytesToHexStr(tempDataByte, tempDataByte.Length) + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
|
|
|
iCommonSecondFlag++;
|
|
|
if (iCommonSecondFlag == iBarcodeGroupCount)
|
|
|
{
|
|
|
byte[] bResult = new byte[12];
|
|
|
bResult = CommandAnalysisBarcode(tagInfoList, 1, 1);
|
|
|
m_readEPCDataLen = tempDataByte.Length;
|
|
|
m_AutoReadEPC = new byte[m_readEPCDataLen];
|
|
|
Array.Copy(bResult, 0, m_AutoReadEPC, 0, m_readEPCDataLen);
|
|
|
LogInfo.Info("----函数调用:Device_GetOneIdentifyData_Finish for End!");
|
|
|
LogInfo.Info("------------------------------------------------------------------------------------------------------");
|
|
|
LogInfo.Info("\r\n");
|
|
|
mutauto.ReleaseMutex();
|
|
|
return m_AutoReadEPC;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("----函数调用:Device_AutoDealContent 自动处理函数异常:" + ex.ToString());
|
|
|
mutauto.ReleaseMutex();
|
|
|
}
|
|
|
return m_AutoReadEPC;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 该函数不实现了
|
|
|
public int Device_GetRf(byte Antenna, WriteOrRead RorW)
|
|
|
{
|
|
|
int bResult = 0;
|
|
|
try
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte[] bCRC = new byte[2];
|
|
|
//获取功率AA 55 00 72 72 0D
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
if (RorW == WriteOrRead.Read)
|
|
|
{
|
|
|
pMessagePack.m_pData = new byte[6];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x00;
|
|
|
pMessagePack.m_pData[3] = 0x72;
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 2);
|
|
|
pMessagePack.m_pData[4] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[5] = 0x0D;
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",发送原始报文:" + bytesToHexStr(pMessagePack.m_pData, pMessagePack.m_pData.Length));
|
|
|
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
|
|
|
{
|
|
|
FilterFunc = response =>
|
|
|
{
|
|
|
// 检查响应数据是否符合预期
|
|
|
if (response.ByteBlock != null && response.ByteBlock.Length > 0)
|
|
|
{
|
|
|
// 可以根据实际情况添加更多的检查逻辑
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(response.ByteBlock.ToArray(0, response.ByteBlock.Length), response.ByteBlock.Length));
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
});
|
|
|
byte[] reciveBuffer = waitClient.SendThenReturn(pMessagePack.m_pData, 1000 * 2);//设置10秒超时
|
|
|
//byte[] message = PareReceiveData(reciveBuffer, reciveBuffer.Length);
|
|
|
if (reciveBuffer != null)
|
|
|
{
|
|
|
byte[] bDB = new byte[2];
|
|
|
bDB[0] = reciveBuffer[6];
|
|
|
bDB[1] = reciveBuffer[7];
|
|
|
int iDB = Convert.ToInt32(StringChange.bytesToHexStr(bDB, 2), 16)/100;
|
|
|
return iDB;
|
|
|
}
|
|
|
}
|
|
|
return bResult;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return bResult;
|
|
|
}
|
|
|
}
|
|
|
public bool Device_SetRf(int iDbi, byte Antenna, WriteOrRead RorW)
|
|
|
{
|
|
|
bool bResult = false;
|
|
|
try
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte[] bCRC = new byte[22];
|
|
|
//获取功率AA 55 00 72 72 0D
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
if (RorW == WriteOrRead.Write)
|
|
|
{
|
|
|
pMessagePack.m_pData = new byte[28];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x14;
|
|
|
pMessagePack.m_pData[3] = 0x42;
|
|
|
pMessagePack.m_pData[4] = 0x01;
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 5, 2);
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 7, 2);
|
|
|
|
|
|
pMessagePack.m_pData[9] = 0x02;
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 10, 2);
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 12, 2);
|
|
|
pMessagePack.m_pData[14] = 0x03;
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 15, 2);
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 17, 2);
|
|
|
pMessagePack.m_pData[19] = 0x04;
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 20, 2);
|
|
|
u16byte = BitConverter.GetBytes(iDbi); //功率
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 22, 2);
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 22);
|
|
|
pMessagePack.m_pData[24] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[25] = 0x0D;
|
|
|
|
|
|
}
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",发送原始报文:" + bytesToHexStr(pMessagePack.m_pData, pMessagePack.m_pData.Length));
|
|
|
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
|
|
|
{
|
|
|
FilterFunc = response =>
|
|
|
{
|
|
|
// 检查响应数据是否符合预期
|
|
|
if (response.ByteBlock != null && response.ByteBlock.Length > 0)
|
|
|
{
|
|
|
// 可以根据实际情况添加更多的检查逻辑
|
|
|
LogInfo.Warn("》》》RFly-I160设备:" + m_iDeviceId + ",IP:" + m_strIp + ",接收原始报文:" + bytesToHexStr(response.ByteBlock.ToArray(0, response.ByteBlock.Length), response.ByteBlock.Length));
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
});
|
|
|
byte[] reciveBuffer = waitClient.SendThenReturn(pMessagePack.m_pData, 1000 * 2);//设置10秒超时
|
|
|
//Console.WriteLine($"收到回应消息:{bytesToHexStr(reciveBuffer, reciveBuffer.Length)}");
|
|
|
|
|
|
//byte[] message = PareReceiveData(reciveBuffer, reciveBuffer.Length);
|
|
|
|
|
|
if (RorW == WriteOrRead.Write)
|
|
|
{
|
|
|
if (reciveBuffer[3] == 0x42 && reciveBuffer[4] == 0x00)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//bool Set_OK;
|
|
|
//if (RorW == WriteOrRead.Read)
|
|
|
//{
|
|
|
// Set_OK = MyReader.SetPower(iDbi, Convert.ToSingle(m_WriteDbm));
|
|
|
// if (Set_OK) //设置功率工程
|
|
|
// {
|
|
|
// LogInfo.Info("设置天线读功率成功!");
|
|
|
// bResult = true;
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// LogInfo.Info("设置天线读功率失败;");
|
|
|
// bResult = false;
|
|
|
// }
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// Set_OK = MyReader.SetPower(Convert.ToSingle(m_ReadDbm), iDbi);
|
|
|
// if (Set_OK) //设置功率工程
|
|
|
// {
|
|
|
// LogInfo.Info("设置天线写功率成功!");
|
|
|
// bResult = true;
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// LogInfo.Info("设置天线写功率失败;");
|
|
|
// bResult = false;
|
|
|
// }
|
|
|
//}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_SetRf异常:" + ex.Message);
|
|
|
bResult = false;
|
|
|
}
|
|
|
return bResult;
|
|
|
}
|
|
|
|
|
|
public string Device_GetOneIdentifyData(Byte Antenna, UInt16 Timedout)
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
byte[] bCRC = new byte[4];
|
|
|
string strResult = "";
|
|
|
try
|
|
|
{
|
|
|
m_GlobalSem.WaitOne(-1, false);
|
|
|
LogInfo.Info("函数调用:Device_GetOneIdentifyData");
|
|
|
if (Antenna == 0) //此版本1为主机
|
|
|
{
|
|
|
Antenna = (byte)(Antenna + 1);
|
|
|
}
|
|
|
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
pMessagePack.m_pData = new byte[8];
|
|
|
pMessagePack.m_pData[0] = 0xAA;
|
|
|
pMessagePack.m_pData[1] = 0x55;
|
|
|
pMessagePack.m_pData[2] = 0x02;
|
|
|
pMessagePack.m_pData[3] = 0x02;
|
|
|
//pMessagePack.m_pData[4] = 0x03;
|
|
|
//pMessagePack.m_pData[5] = 0xE8;
|
|
|
u16byte = BitConverter.GetBytes(Timedout); //超时时间
|
|
|
u16byte = StringChange.Swap16Bytes(u16byte); //协议里为大端在前
|
|
|
LogInfo.Info("u16byte:" + u16byte);
|
|
|
Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2);
|
|
|
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4);
|
|
|
pMessagePack.m_pData[6] = StringChange.CalculateVerify(bCRC, bCRC.Length);
|
|
|
pMessagePack.m_pData[7] = 0x0D;
|
|
|
|
|
|
//m_OneEpcSem.Release(1);
|
|
|
m_OneEpcSem.WaitOne(1, false);
|
|
|
m_OneEpcDataLen = 0;
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
if (m_OneEpcSem.WaitOne(Timedout + 500, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
if ((m_OneEpcDataLen >= 1 && m_OneEpcAntenna == Antenna) || Antenna == 255) //有数据,正常
|
|
|
{
|
|
|
strResult = StringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen);
|
|
|
//pReadData = new byte[m_OneEpcDataLen];
|
|
|
//Array.Copy(m_OneEpcData, 0, pReadData, 0, m_OneEpcDataLen);
|
|
|
LogInfo.Info("Device_GetOneIdentifyData:" + StringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen));
|
|
|
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
strResult = StringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen);
|
|
|
LogInfo.Info("Device_GetOneIdentifyData:" + StringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen));
|
|
|
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
strResult = "";
|
|
|
}
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
LogInfo.Info("Device_GetOneIdentifyData超时未返回");
|
|
|
strResult = "";
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_OneEpcDataLen = 0;
|
|
|
m_OneEpcAntenna = 254;
|
|
|
LogInfo.Info("Device_GetOneIdentifyData发送识别单条EPC命令超时");
|
|
|
strResult = "";
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("Device_GetOneIdentifyData识别单条EPC数据异常:" + ex.Message);
|
|
|
strResult = "";
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
m_GlobalSem.Release();
|
|
|
}
|
|
|
return strResult;
|
|
|
}
|
|
|
|
|
|
public string Device_GetOneIdentifyData_Finish(byte Antenna, ushort Timedout)
|
|
|
{
|
|
|
return "";
|
|
|
}
|
|
|
public Byte Device_GetOneIdentifyData_Finish(ref byte[] pReadData, byte Antenna, ushort Timedout)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
public bool Device_BeginIdentify()
|
|
|
{
|
|
|
byte[] u16byte = new byte[2];
|
|
|
bool bResult = false;
|
|
|
try
|
|
|
{
|
|
|
LogInfo.Info("函数调用:Device_BeginIdentify");
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
|
|
|
pMessagePack.m_pData = new byte[1];
|
|
|
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
if (BeginEvent.WaitOne(200, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
bResult = true;
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
bResult = false;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
LogInfo.Info("发送开始连续识别命令失败:");
|
|
|
bResult = false;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("发送开始连续识别命令异常:" + ex.Message);
|
|
|
bResult = false;
|
|
|
}
|
|
|
return bResult;
|
|
|
}
|
|
|
|
|
|
public bool Device_StopIdentify()
|
|
|
{
|
|
|
bool bResult = false;
|
|
|
try
|
|
|
{
|
|
|
LogInfo.Info("函数调用:Device_StopIdentify");
|
|
|
MessagePack pMessagePack = new MessagePack();
|
|
|
|
|
|
pMessagePack.m_pData = new byte[1];
|
|
|
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
|
|
|
{
|
|
|
if (m_StopSem.WaitOne(200, false)) //等待结果,并取结果返回。
|
|
|
{
|
|
|
bResult = true;
|
|
|
}
|
|
|
else //超时
|
|
|
{
|
|
|
bResult = false;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
LogInfo.Info("发送停止连续识别命令失败:");
|
|
|
bResult = false;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Info("发送停止连续识别命令异常:" + ex.Message);
|
|
|
bResult = false;
|
|
|
}
|
|
|
return bResult;
|
|
|
}
|
|
|
|
|
|
public ushort Device_GetIdentifyData(ref byte[] pReadData, byte Antenna)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
public bool Device_BeginIdentify(byte Antenna, int timeout, bool AutoRead, int num)
|
|
|
{
|
|
|
throw new NotImplementedException();
|
|
|
}
|
|
|
|
|
|
public bool Device_StopIdentify(byte Antenna)
|
|
|
{
|
|
|
throw new NotImplementedException();
|
|
|
}
|
|
|
private string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01"
|
|
|
{
|
|
|
string returnStr = "";
|
|
|
if (bytes != null)
|
|
|
{
|
|
|
for (int i = 0; i < iLen; i++)
|
|
|
{
|
|
|
returnStr += bytes[i].ToString("X2");
|
|
|
}
|
|
|
}
|
|
|
return returnStr;
|
|
|
}
|
|
|
public byte[] PareReceiveData(byte[] buffer, int iLen)
|
|
|
{
|
|
|
RecvState enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
byte[] m_szFullMessage = new byte[buffer.Length]; //此数组用于状态机
|
|
|
int m_iPosition = 0;
|
|
|
byte m_iVerify = 0;
|
|
|
int iBarcodeLength = 0;//条码长度
|
|
|
ArrayList m_FrecvData = new ArrayList();
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160进入状态机:");
|
|
|
try
|
|
|
{
|
|
|
for (int i = 0; i < iLen; i++)
|
|
|
{
|
|
|
switch (enumRecvState)
|
|
|
{
|
|
|
case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160等待接收帧同步字符WaitingBeginChar1_State:0XBB");
|
|
|
Array.Clear(m_szFullMessage, 0, buffer.Length);//清空为0
|
|
|
if (buffer[i] == 0xBB)
|
|
|
{
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("Buffer数据为: " + StringChange.bytesToHexStr(buffer, buffer.Length));
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingBeginChar2_State;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_iPosition = 0;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
}
|
|
|
break;
|
|
|
case RecvState.WaitingBeginChar2_State: //开始接受数据帧1 0xDD
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160等待接收帧同步字符WaitingBeginChar2_State:0XDD");
|
|
|
if (buffer[i] == 0xDD)
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForBarcodeLength_State;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_iPosition = 0;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
}
|
|
|
break;
|
|
|
case RecvState.WaitingForBarcodeLength_State: //开始接受数据长度(TagCount - EPC)
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
iBarcodeLength = buffer[i]; //单组标签:18;两组标签:35
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForCode_State;
|
|
|
break;
|
|
|
|
|
|
case RecvState.WaitingForCode_State: //开始接受指令编号
|
|
|
if (buffer[i] == 0x02)
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForStus_State;
|
|
|
}
|
|
|
else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D
|
|
|
{
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160等待接受WaitingForEndChar_State:温度");
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForEndChar_State;
|
|
|
}
|
|
|
else if (buffer[i] == 0xBF) // 如果是心跳BB DD 04 BF 00 00 00 F9 0B 49 0D
|
|
|
{
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160等待接受WaitingForEndChar_State:心跳");
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForEndChar_State;
|
|
|
}
|
|
|
else if (buffer[i] == 0x51)
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForStus_State;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_iPosition = 0;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
}
|
|
|
break;
|
|
|
case RecvState.WaitingForStus_State: //开始接受状态码
|
|
|
if (buffer[i] == 0x00)
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForTagCount_State;
|
|
|
}
|
|
|
else if (buffer[i] == 0x40)
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFU620等待接受WaitingForEndChar_State:Noread");
|
|
|
lock (m_FrecvData)
|
|
|
{
|
|
|
m_FrecvData.Add(m_szFullMessage);
|
|
|
}
|
|
|
|
|
|
m_iPosition = 0;
|
|
|
i = iLen;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160状态机结束。");
|
|
|
}
|
|
|
break;
|
|
|
case RecvState.WaitingForTagCount_State: //开始接受标签组数
|
|
|
Array.Copy(buffer, i, m_szFullMessage, m_iPosition, iBarcodeLength);//m_iPosition = 5
|
|
|
byte[] tempData = new byte[iBarcodeLength];
|
|
|
Array.Clear(tempData, 0, iBarcodeLength);
|
|
|
Array.Copy(buffer, i, tempData, 0, iBarcodeLength);
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("解析的数据为: " + StringChange.bytesToHexStr(tempData, iBarcodeLength));
|
|
|
|
|
|
//m_szFullMessage[m_iPosition] = buffer[i]; //单组标签:01;两组标签:02
|
|
|
m_iPosition = m_iPosition + iBarcodeLength; //m_iPosition = 39
|
|
|
i = i + iBarcodeLength - 1; //i = 39
|
|
|
enumRecvState = RecvState.WaitingForXor_State;
|
|
|
break;
|
|
|
case RecvState.WaitingForXor_State: //开始比对校验位 Rfly160
|
|
|
byte[] m_CRCVerify = new byte[1024]; //此数组用于校验位计算
|
|
|
Array.Clear(m_CRCVerify, 0, m_CRCVerify.Length);
|
|
|
Array.Copy(m_szFullMessage, 2, m_CRCVerify, 0, iBarcodeLength + 3); //校验位计算是从Length - EPC 结束
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iVerify = m_szFullMessage[m_iPosition];
|
|
|
if (m_iVerify == CalculateVerify(m_CRCVerify, m_CRCVerify.Length))
|
|
|
{
|
|
|
m_iPosition++;
|
|
|
enumRecvState = RecvState.WaitingForEndChar_State;
|
|
|
}
|
|
|
else //如果校验不成功
|
|
|
{
|
|
|
m_iPosition = 0;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
}
|
|
|
break;
|
|
|
case RecvState.WaitingForEndChar_State:
|
|
|
if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x00) //此处为Noread数据显示
|
|
|
{
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160等待接受WaitingForEndChar_State:Noread");
|
|
|
m_szFullMessage[0] = 0xBB;
|
|
|
m_szFullMessage[1] = 0xDD;
|
|
|
m_szFullMessage[2] = 0x00;
|
|
|
lock (m_FrecvData)
|
|
|
{
|
|
|
m_FrecvData.Add(m_szFullMessage);
|
|
|
}
|
|
|
|
|
|
m_iPosition = 0;
|
|
|
i = iLen;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
}
|
|
|
else if (buffer[i] == 0x00) //获取温度
|
|
|
{
|
|
|
m_szFullMessage[3] = 0x00;
|
|
|
m_iPosition++;
|
|
|
lock (m_FrecvData)
|
|
|
{
|
|
|
m_FrecvData.Add(m_szFullMessage);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF)
|
|
|
{
|
|
|
m_szFullMessage[3] = 0xBF;
|
|
|
m_iPosition++;
|
|
|
lock (m_FrecvData)
|
|
|
{
|
|
|
m_FrecvData.Add(m_szFullMessage);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_szFullMessage[m_iPosition] = buffer[i];
|
|
|
m_iPosition++;
|
|
|
if (buffer[i] == 0x0D)
|
|
|
{
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160准备发送");
|
|
|
lock (m_FrecvData)
|
|
|
{
|
|
|
m_FrecvData.Add(m_szFullMessage);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
m_iPosition = 0;
|
|
|
enumRecvState = RecvState.WaitingBeginChar1_State;
|
|
|
//m_RFly_I160Adapter.LogInfo.Warn("RFly-I160状态机结束。");
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return m_szFullMessage;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogInfo.Error(ex.Message);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public byte CalculateVerify(byte[] pMessage, int iLength)
|
|
|
{
|
|
|
UInt16 i;
|
|
|
byte iVerify = 0;
|
|
|
|
|
|
iVerify = pMessage[0];
|
|
|
for (i = 1; i < iLength; i++)
|
|
|
{
|
|
|
iVerify = (byte)(iVerify ^ pMessage[i]);
|
|
|
}
|
|
|
return iVerify;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|