/*
 *  GemCore.h
 *  $Id: GemCore.h,v 1.17 2012/04/08 19:09:47 rousseau Exp $
 *  ifd-GemPC
 *
 *  Created by JL Giraud <jl.giraud@free.fr> on Sun Nov 19 2000.
 *  Updated by Ludovic Rousseau <ludovic.rousseau@free.fr>, Oct 2001
 *
 *  License: this code is under a double licence COPYING.BSD and COPYING.GPL
 *
 */

#ifndef _GEMCORE_H_
#define _GEMCORE_H_

#include <pcsclite.h>
#ifdef __APPLE__
#include <wintypes.h>
#endif

/* Size of an ISO command (CLA+INS+P1+P2) */
#define ISO_CMD_SIZE 4
/* Offset of the length byte in an TPDU */
#define ISO_OFFSET_LENGTH 4
/* Offset of the data in a TPDU */
#define ISO_OFFSET_TPDU_DATA 5
/* ISO length size (1 in general) */
#define ISO_LENGTH_SIZE 1
/* ISO SW size */
#define ISO_SIZE_SW 2

/* Communication buffer size (max=cmd+adpu+Lc+data+Le) */
#define CMD_BUF_SIZE (1+4+1+256+1)
/* Larger communication buffer size (max=reader status+data+sw) */
#define RESP_BUF_SIZE (1+256+2)

/* Size of the command field in a gemcore command */
#define GC_SIZE_CMD 1
/* Size of the reader status */
#define GC_SIZE_STATUS 1

/* *** should disapear */
/* Offset of the status byte in a reader answer (CMD level) */
#define GC_STATUS_OFFSET 0

/* Offset of the command byte in a GemCore command (CMD level) */
#define GC_OFFSET_CMD 0
/* Offset of the APDU in a GemCore command (CMD level) */
#define GC_OFFSET_APDU 1
/* Offset of the Lc byte in the APDU of a Gemcore command */
#define GC_OFFSET_LENGTH (GC_OFFSET_APDU+ISO_OFFSET_LENGTH)
/* Offset of the Data in a TPDU Gemcore command */
#define GC_OFFSET_TPDU_CMD_DATA (GC_OFFSET_APDU+ISO_OFFSET_TPDU_DATA)
/* Offset of the DATA in a GemCore response (CMD level) */
#define GC_OFFSET_RESP_DATA 1
/* Nb of bytes added to the APDU in a GemCore command (CMD level) */
#define GC_FORMAT_SIZE 1

/* STAT byte offset in a response to CARD STATUS command (CMD level) */
#define GC_OFFSET_STAT_BYTE 0
/* Bit mask to get the reader power status */
#define GC_MASK_POWER 0x02
/* Bit mask to detect ICC presence */
#define GC_MASK_ICC_PRESENCE 0x04
/* size if CARD STATUS response */
#define GC_SIZE_CARD_STATUS 6

/* Maximum size of Data for ISO_Output before pcLongDataADPU is required */
#define GC_ISO_OUTPUT_MAX_DATA_LENGTH 252

/* Maximum size of Data for ISO_Output before pcLongDataADPU is required */
#define GC_ISO_INPUT_MAX_DATA_LENGTH 248

/* Maximum length for APDU command (ie CMD+2xlength+DataIn) */
#define GC_ISO_EXC_CMD_MAX_APDU_LENGTH 254

/* Maximum length for APDU response (ie Data + SW) */
#define GC_ISO_EXC_RESP_MAX_APDU_LENGTH 254

/* Length of the reader response to a transmit command */
#define GC_READER_TRANSMIT_RESP_LENGTH 1


/* Powerflag (used to detect quick insertion removals unnoticed by the
 * resource manager) */
/* Initial value */
#define POWERFLAGS_RAZ 0x00
/* Flag set when a power up has been requested */
#define MASK_POWERFLAGS_PUP 0x01
/* Flag set when a power down is requested */
#define MASK_POWERFLAGS_PDWN 0x02
/* Flag set when reader and card are EMV (use only APDU exchange) */
#define MASK_POWERFLAGS_EMV 0x04

/* Size of the GemCore version string */
#define IFD_LEN_VERSION 0x10

/* mode GemCore + ROS - TLP */
#define IFD_MODE_ROSNOTLP 1


/* Gemcore error codes */
typedef enum {
    GCORE_OK               = 0x00,
    GCORE_UNKNOWN_CMD      = 0x01,
    GCORE_IMPOS_OPERATION  = 0x02,
    GCORE_INC_NUMBER_ARG   = 0x03,
    GCORE_RESET_ERROR      = 0x10,
    GCORE_POWERED_DOWN     = 0x15,
    GCORE_MORE_DATA        = 0x1B,
    GCORE_WRONG_TCK        = 0x1D,
    GCORE_ATR              = 0xA0,
    GCORE_CARD_PROT_ERR    = 0xA1,
    GCORE_CARD_MUTE        = 0xA2,
    GCORE_PARITY_ERROR     = 0xA3,
    GCORE_CARD_T1_ABORT    = 0xA4,
    GCORE_READER_T1_ABORT  = 0xA5,
    GCORE_RESYNC           = 0xA6,
    GCORE_PTS              = 0xA7,
    GCORE_CARD_YON         = 0xA8,
    GCORE_INVALID_PROC_BYTE = 0xE4,
    GCORE_CARD_EXC_INT     = 0xE5,
    GCORE_NOT_9000		   = 0xE7,
    GCORE_CARD_REMOVED     = 0xF7,
    GCORE_CARD_MISSING     = 0xFB
} gcore_t;

/* Protocols  */
enum
{
    T_0                    = 0,
    T_1                    = 1
};

typedef struct GCORE_DESC
{
    DWORD nATRLength;
    UCHAR pcATRBuffer[MAX_ATR_SIZE];
    UCHAR bPowerFlags;
} GCoreDesc;

#ifndef TRUE
#define FALSE 0
#define TRUE 1
#endif

#endif

