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

739 lines
26 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections;
//using System.Threading.Tasks;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Mesnac.DeviceAdapter.Fuchs
{
public enum RecvState
{
//Pepperl_Fuchs 返回数据 00.06.0A.02.FF.49.
//00.14.0A.02.00.4A.30.00.30.05.FB.63.AC.1F.36.81.EC.88.04.68
WaitingBeginChar1_State = 1, //等待接收帧同步字符1 0x00
WaitingBeginChar2_State = 2, //等待接收帧同步字符2 0x06
WaitingBeginChar3_State = 3, //等待接收帧同步字符3 0x01
WaitingBeginChar4_State = 4, //等待接收帧同步字符4 0x02
WaitingBeginChar5_State = 5, //等待接收帧同步字符5 0xFF
WaitingBeginChar6_State = 6, //等待接收帧同步字符6 0x49
WaitingForChar7_State = 7, //等待接收帧同步字符7 0x00
};
class BgTcpClient : ICommunicateService
{
private Semaphore m_ReciveSem = new Semaphore(0, 100000);
RecvState enumRecvState = RecvState.WaitingBeginChar1_State;
int m_iPosition = 0;
byte[] m_szFullMessage = new byte[1024]; //此数组用于状态机
int iBarcodeLength = 0;//条码长度
FuchsAdapter m_FuchsAdapter = null;
private BackgroundWorker m_bgwReceive = new BackgroundWorker();
private BackgroundWorker m_bgwDeal = new BackgroundWorker();
private string m_FsIP = "";
private Int32 m_FnPort = 0;
private Socket m_ClientSock = null;
private ArrayList m_FrecvData = new ArrayList();
private Semaphore m_Fsem = new Semaphore(0, 100000);
private ManualResetEvent Exitevent = new ManualResetEvent(false);
public AntInfo[] AntList = AntListInfo.AntList;
public event RecvIdentifyData RecvIdentifyDataEvent = null;
//接收线程
private void bgwReceive_DoWork(object sender, DoWorkEventArgs e)
{
int nPackLen = 1024;
byte[] buff = new byte[nPackLen];
while (true)
{
try
{
if (m_ClientSock != null && m_ClientSock.Connected)
{
int nCount = m_ClientSock.Receive(buff, nPackLen, 0);
if (nCount > 0)
{
//if(buff[0] != 0X00 && buff[1] != 0X06 && buff[2] != 0X00)
//{
//LogService.Instance.Info("方法bgwReceive_DoWorkPepperl_Fuchs接收原始报文:" + bytesToHexStr(buff, nCount));
//}
if (buff[4] == 0XFF)
{
Array.Clear(buff, 0, nCount);
}
else
{
m_FuchsAdapter.LogInfo.Info("方法bgwReceive_DoWorkPepperl_Fuchs设备" + m_FsIP + ":" + m_FnPort + "接收原始报文:" + bytesToHexStr(buff, nCount));
PareReceiveData(buff, nCount); //调用状态机函数
}
//ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_ReceiveData),buff);
continue;
}
else //接收错误
{
if (m_ClientSock != null)
{
m_ClientSock.Close();
m_ClientSock = null;
}
e.Cancel = true;
m_Fsem.Release();
}
}
else
{
e.Cancel = true;
if (m_ClientSock != null)
{
m_ClientSock.Close();
m_ClientSock = null;
}
m_Fsem.Release();
return;
}
Thread.Sleep(10);
}
catch (Exception ex)
{
e.Cancel = true;
if (m_ClientSock != null)
{
m_ClientSock.Close();
m_ClientSock = null;
}
m_FuchsAdapter.LogInfo.Info("Socket接收数据线程退出" + ex.ToString());
m_Fsem.Release();
return;
}
if (this.m_bgwReceive.CancellationPending)
{
e.Cancel = true;
if (m_ClientSock != null)
{
m_ClientSock.Close();
m_ClientSock = null;
}
m_Fsem.Release();
return;
}
}
}
private void PareSend_ReceiveData(object ReceiveData)
{
byte[] buffer = (byte[])ReceiveData;
if (buffer[3] == 0X32) //高频连续识别返回自报数据接收
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.LogInfo.Info("方法PareSend_ReceiveData线程池1号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(1); //处理函数
}
}
else if (buffer[3] == 0X34)
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.LogInfo.Info("方法PareSend_ReceiveData线程池2号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(2); //处理函数
}
}
else if (buffer[3] == 0X36)
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.LogInfo.Info("方法PareSend_ReceiveData线程池3号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(3); //处理函数
}
}
else if (buffer[3] == 0X38)
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.LogInfo.Info("方法PareSend_ReceiveData线程池4号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(4); //处理函数
}
}
}
//发送线程(包括接收后的处理)
private void bgwDeal_DoWork(object sender, DoWorkEventArgs e)
{
//LogService.Instance.Info("Pepperl_Fuchs 进入 bgwDeal_DoWork 线程:");
while (true)
{
try
{
m_Fsem.WaitOne();
//m_ReciveSem.WaitOne();
lock (m_FrecvData)
{
if (m_FrecvData.Count > 0)
{
byte[] buff = (byte[])m_FrecvData[0];
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.Device_DealValidPack(buff); //处理函数
}
m_FrecvData.RemoveAt(0);
}
}
if (Exitevent.WaitOne(0, false))
{
e.Cancel = true;
m_FuchsAdapter.LogInfo.Info("Socket处理数据线程正常退出");
Exitevent.Reset();
return;
}
Thread.Sleep(10);
}
catch (Exception ex)
{
e.Cancel = true;
m_FuchsAdapter.LogInfo.Info("Socket处理数据异常 " + ex.ToString());
return;
}
if (this.m_bgwDeal.CancellationPending)
{
m_FuchsAdapter.LogInfo.Info("Socket处理数据线程异常退出");
e.Cancel = true;
return;
}
}
}
//发送函数
public bool SendMessage(MessagePack pMessagePack)
{
UInt16 iPos = 0;
byte[] u16byte = new byte[2];
try
{
byte[] SendBuffer = new byte[pMessagePack.m_pData.Length]; //起始字符1
//SendBuffer[iPos] = pMessagePack.m_BeginChar;
//iPos += 1;
//SendBuffer[iPos] = pMessagePack.m_SecondChar; //起始字符2
//iPos += 1;
//SendBuffer[iPos] = pMessagePack.m_pData[pMessagePack.m_pData.Length]; //起始字符3
//iPos += Convert.ToUInt16(pMessagePack.m_pData.Length);
//SendBuffer[iPos] = pMessagePack.m_Channel; //通道号
Array.Copy(pMessagePack.m_pData, 0, SendBuffer, iPos, pMessagePack.m_pData.Length); //数据域
//if (pMessagePack.m_pData[0] != 0X00 && pMessagePack.m_pData[1] != 0X16 && pMessagePack.m_pData[2] != 0X0A)//过滤日志中的心跳报文
//{
m_FuchsAdapter.LogInfo.Info("方法SendMessagePepperl_Fuchs设备" + m_FsIP + ":" + m_FnPort + "发送原始报文:" + bytesToHexStr(SendBuffer, pMessagePack.m_pData.Length));
//}
int nCount = m_ClientSock.Send(SendBuffer, pMessagePack.m_pData.Length, SocketFlags.None);
if (nCount > 0) //发送成功
{
//LogService.Instance.Info("m_ClientSock.Send函数发送成功");
return true;
}
else
{
m_FuchsAdapter.LogInfo.Info("方法SendMessage连接已断开数据发送失败");
return false;
}
}
catch (Exception ex)
{
m_FuchsAdapter.LogInfo.Info("方法SendMessagePepperl_Fuchs设备" + m_FsIP + ":" + m_FnPort + "发送报文失败,请检查网络连接!");
return false;
}
}
#region 初始化一套函数
public bool Connect()
{
//连接
try
{
Exitevent.Reset();
if (m_FsIP == "" || m_FnPort == 0)
{
m_FuchsAdapter.LogInfo.Info("IP和端口号不能为空连接失败");
return false;
}
if (m_ClientSock != null && GetState())
{
//LogService.Instance.Info("已经连接了");
return true;
}
m_ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(m_FsIP), m_FnPort);
m_ClientSock.Connect(iep);
if (m_ClientSock.Connected)
{
try
{
//启动接收线程
m_bgwReceive.DoWork += new DoWorkEventHandler(bgwReceive_DoWork);
m_bgwReceive.RunWorkerAsync();
//启动处理线程
m_bgwDeal.DoWork += new DoWorkEventHandler(bgwDeal_DoWork);
m_bgwDeal.RunWorkerAsync();
return true;
}
catch (Exception ex)
{
m_FuchsAdapter.LogInfo.Info("创建后台线程异常 " + ex.ToString());
return true;
}
}
else
{
return false;
}
}
catch (Exception ex)
{
m_FuchsAdapter.LogInfo.Info("IP:" + m_FsIP + ",端口号:" + m_FnPort + "Socket连接异常!");
return false;
}
}
public bool DisConnect()
{
try
{
Exitevent.Set();
m_Fsem.Release();
Thread.Sleep(100);
//if (m_bgwReceive.IsBusy)
//{
// m_bgwReceive.CancelAsync();
//}
//if (m_bgwDeal.IsBusy)
//{
// m_bgwDeal.CancelAsync();
//}
if (m_ClientSock != null)
{
m_ClientSock.Disconnect(false);
m_ClientSock.Close();
m_ClientSock = null;
}
return true;
}
catch (Exception ex)
{
m_FuchsAdapter.LogInfo.Info("Socket连接异常 " + ex.ToString());
return false;
}
}
public bool GetState()
{
bool bResult = false;
bool blockingState = false;
try
{
if (m_ClientSock != null)
{
blockingState = m_ClientSock.Blocking;
byte[] tmp = new byte[1];
m_ClientSock.Blocking = false;
m_ClientSock.Send(tmp, 0, 0);
bResult = true;
Console.WriteLine("Connected!");
}
else
{
bResult = false;
}
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
{
bResult = true;
Console.WriteLine("Still Connected, but the Send would block");
}
else
{
bResult = false;
Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
}
}
finally
{
if (m_ClientSock != null)
{
m_ClientSock.Blocking = blockingState;
}
}
return bResult;
}
public void Init(string strIp, int iPort, object objetcter)
{
Exitevent.Reset();
m_FsIP = strIp;
m_FnPort = iPort;
m_FuchsAdapter = objetcter as FuchsAdapter;
}
#endregion
//状态机函数
public void PareReceiveData(byte[] buffer, int iLen)
{
Array.Clear(m_szFullMessage, 0, 1024);
switch (buffer[2])
{
case 0X19: //高频读头开始连续识别指令
Deal_BeginIdentify(buffer, iLen);
break;
case 0X00: //心跳
Deal_HeartPack(buffer, iLen);
break;
case 0X02://高频及超高频读头停止连续识别指令
Deal_StopIdentify(buffer, iLen);
break;
case 0X71://超高频读头开始连续识别指令
Deal_UHFBeginIdentify(buffer, iLen);
break;
case 0X0A: //超高频读头单次读标签指令
Deal_UHFReadData(buffer, iLen);
break;
case 0X10: //高频读头单次读标签指令
Deal_HFReadData(buffer, iLen);
break;
case 0X05://高频读头NoData
Deal_HFNoData(buffer, iLen);
break;
case 0X04://设置读头工作模式高频or超高频
Deal_SetAntCT(buffer, iLen);
break;
case 0X0D:
Deal_UHFWriteData(buffer, iLen);
break;
case 0XBF:
Deal_UHFSetSignelModel(buffer, iLen);
break;
default:
break;
}
}
private void Deal_UHFSetSignelModel(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_UHFWriteData(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_SetAntCT(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_HFNoData(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_HFReadData(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_UHFReadData(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
public void deal_TagInfo(byte Ant)
{
AntList[Ant - 1].ReadData = null;
while (AntList[Ant - 1].IsReading)
{
if (AntList[Ant - 1].ReadData != null)
{
m_FuchsAdapter.Device_DealValidPack(AntList[Ant - 1].ReadData);
Array.Clear(AntList[Ant - 1].ReadData, 0, AntList[Ant - 1].ReadData.Length);
AntList[Ant - 1].IsReading = false;
}
}
}
public void Receive_tagInf(DateTime dt1, byte Ant, int timeout, bool TagInventory)
{
AntList[Ant - 1].ReadData = null;
while (TagInventory)
{
int dt = (int)DateTime.Now.Subtract(dt1).TotalMilliseconds;
if (AntList[Ant - 1].ReadData != null)
{
m_FuchsAdapter.Device_DealValidPack(AntList[Ant - 1].ReadData);
Array.Clear(AntList[Ant - 1].ReadData, 0, AntList[Ant - 1].ReadData.Length);
TagInventory = false;
}
if (dt > timeout)
{
//m_FuchsAdapter.DealNoData(Ant);
if (!m_FuchsAdapter.Device_StopIdentify(Ant))
{
m_FuchsAdapter.Device_StopIdentify(Ant);
}
if (AntList[Ant - 1].IsReading)
{
m_FuchsAdapter.LogInfo.Info("》》》Receive_tagInf:IsReading = true");
}
else
{
m_FuchsAdapter.LogInfo.Info("》》》Receive_tagInf:IsReading = false");
}
AntList[Ant - 1].IsReading = false;
AntList[Ant - 1].readType = 0;
TagInventory = false;
}
}
}
private void Deal_UHFBeginIdentify(byte[] buffer, int iLen)
{
if (buffer[4] == 0XFF)
{
Array.Clear(buffer, 0, iLen);
m_FuchsAdapter.LogInfo.Info("丢掉数据");
}
else
{
if (buffer[4] == 0X00)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
m_FuchsAdapter.LogInfo.Info("接收自报数据丢进线程池,发送停止指令");
ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_UHFReceiveData), buffer); //超高频读头处理数据线程池
}
else
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
}
}
private void PareSend_UHFReceiveData(object ReceiveData) //超高频接收数据后发送停止指令
{
byte[] buffer = (byte[])ReceiveData;
if (buffer[3] == 0X02) //高频连续识别返回自报数据接收
{
if (m_FuchsAdapter != null)
{
//LogService.Instance.Info("线程池5号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(5); //处理函数
}
}
else if (buffer[3] == 0X04)
{
if (m_FuchsAdapter != null)
{
//LogService.Instance.Info("线程池6号天线发送停止指令");
m_FuchsAdapter.Device_StopIdentify(6); //处理函数
}
}
else if (buffer[3] == 0X06)
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.Device_StopIdentify(7); //处理函数
}
}
else if (buffer[3] == 0X08)
{
if (m_FuchsAdapter != null)
{
m_FuchsAdapter.Device_StopIdentify(8); //处理函数
}
}
}
private void Deal_StopIdentify(byte[] buffer, int iLen)
{
if (buffer[4] == 0XFF)
{
Array.Clear(buffer, 0, iLen);
m_FuchsAdapter.LogInfo.Info("丢掉数据");
}
else
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
}
private void Deal_HeartPack(byte[] buffer, int iLen)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
private void Deal_BeginIdentify(byte[] buffer, int iLen)
{
if (buffer[4] == 0XFF)
{
Array.Clear(buffer, 0, iLen);
m_FuchsAdapter.LogInfo.Info("丢掉数据");
}
if (buffer[4] == 0X00)
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
//switch (buffer[3])
//{
// case 0X32:
// if (AntList[0].readType > 0)
// {
// AntList[0].ReadData = new byte[buffer.Length];
// Array.Copy(buffer, 0, AntList[0].ReadData, 0, buffer.Length);
// }
// break;
// case 0X34:
// if (AntList[1].readType > 0)
// {
// AntList[1].ReadData = new byte[buffer.Length];
// Array.Copy(buffer, 0, AntList[1].ReadData, 0, buffer.Length);
// }
// break;
// case 0X36:
// if (AntList[2].readType > 0)
// {
// AntList[2].ReadData = new byte[buffer.Length];
// Array.Copy(buffer, 0, AntList[2].ReadData, 0, buffer.Length);
// }
// break;
// case 0X38:
// if (AntList[3].readType > 0)
// {
// AntList[3].ReadData = new byte[buffer.Length];
// Array.Copy(buffer, 0, AntList[3].ReadData, 0, buffer.Length);
// }
// break;
//}
m_FuchsAdapter.LogInfo.Info("接收自报数据丢进线程池,发送停止指令");
ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_ReceiveData), buffer); //超高频读头处理数据线程池
}
else
{
Array.Copy(buffer, 0, m_szFullMessage, 0, iLen);
lock (m_FrecvData)
{
m_FrecvData.Add(m_szFullMessage);
}
m_Fsem.Release();
}
}
//CRC异或校验
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;
}
private byte[] Swap16Bytes(byte[] OldU16)
{
byte[] ReturnBytes = new byte[2];
ReturnBytes[1] = OldU16[0];
ReturnBytes[0] = OldU16[1];
return ReturnBytes;
}
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;
}
}
}