
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>

#include <winscard.h>

/**
 * NTAG ADPU error codes
 */
typedef enum
{
    SUCCESS = 0,
    LENGTH_ERROR = 0x7E,
    AUTHENTICATION_ERROR = 0xAE,
    MEMORY_ERROR = 0xEE,
    COMMAND_ABORTED = 0xCA,
    PARAMETER_ERROR = 0x9E,
    NO_SUCH_KEY = 0x40,
    PERMISSION_DENIED = 0x9D,
    AUTHENTICATION_DELAY = 0xAD,
    INTEGRITY_ERROR = 0x1E,
    FILE_NOT_FOUND = 0xF0,
    BOUNDARY_ERROR = 0xBE,
} NTAG_ERROR;

/**
 * NTAG File access code definitions
 */
typedef enum
{
    USE_KEY_0,
    USE_KEY_1,
    USE_KEY_2,
    USE_KEY_3,
    USE_KEY_4,
    NUM_KEYS,

    OPEN_ACCESS = 0x0E,
    NO_ACCESS = 0x0F,
} FILE_ACCESS;

/**
 * NTAG command and file communication modes
 */
typedef enum
{
    PLAIN,      ///< No encryption in any direction
    MAC,        ///< MAC mode, write only operations
    ENCRYPTED   ///< Full encrypted, both directions
} COMM_MODE;

/**
 * Predefined Ntag424 file numbers and IDs
 */
#define NUM_NTAG424_FILES 4

#define APP_FILE_NO  (0x00u)
#define CC_FILE_NO   (0x01u)
#define NDEF_FILE_NO (0x02u)
#define DATA_FILE_NO (0x03u)

#define APP_FILE_ID  (0xE110u)
#define CC_FILE_ID   (0xE103u)
#define NDEF_FILE_ID (0xE104u)
#define DATA_FILE_ID (0xE105u)

/**
 * NTAG File communications control structure
 */
typedef struct 
{       
    unsigned file_no;   ///< 
    unsigned file_id;
    size_t size;
    FILE_ACCESS access;
    COMM_MODE comm_mode;
} TagFile;

/**
 * AES128 Definitions
 */
#define KEY_LEN (16u)  ///< AES keys are 16 bytes, 128 bits
typedef BYTE AesKey[KEY_LEN];

/**
 * NTAG transaction identifier definitions
 * 
 * A new transaction identifier is assigned with each 
 * authentication to the tag.
 */
#define TI_LEN (4u) ///< Transaction Identifier length
typedef BYTE TI[TI_LEN];

/**
 * Unique tag type identifier
 */
#define ATR_LEN (6u)
typedef BYTE RfidAtr[ATR_LEN];

/**
 * Ntag Definition and control
 */
typedef struct 
{
    const RfidAtr atr;
    const AesKey keys[NUM_KEYS];  ///< list of key values used for authentication
    const TagFile files[NUM_NTAG424_FILES];

    bool connected; ///< indicate that we are current connected to the reader
    size_t command_counter; ///< counter used for ADPU construction

    AesKey encrypt_key; ///< authentication derived AES encryption key
    AesKey cmac_key;    ///< authentication derived AES-MAC key
    TI ti;  ///< authentication derived transaction identifier

    pthread_t tid; ///< Monitor thread ID

    char* reader_name; ///< name of the reader returned by the driver to use
    SCARDCONTEXT context; ///< device driver context
    SCARDHANDLE handle; ///< handle to the connected card
    SCARD_READERSTATE reader_state; ///< current state of the reader, updated by monitor
    DWORD card_state; ///< current state of the card in the reader
	SCARD_IO_REQUEST card_protocol; ///< card protocol to be used


} Ntag424;

