// *** rd0xAB.h, header for main API file, Ver. 1.7, Windows ***
#ifndef _RD0XAB_WIN_H_
#define _RD0XAB_WIN_H_

#include <windows.h>
#include <tchar.h>
#include "lu_libusb.h"

// *** define _RD0XAB_DLL_ for rd0xAB.dll use ***
// *** undefine _RD0XAB_DLL_ for normal mode, rd0xAB.cpp must be included into project ***
// #define _RD0XAB_DLL_

#ifdef _RD0XAB_DLL_
#pragma message("*** rd0xAB.h: dllimport is active ***")
#define DLL_API extern "C" __declspec(dllimport)
#else
#pragma message("*** rd0xAB.h: compiling without DLL support ***")
#define DLL_API
#endif // _RD0XAB_DLL_

#define RDRAPI_VER              TEXT("1.7L")// current API version
#define UDEV_REV                0x20        // HW min.version

#define SZ_UID                  10          // UID size for data frames
#define SZ_SCCD                 14          // card descriptor size for data frames: uidlen(1)+UID(10)+SAK(1)+ATQA(2)

#define SZ_MFBLK                16
#define SZ_MFPAGE               4

#define MFDM_BLOCK              0x00        // block access to data (16b) if b.0 = 0
#define MFDM_PAGE               0x01        // page access to data (4b) if b.0 = 1
#define MFDM_DM                 0x00        // data read mode if b.1 = 0
#define MFDM_AM                 0x02        // authorization only mode (w/out read) if b.1 = 1
#define MFDM_NMC                0x00        // normal card operation if b.7 == 0
#define MFDM_RWC                0x80        // RW card operation if b.7 == 1

#define LERR_SUCCESS            0
#define LERR_FAIL               1
#define LERR_HARDWARE           2
#define LERR_TIMEOUT_TX         3
#define LERR_TIMEOUT_RX         4
#define LERR_NOTSYNC            5
//
#define LERR_NOREADER           6
#define LERR_NOCARD             7
#define LERR_INVALIDCARD        8
#define LERR_INVALIDKEY         9
#define LERR_IOERR              10
#define LERR_DATAREAD           11
#define LERR_DATAWRITE          12
#define LERR_BUSY               13
#define LERR_USER               14

// card type
#define SCD_UNKNOWN             0
#define SCD_UL                  0x01
#define SCD_CL1K                0x02
#define SCD_CL4K                0x03
#define SCD_CL1K1               0x04
#define SCD_CL4K1               0x05
#define SCD_PL2S1               0x06
#define SCD_PL4S1               0x07
#define SCD_PL2S2               0x08
#define SCD_PL4S2               0x09
#define SCD_PL2S3               0x0A
#define SCD_PL4S3               0x0B
#define SCD_MINI                0x0C
#define SCD_DF1                 0x0D
#define SCD_DF2                 0x0E
#define SCD_SMMX                0x0F
#define SCD_SM1K                0x10
#define SCD_SM2K                0x11
#define SCD_SM4K                0x12

// mifare commands
#define PICC_REQIDL             0x26            // request idle
#define PICC_REQRW              0x40            // request RW (mifare zero)
#define PICC_REQALL             0x52            // request all

#define PICC_ANTICOLLRW         0x43            // anticollision for RW-card (mifare zero)
#define PICC_ANTICOLL1          0x93            // anticollision level 1 106 kBaud
#define PICC_ANTICOLL11         0x92            // anticollision level 1 212 kBaud
#define PICC_ANTICOLL12         0x94            // anticollision level 1 424 kBaud
#define PICC_ANTICOLL13         0x98            // anticollision level 1 848 kBaud
#define PICC_ANTICOLL2          0x95            // anticollision level 2
#define PICC_ANTICOLL3          0x97            // anticollision level 3
#define PICC_HALT               0x50            // halt
#define PICC_PWDAUTH            0x1B            // password authentication
#define PICC_GETVERSION         0x60            // information on the MIFARE family
#define PICC_AUTHENT1A          0x60            // authentication using key A
#define PICC_AUTHENT1B          0x61            // authentication using key B
#define PICC_READ16             0x30            // read 16 byte block
#define PICC_READCNT            0x39            // read out counters value
#define PICC_FASTREAD           0x3A            // fast read
#define PICC_READSIG            0x3C            // read manufacturer signature
#define PICC_CHKTEARING         0x3E            // enables the application to identify
#define PICC_VCSL               0x4B            // enable a unique identification and selection
#define PICC_WRITE16            0xA0            // write 16 byte block
#define PICC_WRITE4             0xA2            // write 4 byte block
#define PICC_INCRCNT            0xA5            // increment one-way counters
#define PICC_TRANSFER           0xB0            // transfer command code
#define PICC_DECREMENT          0xC0            // decrement value
#define PICC_INCREMENT          0xC1            // increment value
#define PICC_RESTORE            0xC2            // restore command code
#define PICC_RATS               0xE0            // command identifies the PICC type

// * reader commands *
#define CMG_VER                 0xFF            // get reader version
#define CMF_RST                 0xFE            // factory reset
#define CMG_MOD                 0xFD            // get device mode (RAM/ROM)
#define CMS_MOD                 0xFC            // set device mode (RAM/ROM)
#define CMG_UBR                 0xFB            // get UART baud rate (ROM only)
#define CMS_UBR                 0xFA            // set UART baud rate (ROM only)
#define CMG_OPT                 0xF9            // get options {BUZZ(RAM/ROM)+POLARITY(ROM only)}
#define CMS_OPT                 0xF8            // set options {BUZZ(RAM/ROM)+POLARITY(ROM only)}
#define CMG_TMR                 0xF7            // get lock timers (ACK_TMR + ON_TMR, ROM only)
#define CMS_TMR                 0xF6            // set lock timers (ACK_TMR + ON_TMR, ROM only)
#define CMF_SW                  0xF5            // IO_SW control (RAM only)
#define CMF_BUZ                 0xF4            // buzzer control
#define CMF_KME                 0xF3            // erase unlock-UID's page(s)
#define CMG_KM                  0xF2            // get unlock-UID's page
#define CMS_KM                  0xF1            // save unlock-UID's page
#define CMG_IB                  0xF0            // get emulate parameters for i-Button
#define CMS_IB                  0xEF            // set emulate parameters for i-Button
#define CMG_SRD                 0xEE            // get simple read options (ROM only)
#define CMS_SRD                 0xED            // set simple read options (ROM only)
#define CMS_AKEY                0xEC            // set authorization key (RAM or ROM)
#define CMG_BUF                 0xEB            // get data from RX card buffer
#define CMS_BUF                 0xEA            // set data to TX card buffer
#define CMG_RAW                 0xE9            // get data from RAW card buffer
#define CMF_IO                  0xE8            // IO operation with PIC
#define CMF_D106A               0xE7            // decode RAW-buffer for baud rate 106Kbit/s
#define CMF_ACRCA               0xE6            // add odd parity bits for tx data
#define CMF_CCRCA               0xE5            // verify CRC (A-mode) in RX-buffer
#define CMF_APAR                0xE4            // add CRC (A-mode) for tx data
#define CMG_ISO                 0xE3            // get IO options (carrier disable & phase detector level/auto)
#define CMS_ISO                 0xE2            // set IO options (carrier disable & phase detector level/auto)
#define CMS_CBLK                0xE1            // write card blocks w/out authorization (block length 16 bytes
#define CMG_CBLK                0xE0            // read card blocks w/out authorization (block length 16 bytes)
#define CMS_CPGE                0xDF            // read card pages(s) w/out authorization (page length 4 bytes)
#define CMG_CPGE                0xDE            // write card page(s) w/out authorization (page length 4 bytes)
#define CMF_CSEL                0xDD            // wake-up PIC and SELECT procedure for it
#define CMF_CAUT                0xDC            // Crypto1 authorization
#define CMF_LCMD                0xDB            // long command IO

#define IO_CHFAIL               '-'             // fail marker
#define IO_CHOK                 '+'             // success marker
#define IO_CHRDY                'R'             // ready marker
#define IO_CHDAT                'D'             // data transfer start marker
#define IO_CHBUSY               'B'             // busy marker
#define IO_CHREQ                'Q'             // request marker
#define IO_CHPING               0xB0            // start ping value

#define PINGLEN_CN              8
#define HIDBUF_SZ               32

#define RDRBUF_SZ               33
#define KEYCRYPTO1_SZ           6

#pragma pack(1)
typedef struct  {
    union
    {
        HANDLE                  t;              // TTY handle
        libusb_device_handle    *u;             // USB handle
    } hL;                                       // handle
    DWORD       txq;                            // tx quantile
    DWORD       rxout;                          // rx timeout
    DWORD       txout;                          // tx timeout
    DWORD       wtout;                          // wait timeout
    PBYTE       inbuf;                          // in-queue
    BYTE        inlen;                          // length of in-queue
    PBYTE       outbuf;                         // out-queue
    BYTE        outlen; } CCR, *PCCR;           // length of out-queue
#pragma pack()

// test device handle
DLL_API BOOL link_isopen(PCCR pccr);

// close device handle
DLL_API void link_close(PCCR pccr);

// open USB device; return LERR_SUCCESS, LERR_HARDWARE
DLL_API DWORD link_hidopen(DWORD idx, PDWORD pusn, PCCR pccr);

// open COM port; return LERR_SUCCESS, LERR_HARDWARE
DLL_API DWORD link_comopen(DWORD port, DWORD cbr, PCCR pccr);

// queues flush; return LERR_SUCCESS, LERR_HARDWARE
DLL_API DWORD link_flush(PCCR pccr);

// byte transmitting then echo receiving; return LERR_SUCCESS, LERR_HARDWARE, LERR_TIMEOUT_RX, LERR_TIMEOUT_TX, LERR_NOTSYNC
DLL_API DWORD link_echobyte(PCCR pccr, BYTE dt);

// * wait for request from reader; return LERR_SUCCESS, LERR_HARDWARE, LERR_NOTSYNC, LERR_TIMEOUT_RX
DLL_API DWORD link_rqwait(PCCR pccr, PBYTE buf, BYTE len);

// * send acknowledge to reader; return LERR_SUCCESS, LERR_HARDWARE, LERR_NOTSYNC, LERR_TIMEOUT_RX, LERR_TIMEOUT_TX
DLL_API DWORD link_rqack(PCCR pccr, BYTE ack);

// main function for reader IO
DLL_API DWORD link_packet(PCCR pccr, BYTE cmd, BYTE parm, PBYTE outbuf, WORD outlen, PBYTE inbuf, WORD inlen);

#endif  // _RD0XAB_WIN_H_