RFIDReader.cs 10.5 KB
using log4net;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; 

namespace Asa.RFID
{
    public class RFID
    {
        public static readonly ILog LOGGER = LogManager.GetLogger("TheRFID");

        private System.Threading.Thread tScan;
        private bool loop;
        private string IP = "";
        private byte addr;
        private int portIndex;
        private bool IsConnect = false;
        private byte[] lastData = new byte[8];
        internal byte[] _buff;   //8字节缓存
        private byte[] _uid;    //卡片ID 
        public bool IsExist = false;
        public int ErrCode = 0;

        /// <summary>
        /// 接收事件
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="buff"></param>
        public delegate void Received_Event(string ip, byte[] buff);
        /// <summary>
        /// 接收数据
        /// </summary>
        public event Received_Event Received;

        public RFID(string ip)
        {
            this.IP = ip;
        }

        public int Close()
        {
            try
            {
                loop = false; 
                IsConnect = false;
                int ErrCode = ReaderA.StaticClassReaderA.CloseNetPort(portIndex);
                LOGGER.Info("Close RFID [" + IP + "]:" + ErrCode);
                return ErrCode;
            }
            catch (Exception e)
            {
                LOGGER.Error("Close RFID[" + IP + "] has error", e);
            }
            return -1;
        }

        public int Open()
        {
            if (IsConnect)
            {
                LOGGER.Warn(" RFID [" + IP + "] is already connected, no need to start again");
                return 0;
            }
            //IP合法
            string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
            bool rtn = System.Text.RegularExpressions.Regex.IsMatch(IP, pattern);
            if (!rtn)
            {
                LOGGER.Error(IP + " is error");
                return -1;
            }

            string[] arr = IP.Split('.');
            if (arr.Length != 4)
            {
                LOGGER.Error(IP + " length is not 4");
                return -1;
            }
            addr = Convert.ToByte(arr[3]);
            int port = 6000 + Convert.ToInt32(arr[3]);
            portIndex = 0;

            int ErrCode = ReaderA.StaticClassReaderA.OpenNetPort(port, IP, ref addr, ref portIndex);
            LOGGER.Info("Connect [" + IP + "] :" + ErrCode);
            //  在 OpenNetPort 后面使用
            System.Threading.Thread.Sleep(100);
            OpenCloseRF(false);
            System.Threading.Thread.Sleep(100);
            OpenCloseRF(true);
            return ErrCode;
        }

        public void FindMode()
        {
            loop = true;
            tScan = new System.Threading.Thread(new System.Threading.ThreadStart(Scan));
            tScan.Start();
        }

        private void Scan()
        {
            while (loop)
            {
                bool rtn = FindRFID();
                if (rtn)
                {
                    ReadRFID();
                    byte[] bb = new byte[] { _buff[0], _buff[1], _buff[2] };
                    string dataStr = byteToStr(bb, bb.Length);
                    LOGGER.Info(IP + " Scan Data:" + dataStr);
                    Received?.Invoke(IP, bb);
                }
                System.Threading.Thread.Sleep(100);
            }
        }

        private void OpenCloseRF(bool rtn)
        {
            if (rtn)
                ErrCode = ReaderA.StaticClassReaderA.OpenRf(ref addr, portIndex);
            else
                ErrCode = ReaderA.StaticClassReaderA.CloseRf(ref addr, portIndex);
        }

        /// <summary>
        /// 查找电子标签,扫描模式不能使用
        /// </summary>
        /// <returns></returns>
        public bool FindRFID()
        {
            try
            {
                //0 不带AFI
                //1 带AFI
                //2 不带AFI,继续查询
                //3 带AFI,继续查询
                //6 不带AFI,新的查询
                //7 带AFI,新的查询
                byte state = 0;

                //Select模式需要AFI
                byte AFI = 0;

                //输出,1字节DSFID,8字节UID
                byte[] DSFIDAndUID = new byte[9];

                //输出,标签数量
                byte cardNumber = 0;
                if (_uid == null)
                {
                    _uid = new byte[8];
                }
                ErrCode = ReaderA.StaticClassReaderA.Inventory(ref addr, ref state, ref AFI, DSFIDAndUID, ref cardNumber, portIndex);
                if (ErrCode == 0)
                {
                    //查询时间
                    //fCmdRet = StaticClassReaderA.GetInventoryTime(ref n_time, portIndex);
                    Array.Copy(DSFIDAndUID, 1, _uid, 0, 8);
                    IsExist = true;
                    return true;
                }
                else
                {
                    for (int i = 0; i < _uid.Length; i++)
                        _uid[i] = 0;
                    IsExist = false;
                }
            }catch(Exception ex)
            {
                LOGGER.Error(IP + "FindRFID Error:" + ex.ToString());
            }
            return false;
        }

        public byte[] Read(bool isNeedFind = false)
        {
            if (isNeedFind)
            {
                FindRFID();
            }
            if (IsExist)
            {
                ReadRFID();
                return _buff;
            }
            else
            {
                LOGGER.Info(IP + " Read:    IsExist=false ");
            }
            return null;
        }
        private void ReadRFID()
        {
            try
            {
                //0 不带AFI
                //1 带AFI
                //2 不带AFI,继续查询
                //3 带AFI,继续查询
                //6 不带AFI,新的查询
                //7 带AFI,新的查询
                byte state = 0;
                //起始块号
                byte blockNum = 0;
                //块数量
                byte blockCount = 2;
                //输出,块内安全信息,长度为BlockCount个字节
                byte[] blockSecStatus = new byte[blockCount];
                //输出,块内数据信息,长度为块的大小(4或8字节)乘以BlockCount个字节
                byte[] data = new byte[4 * blockCount];

                //错误代码
                byte errorCode = 0;
                if (_buff == null)
                {
                    _buff = new byte[8];
                }
                ErrCode = ReaderA.StaticClassReaderA.ReadMultipleBlock(ref addr, ref state, _uid, blockNum, blockCount, blockSecStatus, data, ref errorCode, portIndex);
                if (ErrCode == 0)
                {
                    Array.Copy(data, 0, _buff, 0, data.Length);
                    string dataStr = byteToStr(data, data.Length);
                    LOGGER.Info(IP + " ReadMultipleBlock:    Length: " + data.Length + " Data:" + dataStr);
                }
                else
                {

                    LOGGER.Info(IP + " ReadMultipleBlock:    ErrCode: " + ErrCode);
                }
            }
            catch (Exception ex)
            {
                LOGGER.Error(IP + "ReadRFID Error:" + ex.ToString());
            }
        }

        private string byteToStr(byte[] data, int len)
        {
            string s = "";
            for (int i = 0; i < len; i++)
            {
                s += data[i].ToString("X2") + " ";
            }
            return s;
        }
    } 
    public class RFIDReader
    {
        public static readonly ILog LOGGER = LogManager.GetLogger("TheRFID");

        private static Dictionary<string, RFID> rfidMap = new Dictionary<string, RFID>();
        private static Dictionary<string, byte[]> LastRfidData = new Dictionary<string, byte[]>();
        public static void Open(params string[] ipArr)
        {
            try
            { 
                foreach (var ip in ipArr)
                {
                    if (rfidMap.ContainsKey(ip))
                    {
                        rfidMap[ip].Open();
                        rfidMap[ip].FindMode();
                    }
                    else
                    {
                        RFID rfid = new RFID(ip);
                        rfid.Received += Rfid_Received;
                        rfid.Open();
                        rfid.FindMode();
                        rfidMap.Add(ip, rfid);
                    }
                }
            }
            catch (Exception ex)
            {
                LOGGER.Error ("RFIDReader Open Error:" + ex.ToString());
            }
        }

        private static void Rfid_Received(string ip, byte[] buff)
        {
            if (buff == null)
            {
                return;
            }
            string dataStr = byteToStr(buff, buff.Length);
            LOGGER.Info(ip + " Rfid_Received 保存数据:" + dataStr);
            if (LastRfidData.ContainsKey(ip))
            {
                LastRfidData[ip] = buff;
            }
            else
            {
                LastRfidData.Add(ip, buff);
            }
        }

        //public static bool FindRFID(string ip)
        //{
        //    if (rfidMap.ContainsKey(ip))
        //    {
        //        return rfidMap[ip].FindRFID();
        //    }
        //    return false;
        //}

        public static byte[] Read(string ip, bool isClear = false)
        {
            if (rfidMap.ContainsKey(ip))
            {
                if (LastRfidData.ContainsKey(ip))
                {
                    byte[] data= LastRfidData[ip];
                    if (isClear)
                    {
                        LastRfidData.Remove(ip);
                    }
                    return data;
                }
               // return rfidMap[ip].Read(isNeedFind);
            }
            return null;
        }

        public static void CloseAll()
        {
            foreach (var rfid in rfidMap.Values)
            {
                rfid.Close();
            }
        }
        private static string byteToStr(byte[] data, int len)
        {
            string s = "";
            for (int i = 0; i < len; i++)
            {
                s += data[i].ToString("X2") + " ";
            }
            return s;
        }
    }
}