using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MF_800U
{

    #region 枚举
    /// <summary>
    /// 读写卡器波特率
    /// </summary>
    public enum Baud
    {
        baud_9600 = 9600,
        baud_14400 = 14400,
        baud_19200 = 19200,
        baud_28800 = 28800,
        baud_38400 = 38400,
        baud_57600 = 57600,
        baud_115200 = 115200,
    }


    /// <summary>
    /// 寻卡模式
    /// </summary>
    public enum RequestMode
    {
        /// <summary>
        /// 未进入休眠状态的卡
        /// </summary>
        Halt_Mode = 0x26,

        /// <summary>
        /// 所有状态的卡
        /// </summary>
        All_Mode = 0x52,
    }

    public enum RequestTagTpe
    {
        ultra_light = 0x4400,
        Mifare_One_S50 = 0x0400,
        Mifare_One_S70 = 0x0200,
        Mifare_DESFire = 0x4403,
        Mifare_Pro = 0x0800,
        Mifare_ProX = 0x0403,
        SHC1102 = 0x0033,
    }

    /// <summary>
    /// 验证模式
    /// </summary>
    public enum KeyModel
    {
        /// <summary>
        /// 验证A密钥
        /// </summary>
        Model_keyA = 0x60,

        /// <summary>
        /// 验证B密钥
        /// </summary>
        Model_keyB = 0X61,
    }

    /// <summary>
    /// 天线状态
    /// </summary>
    public enum AntennaStatus
    {
        /// <summary>
        /// 关闭状态
        /// </summary>
        disable = 0x00,

        /// <summary>
        /// 开启状态
        /// </summary>
        enable = 0x01,
    }

    /// <summary>
    /// 读写卡器工作状态
    /// </summary>
    public enum WorkType
    {
        /// <summary>
        /// 设置为TYPE_A方式
        /// </summary>
        TYPE_A = 'A',
        /// <summary>
        /// 设置为TYPE_B方式
        /// </summary>
        TYPE_B = 'B',
        /// <summary>
        /// 设置为AT88RF020卡方式
        /// </summary>
        AT88RF020 = 'r',
        /// <summary>
        /// 设置为ST卡方式
        /// </summary>
        ST = 's',
        /// <summary>
        /// 设置为ISO15693方式
        /// </summary>
        ISO15693 = '1',
    }

    /// <summary>
    /// 读写卡器指示灯颜色
    /// </summary>
    public enum LightColor
    {
        /// <summary>
        /// 熄灭
        /// </summary>
        die = 0,

        /// <summary>
        /// 红色
        /// </summary>
        red = 1,

        /// <summary>
        /// 绿色
        /// </summary>
        green = 2,

        /// <summary>
        /// 黄色
        /// </summary>
        yellow = 3,
    }
    #endregion

    /// <summary>
    /// RFID_MF - 800U 内部DLL
    /// </summary>
    public class MF_800U
    {
        #region C MasterRD.DLL 内部方法
        #region 系统函数
        /// <summary>
        /// 休眠
        /// </summary>
        /// <param name="dwMilliseconds">休眠时间(毫秒)</param>
        [DllImport("kernel32.dll")]
        static extern void Sleep(int dwMilliseconds);

        /// <summary>
        /// 获取动态库版本号 
        /// </summary>
        /// <param name="pVer">动态库版本号</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int lib_ver(ref uint pVer);

        /// <summary>
        /// 初始化Com 端口
        /// </summary>
        /// <param name="port">端口号</param>
        /// <param name="baud">为通讯波特率4800～115200</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_init_com(int port, int baud);

        /// <summary>
        /// 关闭Com 端口
        /// </summary>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_ClosePort();

        /// <summary>
        /// 读取读写卡器型号及产品批号   
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="pVersion">返回的信息</param>
        /// <param name="pLen">返回信息的长度   </param>
        /// <returns>成功返回0 </returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_get_model(short icdev, ref byte pVersion, ref byte pLen);

        /// <summary>
        /// 指定设备标识
        /// SL系列读卡器支持组网功能，读卡器只响应设备标识符与本身相符或设备标识符等于0x0000的指令。
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_init_device_number(short icdev);

        /// <summary>
        /// 读取设备标识 
        /// 如果一个串口同时联有两台以上读卡器，不可使用该命令
        /// </summary>
        /// <param name="icdev">存放返回通讯设备标识符</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_get_device_number(ref short icdev);

        /// <summary>
        /// 设置读写卡器非接触工作方式 
        /// 只支持单一协议的读卡器此函数无效
        /// type = 'A'：设置为TYPE_A方式
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="type">读写卡器工作方式</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_init_type(short icdev, byte type);

        /// <summary>
        /// 设置读写卡器天线状态
        /// 说明：model = 0：关闭天线 model = 1：开启天线 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="model">天线状态</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_antenna_sta(short icdev, byte model);

        /// <summary>
        /// 设置指示灯颜色
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="color">0＝熄灭,1＝红色,2＝绿色,3＝黄色</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_light(short icdev, byte color);

        /// <summary>
        /// 蜂鸣 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="msec">蜂鸣时限，单位是10毫秒</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_beep(short icdev, byte msec);

        /// <summary>
        /// DES算法加密函数 
        /// </summary>
        /// <param name="szOut">返回的DES加密结果，长度等于明文长度</param>
        /// <param name="szIn">明文</param>
        /// <param name="inlen">明文长度,8字节的整数倍</param>
        /// <param name="key">密钥</param>
        /// <param name="keylen">密钥长度,如果大于8字节，是3des,如果小于等于8字节单des.不足补零</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int des_encrypt(IntPtr szOut, IntPtr szIn, int inlen, IntPtr key, int keylen);


        /// <summary>
        /// DES算法解密算法函数 
        /// </summary>
        /// <param name="szOut">返回的DES解密结果，长度等于密文长度</param>
        /// <param name="szIn">密文</param>
        /// <param name="inlen">密文长度,8字节的整数倍</param>
        /// <param name="key">密钥</param>
        /// <param name="keylen">密钥长度,如果大于8字节，是3des,如果小于等于8字节单des.不足补零</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int des_decrypt(IntPtr szOut, IntPtr szIn, int inlen, IntPtr key, int keylen);
        #endregion

        #region SL200专有 系统函数
        /// <summary>
        /// 读取读写卡器内部时钟（SL200专有函数） 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="pData">年(1)+星期(1)+月(1)+日(1)+时(1)+分(1)+秒</param>
        /// <param name="pLen">返回数据的长度</param>
        /// <returns>成功返回0</returns>
        [DllImport("SL_Paper.dll")]
        static extern int ReadTime(short icdev, ref byte pData, ref byte pLen);

        /// <summary>
        /// 更新读写卡器内部时钟（SL200专有函数） 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="pData">年(1)+星期(1)+月(1)+日(1)+时(1)+分(1)+秒</param>
        /// <returns>成功返回0</returns>
        [DllImport("SL_Paper.dll")]
        static extern int WriteTime(short icdev, byte pData);

        /// <summary>
        /// 设置时钟显示格式（SL200专有函数） 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="bShowFlag">显示方式：0＝显示'年'－'月'－'日';!0＝显示'时'－'分'－'秒'</param>
        /// <returns>成功返回0</returns>
        [DllImport("SL_Paper.dll")]
        static extern int DisPlayTime(short icdev, byte bShowFlag);

        /// <summary>
        /// 设置读写卡器显示数据（SL200专有函数） 
        /// 例：  unsigned char disdata[9] = {"1234567.8"};
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="pData">显示内容，ASCII字符</param>
        /// <param name="Len">数据长度</param>
        /// <returns>成功返回0</returns>
        [DllImport("SL_Paper.dll")]
        static extern int DisPlayString(short icdev, byte pData, byte Len);
        #endregion

        #region Mifare 函数
        /// <summary>
        /// 寻TYPE_A卡 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="mode">寻卡模式</param>
        /// <param name="pTagType">返回卡类型值</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_request(short icdev, byte mode, ref ushort pTagType);

        /// <summary>
        /// TYPE_A卡防冲撞 
        /// </summary>
        /// <param name="icdev"> 通讯设备标识符</param>
        /// <param name="bcnt">取值4</param>
        /// <param name="pSnr">返回的卡序列号</param>
        /// <param name="pRLength">返回序列号的长度</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_anticoll(short icdev, byte bcnt, IntPtr pSnr, ref byte srcLen);

        /// <summary>
        /// 激活TYPE_A卡  
        /// 卡片接收到该命令后进入激活状态，在一个感应区域内的同一时刻只可有一张TYPE_A卡处于激活状态
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="pSnr">卡序列号</param>
        /// <param name="srcLen">卡序列号长度</param>
        /// <param name="Size">返回卡容量</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_select(short icdev, IntPtr pSnr, byte srcLen, ref sbyte Size);

        /// <summary>
        /// 命令已激活的TYPE_A卡进入HALT状态
        /// 卡片接收到此命令后退出激活状态
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_halt(short icdev);

        /// <summary>
        /// 验证Mifare 卡密钥 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="mode">密码验证模式</param>
        /// <param name="secnr">要验证密码的绝对快地址</param>
        /// <param name="key">密钥内容，6 字节</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_authentication2(short icdev, byte mode, byte secnr, IntPtr pKey);

        /// <summary>
        /// 将Mifare One 卡某一块初始化为钱包
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="value">初始金额，16进制，低字节在前</param>
        /// <returns>成功返回0 </returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_initval(short icdev, byte adr, Int32 value);

        /// <summary>
        /// Mifare One卡充值
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="value">要增加的值，16进制，低字节在前</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_increment(short icdev, byte adr, Int32 value);

        /// <summary>
        /// Mifare One卡扣款
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="value">要扣的值，16进制，低字节在前</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_decrement(short icdev, byte adr, Int32 value);

        /// <summary>
        /// 读取Mifare One卡钱包值
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="pValue">返回的值，16进制，低字节在前</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_readval(short icdev, byte adr, ref Int32 pValue);

        /// <summary>
        /// 读取MifareOne卡一块数据 
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="pData">返回的数据</param>
        /// <param name="pLen">返回数据的长度</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_read(short icdev, byte adr, IntPtr pData, ref byte pLen);

        /// <summary>
        /// 写入MifareOne卡一块数据
        /// </summary>
        /// <param name="icdev">通讯设备标识符</param>
        /// <param name="adr">绝对块号</param>
        /// <param name="pData">写入的数据，16 字节</param>
        /// <returns>成功返回0</returns>
        [DllImport("MasterRD.dll")]
        static extern int rf_M1_write(short icdev, byte adr, IntPtr pData);
        #endregion
        #endregion

        #region 属性
        private static short ICDEV = 0x0000;
        private static byte BCNT = 0x04;
        private int portNo;
        private Baud baud;
        private bool isOpen = false;
        /// <summary>
        /// 是否打开
        /// </summary>
        public bool IsOpen
        {
            get { return isOpen; }
            set { isOpen = value; }
        }
        /// <summary>
        /// 端口号
        /// </summary>
        public int PortNo
        {
            get { return portNo; }
            set { portNo = value; }
        }
        /// <summary>
        /// 波特率
        /// </summary>
        public Baud Baud
        {
            get { return baud; }
            set { baud = value; }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// stirng 字符串转换 byte[]数组
        /// </summary>
        /// <param name="theHex">stirng字符串</param>
        /// <returns>byte[] 数组</returns>
        public static byte[] ToDigitsBytes(string theHex)
        {
            byte[] bytes = new byte[theHex.Length / 2 + (((theHex.Length % 2) > 0) ? 1 : 0)];
            for (int i = 0; i < bytes.Length; i++)
            {
                char lowbits = theHex[i * 2];
                char highbits;

                if ((i * 2 + 1) < theHex.Length)
                    highbits = theHex[i * 2 + 1];
                else
                    highbits = '0';

                int a = (int)GetHexBitsValue((byte)lowbits);
                int b = (int)GetHexBitsValue((byte)highbits);
                bytes[i] = (byte)((a << 4) + b);
            }
            return bytes;
        }

        /// <summary>
        /// byte[] 数组转换 stirng字符串
        /// </summary>
        /// <param name="bytes">yte[] 数组</param>
        /// <returns>stirng字符串</returns>
        public static string ToHexString(byte[] bytes)
        {
            char[] chars = new char[bytes.Length * 2];

            for (int i = 0; i < bytes.Length; i++)
            {
                int b = bytes[i];
                chars[i * 2] = hexDigits[b >> 4];
                chars[i * 2 + 1] = hexDigits[b & 0xF];
            }

            return new string(chars);
        }


        /// <summary>
        /// 验证十六进制
        /// </summary>
        static char[] hexDigits = { 
            '0','1','2','3','4','5','6','7',
            '8','9','A','B','C','D','E','F'};

        /// <summary>
        /// 验证输入byte字节是否为十六进制字符
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        public static byte GetHexBitsValue(byte ch)
        {
            byte sz = 0;
            if (ch <= '9' && ch >= '0')
                sz = (byte)(ch - 0x30);
            if (ch <= 'F' && ch >= 'A')
                sz = (byte)(ch - 0x37);
            if (ch <= 'f' && ch >= 'a')
                sz = (byte)(ch - 0x57);

            return sz;
        }
        #endregion

        #region C# MF_800U 方法
        #region 系统函数
        /// <summary>
        /// 休眠
        /// </summary>
        /// <param name="dwMilliseconds">休眠时间(毫秒)</param>
        public void sleep(int dwMilliseconds)
        {
            Sleep(dwMilliseconds);
        }

        /// <summary>
        /// 获取动态库版本号 
        /// </summary>
        /// <param name="pVer">动态库版本号</param>
        /// <returns>返回版本号</returns>
        public string lib_ver()
        {
            uint version = new uint();
            if (lib_ver(ref version) == 0)
            { return version.ToString(); }
            else
            { return string.Empty; }
        }

        /// <summary>
        /// 初始化Com 端口
        /// </summary>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_init_com()
        {
            if (rf_init_com(this.PortNo, (int)this.Baud) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 关闭Com 端口
        /// </summary>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_closePort()
        {
            if (rf_ClosePort() == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 读取读写卡器型号及产品批号   
        /// </summary>
        /// <returns>返回读写卡器型号及产品批号 </returns>
        public string rf_get_model()
        {
            byte version = 0;
            byte len = 0;
            if (rf_get_model(ICDEV, ref version, ref len) == 0)
            { return version + "  Length " + len; }
            else
            { return string.Empty; }
        }

        /// <summary>
        /// 指定设备标识
        /// </summary>
        /// <param name="icdev">通讯设备标识</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_init_device_num(short icdev)
        {
            if (rf_init_device_number(icdev) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 读取设备标识 
        /// </summary>
        /// <returns>通讯设备标识</returns>
        public string rf_get_device_number()
        {
            short icdev = 0;
            if (rf_get_device_number(ref icdev) == 0)
            { return icdev.ToString(); }
            else
            { return string.Empty; }
        }

        /// <summary>
        /// 设置读写卡器非接触工作方式
        /// </summary>
        /// <param name="type">工作方式</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_init_type(WorkType type)
        {
            if (rf_init_type(ICDEV, (byte)type) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 设置读写卡器天线状态
        /// </summary>
        /// <param name="model">天线状态</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_antenna_sta(AntennaStatus model)
        {
            if (rf_antenna_sta(ICDEV, (byte)model) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 设置指示灯颜色
        /// </summary>
        /// <param name="color">颜色</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_light(LightColor color)
        {
            if (rf_light(ICDEV, (byte)color) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 蜂鸣
        /// </summary>
        /// <param name="msec">蜂鸣时限，单位是10毫秒</param>
        public void rf_beep(byte msec)
        {
            rf_beep(ICDEV, msec);
        }
        #endregion

        #region SL200专有 系统函数
        /// <summary>
        /// 读取读写卡器内部时钟（SL200专有函数） 
        /// </summary>
        /// <returns>成功返回Ture；否则返回False</returns>
        public string ReadTime()
        {
            byte pData = 0;
            byte pLen = 0;
            if (ReadTime(ICDEV, ref pData, ref pLen) == 0)
            { return pData + "  length " + pLen; }
            else
            { return string.Empty; }
        }

        /// <summary>
        /// 更新读写卡器内部时钟（SL200专有函数）
        /// </summary>
        /// <param name="pData">年(1)+星期(1)+月(1)+日(1)+时(1)+分(1)+秒</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool WriteTime(byte pData)
        {
            if (WriteTime(ICDEV, pData) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 设置时钟显示格式（SL200专有函数） 
        /// </summary>
        /// <param name="bShowFlag">显示方式：0＝显示'年'－'月'－'日';!0＝显示'时'－'分'－'秒'</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool DisplayTime(byte bShowFlag)
        {
            if (DisPlayTime(ICDEV, bShowFlag) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 设置读写卡器显示数据（SL200专有函数） 
        /// </summary>
        /// <param name="pData">显示内容，ASCII字符</param>
        /// <param name="pLen">数据长度</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool DisPlayString(byte pData, byte pLen)
        {
            if (DisPlayString(ICDEV, pData, pLen) == 0)
            { return true; }
            else
            { return false; }
        }
        #endregion

        #region Mifare 函数
        /// <summary>
        /// 寻卡
        /// </summary>
        /// <param name="mode">寻卡模式</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_request(RequestMode mode)
        {
            ushort pTagType = 0;
            if (rf_request(ICDEV, (byte)mode, ref pTagType) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 防冲撞
        /// </summary>
        /// <param name="serialId">返回卡序列号</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        unsafe public bool rf_anticoll(ref string serialId)
        {
            byte srcLen = 0;
            byte[] bSnr = new byte[4];
            fixed (byte* pSnr = bSnr)
            {
                int status = rf_anticoll(ICDEV, BCNT, (IntPtr)pSnr, ref srcLen);
                if (status == 0)
                {
                    for (int j = 0; j < srcLen; j++)
                    { bSnr[j] = Marshal.ReadByte((IntPtr)pSnr, j); }
                    serialId = ToHexString(bSnr);
                    return true;
                }
                else
                { return false; }
            }
        }

        /// <summary>
        /// 激活卡
        /// </summary>
        /// <param name="serialId">卡序列号</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        unsafe public bool rf_select(string serialId)
        {
            sbyte Size = 0;
            byte[] bSnr = ToDigitsBytes(serialId);
            fixed (byte* pSnr = bSnr)
            {
                if (rf_select(ICDEV, (IntPtr)pSnr, (byte)bSnr.Length, ref Size) == 0)
                { return true; }
                else
                { return false; }
            }
        }

        /// <summary>
        /// 命令已激活的TYPE_A卡进入HALT状态
        /// </summary>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_halt()
        {
            if (rf_halt(ICDEV) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 验证密钥
        /// </summary>
        /// <param name="mode">验证模式</param>
        /// <param name="secnr">绝对快地址</param>
        /// <param name="key">验证Key</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        unsafe public bool rf_M1_authentication2(KeyModel mode, byte secnr, string key)
        {
            byte[] bKey = ToDigitsBytes(key);//67
            fixed (byte* pKey = bKey)
            {
                if (rf_M1_authentication2(ICDEV, (byte)mode, secnr, (IntPtr)pKey) == 0)
                { return true; }
                else
                { return false; }
            }
        }

        /// <summary>
        /// 将Mifare One 卡某一块初始化为钱包
        /// </summary>
        /// <param name="adr">绝对块地址</param>
        /// <param name="value">初始化金额</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_M1_initval(byte adr, Int32 value)
        {
            if (rf_M1_initval(ICDEV, adr, value) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// Mifare One卡充值
        /// </summary>
        /// <param name="adr">绝对快地址</param>
        /// <param name="value">充值金额</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_M1_increment(byte adr, Int32 value)
        {
            if (rf_M1_increment(ICDEV, adr, value) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// Mifare One卡扣款
        /// </summary>
        /// <param name="adr">绝对快地址</param>
        /// <param name="value">扣款金额</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        public bool rf_M1_decrement(byte adr, Int32 value)
        {
            if (rf_M1_decrement(ICDEV, adr, value) == 0)
            { return true; }
            else
            { return false; }
        }

        /// <summary>
        /// 读取Mifare One卡钱包值
        /// </summary>
        /// <param name="adr">绝对快地址</param>
        /// <returns>金额</returns>
        public int rf_M1_readval(byte adr)
        {
            int pValue = 0;
            rf_M1_readval(ICDEV, adr, ref pValue);
            return pValue;
        }

        /// <summary>
        /// 读取MifareOne卡一块数据 
        /// </summary>
        /// <param name="adr">绝对快地址</param>
        /// <returns>成功返回Ture；否则返回False</returns>
        unsafe public string rf_M1_read(byte adr)
        {
            byte cLen = 0;
            byte[] bData = new byte[16];
            fixed (byte* pData = bData)
            {
                if (rf_M1_read(ICDEV, adr, (IntPtr)pData, ref cLen) == 0 && cLen == 16)
                {
                    for (int j = 0; j < cLen; j++)
                    { bData[j] = Marshal.ReadByte((IntPtr)pData, j); }
                    return ToHexString(bData);
                }
                else
                { return string.Empty; }
            }
        }

        /// <summary>
        /// 写入MifareOne卡一块数据
        /// </summary>
        /// <param name="adr"></param>
        /// <param name="Data"></param>
        /// <returns></returns>
        unsafe public bool rf_M1_write(byte adr, string Data)
        {
            byte[] bData = ToDigitsBytes(Data);
            fixed (byte* pData = bData)
            {
                if (rf_M1_write(ICDEV, adr, (IntPtr)pData) == 0)
                { return true; }
                else
                { return false; }
            }
        }
        #endregion
        #endregion
    }
}
