#ifndef GREADER_H
#define GREADER_H


#if defined DLL_EXPORT  //源文件需引用下一函数   
	#define DECLDIR //__declspec(dllexport)//就是这个 
#else   
	#define DECLDIR //__declspec(dllimport) 
#endif


#define LED_OFF    0
#define LED_RED    1
#define LED_GREEN  2


//一台机器最多可以连接10个读写器

extern "C"
{


//*****************************************************************************
//设置读写器函数
//*****************************************************************************


//连接读写器
//参数：port->串口号，例："com1"
//      addr->读卡器地址，这个数值由程序员指定，相当于给读卡器一个身份标识，范围0~9，
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回：成功true，失败返回false
DECLDIR BOOL _stdcall gConnReader(char *port, int addr=0);



//断开连接
//参数：addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gDiscReader(int addr=0);



//设置串口等待时间
//参数：time->等待时间，单位ms
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gSetTimeOut(int time, int addr=0);



//设置读写器波特率
//参数：baud->标准波特率
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gSetBaud(DWORD baud, int addr=0);



//获取读写器型号
//参数：model->返回读写器型号
//      len  ->返回型号长度
//      addr ->读卡器地址，必须与 gConnReader 函数的保持一致；
//             缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gGetModel(BYTE *model, int *len, int addr=0);



//设置蜂鸣
//参数：time->蜂鸣时间，单位5MS
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gSetBeep(BYTE time, int addr=0);



//设置LED颜色
//参数：color->0x00 = 熄灭
//             0x01 = 红色
//             0x02 = 绿色
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回true，失败返回false
DECLDIR BOOL _stdcall gSetLED(BYTE color, int addr=0);



//休眠读写器，发送任意指令均可唤醒读写器，这条指令可当做复位MCU使用
//参数：addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回ture，失败返回false
DECLDIR BOOL _stdcall gSleepReader(int addr=0);



//读FDX_A卡
//参数：ID ->返回卡号，5 BYTES
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall gReadFDXA(BYTE *ID, int addr=0);



//读FDX_B（ISO11784/85）卡
//参数：nation ->返回国内代码，5 BYTES
//      country->返回国家代码，2 BYTES
//      trailer->返回用户自定义数据 3 BYTES
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall gReadFDXB(BYTE *nation, BYTE *country, BYTE *trailer, int addr=0);



//读EM4100卡
//参数：ID ->返回卡号，5 BYTES
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall gReadEM4100(BYTE *ID, int addr=0);



//读HID卡
//参数：hid ->返回卡号，3 BYTES
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall gReadHID(BYTE *hid, int addr=0);


//读EEPROM，
//参数：eeprom_data->返回卡号，最大为64 BYTES
//      addr       ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                   缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回读取到的数据长度
DECLDIR int _stdcall gReadEeprom(BYTE *eeprom_data, int addr=0);



//写EEPROM，此操作将直接覆盖EEPROM原来的数据，无法恢复
//参数：eeprom_data->EEPROM数据
//      len        ->EEPROM数据长度，最长为64 bytes
//      addr       ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                   缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//写成功放回true，否则返回false
DECLDIR BOOL _stdcall gWriteEeprom(BYTE *eeprom_data, BYTE len, int addr=0);



//直通函数
//参数：cmd     ->数据包命令
//      para    ->数据包参数
//      para_len->数据包参数长度
//      resp    ->返回数据包数据
//      resp_len->返回数据包数据长度
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//操作成功返回1，操作失败返回2，通信失败返回3
DECLDIR int _stdcall gDirecteAccess(WORD cmd, BYTE *para, int para_len, BYTE *resp, int *resp_len, int addr=0);



//=============================================================================
//ATA5567指令
//=============================================================================


//写卡
//参数：page      ->页地址，起始页为0
//      block     ->块地址，页0的用户存储起始地址为1，block 0为卡片配置块
//      lock      ->0x00 = 不固化
//                  0x01 = 固化
//      block_data->待写入数据，4 BYTES
//      addr      ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                  缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_StandWrite(BYTE page, BYTE block, BYTE lock, BYTE *block_data, int addr=0);



//写卡（带密码）
//参数：page      ->页地址，起始页为0
//      block     ->块地址，页0的用户存储起始地址为1，block 0为卡片配置块
//      lock      ->0x00 = 不固化
//                  0x01 = 固化
//      block_data->待写入数据，4 BYTES
//      password  ->卡片密码
//      addr      ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                  缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_ProteWrite(BYTE page, BYTE block, BYTE lock, BYTE *block_data, BYTE* password, int addr=0);



//唤醒卡片
//参数：password  ->卡片密码
//      addr      ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                  缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_WakeUp(BYTE *password, int addr=0);



//设置卡片返回数据的地址
//参数：page ->页地址，起始页为0
//      block->块地址，页0的用户存储起始地址为1，block 0为卡片配置块
//      addr ->读卡器地址，必须与 gConnReader 函数的保持一致；
//             缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_Access(BYTE page, BYTE block, int addr=0);



//设置卡片返回数据的地址（带密码）
//参数：page      ->页地址，起始页为0
//      block     ->块地址，页0的用户存储起始地址为1，block 0为卡片配置块
//      password  ->卡片密码
//      addr      ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                  缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_AccessPWD(BYTE page, BYTE block, BYTE* password, int addr=0);



//选择用户存储页
//参数：page->页地址，起始页为0
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_SelectPage(BYTE page, int addr=0);



//复位卡片
//参数：addr ->读卡器地址，必须与 gConnReader 函数的保持一致；
//             缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 ATA_Read 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_Reset(int addr=0);



//读卡Manchester RF/32
//参数：data_card->返回卡片数据
//      data_len ->返回卡片数据长度
//      addr     ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                 缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall ATA_ReadCardRF32(BYTE *data_card, int *data_len, int addr=0);



//读卡Manchester RF/64
//参数：data_card->返回卡片数据
//      data_len ->返回卡片数据长度
//      addr     ->读卡器地址，必须与 gConnReader 函数的保持一致；
//                 缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//读卡成功返回1，读卡失败返回2，通信失败返回3
DECLDIR int _stdcall ATA_ReadCardRF64(BYTE *data_card, int *data_len, int addr=0);



//把 ATA5567 格式化成 FDX_A 卡
//参数：ID  ->FDX_A卡号，5 BYTES，后7位有效
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 gReadFDXA 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_WriteFDXA(BYTE *ID, int addr=0);



//把 ATA5567 格式化成 HID 卡
//参数：hid  ->HID卡号，3 BYTES
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 gReadHID 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_WriteHID(BYTE *hid, int addr=0);



//把 ATA5567 格式化成 FDX_B 卡
//参数：nation ->返回国内代码，38 bits
//      country->返回国家代码，10 bits
//      trailer->返回用户自定义数据 3 BYTES
//      lock->锁卡，0为不加密，1为加密，把卡片加密，使得他人无法修改ID卡号
//      old_pw->4 BYTES卡片原来的密码，新卡的密码是{0x00, 0x00, 0x00, 0x00}
//      new_pw->4 BYTES卡片的新密码,假如lock=0，卡片的新密码为{0,0,0,0}，否则为new_pw
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 gReadFDXB 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_WriteFDXB(BYTE *nation, BYTE *country, BYTE *trailer, BYTE lock, BYTE *old_pw, BYTE *new_pw, int addr=0);



//把 T5557 格式化成 EM4100 卡
//参数：ID  ->EM4100卡号，5 BYTES
//      lock->锁卡，0为不加密，1为加密，把卡片加密，使得他人无法修改ID卡号
//      old_pw->4 BYTES卡片原来的密码，新卡的密码是{0x00, 0x00, 0x00, 0x00}
//      new_pw->4 BYTES卡片的新密码,假如lock=0，卡片的新密码为{0,0,0,0}，否则为new_pw
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回true表示与读写器通信成功，否则返回false，
//可以调用 gReadEM4100 函数验证是否写卡成功
DECLDIR BOOL _stdcall ATA_WriteEM4100(BYTE *ID, BYTE lock, BYTE *old_pw, BYTE *new_pw, int addr=0);



//=============================================================================
//EM4305指令
//=============================================================================


//写EM4305
//参数：word_addr->指定卡片地址
//      word_data->待写入卡片数据，4 bytes
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0写卡成功，返回1写卡失败，返回2读写串口失败
DECLDIR int _stdcall EM_WriteWord(BYTE word_addr, BYTE *word_data, int addr=0);



//读EM4305
//参数：word_addr->指定卡片地址
//      word_data->返回卡片数据，4 bytes
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0读卡成功，返回1读卡失败，返回2读写串口失败
DECLDIR int _stdcall EM_ReadWord(BYTE word_addr, BYTE *word_data, int addr=0);



//验证EM4305密码
//参数：password->4 bytes卡片密码
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0密码正确，返回1密码错误，返回2读写串口失败
DECLDIR int _stdcall EM_Login(BYTE *password, int addr=0);



//锁定卡片指定数据块
//参数：array_addr->卡片地址数组，指定待锁定块的地址
//      array_size->卡片地址数组长度，指定锁定块数量
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//备注：一旦这些块锁定之后，就不能再解锁
//返回0锁卡成功，返回1锁卡失败，返回2读写串口失败，返回3表示锁定块地址错误
DECLDIR int _stdcall EM_Protect(BYTE *array_addr, int array_size, int addr=0);


//休眠卡片
//参数：addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0休眠成功，返回1休眠失败，返回2读写串口失败
DECLDIR int _stdcall EM_Disable(int addr=0);



//设置EM卡类型
//参数：mode-> 0 = Manchester RF/64
//             1 = Manchester RF/32
//             2 = Bi-phase RF/32
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//成功返回ture，失败返回false
DECLDIR BOOL _stdcall EM_SetCardMode(BYTE mode, int addr=0);



//把 EM4305 格式化成 FDX_B 卡
//参数：nation ->返回国内代码，38 bits
//      country->返回国家代码，10 bits
//      trailer->返回用户自定义数据 3 BYTES
//      lock->锁卡，0为不加密，1为加密，把卡片加密，使得他人无法修改ID卡号
//      old_pw->4 BYTES卡片原来的密码，新卡的密码是{0x00, 0x00, 0x00, 0x00}
//      new_pw->4 BYTES卡片的新密码,假如lock=0，卡片的新密码为{0,0,0,0}，否则为new_pw
//      addr   ->读卡器地址，必须与 gConnReader 函数的保持一致；
//               缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0写卡成功，返回1写卡失败，返回2读写串口失败
DECLDIR int _stdcall EM_WriteFDXB(BYTE *nation, BYTE *country, BYTE *trailer, BYTE lock, BYTE *old_pw, BYTE *new_pw, int addr=0);



//把 EM4305 格式化成 EM4100 卡
//参数：ID  ->EM4100卡号，5 BYTES
//      lock->锁卡，0为不加密，1为加密，把卡片加密，使得他人无法修改ID卡号
//      old_pw->4 BYTES卡片原来的密码，新卡的密码是{0x00, 0x00, 0x00, 0x00}
//      new_pw->4 BYTES卡片的新密码,假如lock=0，卡片的新密码为{0,0,0,0}，否则为new_pw
//      addr->读卡器地址，必须与 gConnReader 函数的保持一致；
//            缺省为0，如果你的程序只操作一个读写器，建议采用缺省值；
//返回0写卡成功，返回1写卡失败，返回2读写串口失败
DECLDIR int _stdcall EM_WriteEM4100(BYTE *ID, BYTE lock, BYTE *old_pw, BYTE *new_pw, int addr=0);


}


#endif