/*
 * Copyright (C) 2010-2014 NXP Semiconductors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _PHNXPESEPROTO7816_3_H_
#define _PHNXPESEPROTO7816_3_H_
#include <phNxpEse_Internal.h>
#include <phNxpLog.h>
#include <phNxpEseDataMgr.h>
#include <NXP_ESE_FEATURES.h>



/**
 * \addtogroup ISO7816-3_protocol_lib
 * \brief 7816-3 PROTOCOL STACK
 * @{ */

/********************* Definitions and structures *****************************/

/*!
 * \brief S-Frame types used in 7816-3 protocol stack
 */
typedef enum sFrameTypes {
    RESYNCH_REQ = 0x00,/*!< Re-synchronisation request between host and ESE */
    RESYNCH_RSP = 0x20,/*!< Re-synchronisation response between host and ESE */
    IFS_REQ = 0x01,    /*!< IFSC size request */
    IFS_RES = 0x21,    /*!< IFSC size response */
    ABORT_REQ = 0x02,/*!< Abort request */
    ABORT_RES = 0x22,/*!< Abort response */
    WTX_REQ = 0x03,/*!< WTX request */
    WTX_RSP = 0x23,/*!< WTX response */
    INTF_RESET_REQ = 0x04,/*!< Interface reset request */
    INTF_RESET_RSP = 0x24,/*!< Interface reset response */
    PROP_END_APDU_REQ = 0x05,/*!< Proprietary Enf of APDU request */
    PROP_END_APDU_RSP = 0x25,/*!< Proprietary Enf of APDU response */
    HARD_RESET_REQ = 0x06,/*!< Chip reset request */
    HARD_RESET_RSP = 0x26,/*!< Chip reset request */
    ATR_REQ = 0x07,    /*!< ATR request */
    ATR_RSP = 0x27,    /*!< ATR response */
    INVALID_REQ_RES /*!< Invalid request */
} sFrameTypes_t;

/*!
 * \brief R-Frame types used in 7816-3 protocol stack
 */
typedef enum rFrameTypes
{
  RACK = 0x01, /*!< R-frame Acknowledgement frame indicator */
  RNACK = 0x02 /*!< R-frame Negative-Acknowledgement frame indicator */
}rFrameTypes_t;

/*!
 * \brief R-Frame error types used 7816-3 protocol stack
 */
typedef enum rFrameErrorTypes
{
  NO_ERROR, /*!< R-frame received with success */
  PARITY_ERROR, /*!< R-frame received with parity error */
  OTHER_ERROR, /*!< R-frame received with Other error */
  SOF_MISSED_ERROR, /*!< R-frame received with frame missing error */
  UNDEFINED_ERROR /*!< R-frame received with some undefined error */
}rFrameErrorTypes_t;

/*!
 * \brief Frame types used in 7816-3 protocol stack
 */
typedef enum phNxpEseProto7816_FrameTypes
{
  IFRAME,/*!< Frame type: I-frame */
  SFRAME,/*!< Frame type: S-frame */
  RFRAME,/*!< Frame type: R-frame */
  INVALID,/*!< Frame type: Invalid */
  UNKNOWN /*!< Frame type: Unknown */
}phNxpEseProto7816_FrameTypes_t;

/*!
 * \brief 7816-3 protocol stack states
 */
typedef enum phNxpEseProto7816_State
{
 PH_NXP_ESE_PROTO_7816_IDLE,/*!< 7816-3 protocol state: IDLE */
 PH_NXP_ESE_PROTO_7816_TRANSCEIVE,/*!< 7816-3 protocol state: TRANSCEIVE going on */
 PH_NXP_ESE_PROTO_7816_DEINIT /*!< 7816-3 protocol state: DeInit going on */
}phNxpEseProto7816_State_t;

/*!
 * \brief 7816-3 protocol transceive states
 */
typedef enum phNxpEseProto7816_TransceiveStates
{
  IDLE_STATE, /*!< 7816-3 protocol transceive state: IDLE */
  SEND_IFRAME, /*!< 7816-3 protocol transceive state: I-frame to be sent */
  SEND_R_NACK, /*!< 7816-3 protocol transceive state: R-NACK frame to be sent */
  SEND_R_ACK, /*!< 7816-3 protocol transceive state: R-ACK frame to be sent */
  SEND_S_RSYNC, /*!< 7816-3 protocol transceive state: S-frame re-synchronisation command to be sent */
  SEND_S_INTF_RST, /*!< 7816-3 protocol transceive state: S-frame interface reset command to be sent */
  SEND_S_EOS, /*!< 7816-3 protocol transceive state: S-frame end of session command to be sent */
  SEND_S_HRD_RST, /*!< 7816-3 protocol transceive state: S-frame 
						chip/hard reset command to be sent */
  SEND_S_WTX_REQ, /*!< 7816-3 protocol transceive state: S-frame WTX command to be sent */
  SEND_S_WTX_RSP, /*!< 7816-3 protocol transceive state: S-frame WTX response to be sent */
  SEND_S_IFS_ADJ, /*!< 7816-3 protocol transceive state: S-frame IFS adjustment */
  SEND_S_ATR_REQ,  /*!< 7816-3 protocol transceive state: S-frame ATR request */
}phNxpEseProto7816_TransceiveStates_t;

/*!
 * \brief I-frame information structure for ISO 7816-3
 *
 * This structure holds the  information of I-frame used for sending
 * and receiving the frame packet.
 *
 */
typedef struct iFrameInfo
{
  bool_t isChained; /*!< I-frame: Indicates if more frames to follow in the same data packet or not */
  uint8_t *p_data; /*!< I-frame: Actual data (Information field (INF)) */
  uint8_t seqNo; /*!< I-frame: Sequence number of the I-frame */
  uint32_t maxDataLenIFSC;   /*!< I-frame: Maximum data length to be allowed in a
							single I-frame */
  uint32_t maxDataLen; /*!< I-frame: Maximum data length to be allowed in a single I-frame */
  uint32_t defaultDataLenIFSC;   /*!< I-frame: Maximum data length to be allowed in a
                            single I-frame */
  uint32_t currentDataLenIFS;   /*!< I-frame: Current data length agreed
                            between PCD and Card to be allowed in a
                            single I-frame */

  uint32_t dataOffset; /*!< I-frame: Offset to the actual data(INF) for the current frame of the packet */
  uint32_t totalDataLen; /*!< I-frame: Total data left in the packet, used to set the chained flag/calculating offset */
  uint32_t sendDataLen; /*!< I-frame: the length of the I-frame actual data */
}iFrameInfo_t;

/*!
 * \brief S-frame information structure for ISO 7816-3
 *
 * This structure holds the  information of S-frame used for sending
 * and receiving the frame packet.
 *
 */
typedef struct sFrameInfo
{
  sFrameTypes_t sFrameType;/*!< S-frame: Type of S-frame cmd/rsp */
  uint8_t* p_data; /*!< S-frame: Actual data (Information field (INF)) */
  uint8_t len; /*!< S-frame: the length of the I-frame actual data */
}sFrameInfo_t;

/*!
 * \brief R-frame information structure for ISO 7816-3
 *
 * This structure holds the  information of R-frame used for sending
 * and receiving the frame packet.
 *
 */
typedef struct rFrameInfo
{
  uint8_t seqNo; /*!< R-frame: Sequence number of the expected I-frame */
  rFrameErrorTypes_t errCode; /*!< R-frame: Error type */
}rFrameInfo_t;

/*!
 * \brief ATRInfo: ISO7816 ATR Information bytes
 *
 * This structure holds ATR information bytes
 *
 */
typedef struct phNxpEseProto7816_ATR_Info {
  uint8_t len;          /*!< ATR: ATR length in bytes */
  uint8_t vendorID[5];  /*!< ATR: VendorID according to ISO7816-5 */
  uint8_t dll_IC;       /*!< ATR: Data Link Layer - Interface Character */
  uint8_t bgt[2];         /*!< ATR: Minimum guard time in milliseconds for
                        T=1 blocks sent in opposite directions */
  uint8_t bwt[2];         /*!< ATR: Maximum allowed command processing
                        time in milliseconds before card has sent either
                        command response or S(WTX) requesting processing time extension */
  uint8_t maxFreq[2];     /*!< ATR: Max supported  clock frequency in kHz  */
  uint8_t checksum;     /*!< ATR: Checksum (0 = LRC / 1 = CRC) */
  uint8_t defaultIFSC;  /*!< ATR: Default IFS size */
  uint8_t numChannels;  /*!< ATR: Number of logical connections supported */
  uint8_t maxIFSC[2];     /*!< ATR: Maximum size of IFS supported */
  uint8_t capbilities[2]; /*!< ATR: Bitmap to indicate various features supported by SE
                        Bit-1: SE Data Available Line supported.
                        Bit-2: SE Data available polarity. 1 - Data available GPIO will be pulled HIGH when SE response is ready
                        Bit 3: SE chip reset S-blk command supported
                        Bit-4: Extended frame length feature supported
                        Bit-5: Support for more than one logical channel
                        Bit 6 to 16: Reserved for future use
                        */
} phNxpEseProto7816_ATR_Info_t;

typedef struct phNxpEseProto7816_ATR_Info2 {
  uint8_t channelNo; /*!< ATR: Current ongoing channel no */
  uint8_t osType;    /*!< ATR: Indicates OS Type
                       JCOP_OS    = 0x01
                       UPDATER_OS = 0x02 */
} phNxpEseProto7816_ATR_Info2_t;

/*!
 * \brief Next/Last Tx information structure holding transceive data
 *
 * This structure holds the information of the next/last sent
 * I-frame/R-frame/S-frame depending on the frame type
 *
 */
typedef struct phNxpEseProto7816_NextTx_Info
{
  iFrameInfo_t IframeInfo; /*!< Information of the I-frame to be send next or the last sent I-frame depending on the frame type */
  rFrameInfo_t RframeInfo; /*!< Information of the R-frame to be send next or the last sent R-frame depending on the frame type */
  sFrameInfo_t SframeInfo; /*!< Information of the S-frame to be send next or the last sent S-frame depending on the frame type */
  phNxpEseProto7816_FrameTypes_t FrameType; /*!< Frame (I/R/S frames) type to be sent next */
}phNxpEseProto7816_NextTx_Info_t;

/*!
 * \brief Last sent Tx ransceive data
 *
 * This structure holds the information of the last sent
 * I-frame/R-frame/S-frame
 *
 */
typedef phNxpEseProto7816_NextTx_Info_t phNxpEseProto7816_LastTx_Info_t;

/*!
 * \brief Last Rx information structure holding transceive data
 *
 * This structure holds the information of the next/last sent
 * I-frame/R-frame/S-frame
 *
 */
typedef struct phNxpEseRx_Cntx
{
  iFrameInfo_t lastRcvdIframeInfo; /*!< I-frame: Last received frame */
  rFrameInfo_t lastRcvdRframeInfo; /*!< R-frame: Last received frame */
  sFrameInfo_t lastRcvdSframeInfo; /*!< S-frame: Last received frame */
  phNxpEseProto7816_FrameTypes_t lastRcvdFrameType; /*!< Last received frame type */
}phNxpEseRx_Cntx_t;

typedef struct phNxpEseProto7816_IntfResetParams {
  phNxpEse_data* pAtrData;
} phNxpEseProto7816_IntfResetParams_t;

/*!
 * \brief 7816-3 protocol stack context structure
 *
 * This structure holds the complete information of the
 * 7816-3 protocol stack context
 *
 */
typedef struct phNxpEseProto7816
{
  phNxpEseProto7816_LastTx_Info_t phNxpEseLastTx_Cntx; /*!< Last transmitted frame information */
  phNxpEseProto7816_NextTx_Info_t phNxpEseNextTx_Cntx; /*!< Next frame to be transmitted */
  phNxpEseRx_Cntx_t phNxpEseRx_Cntx; /*!< Last received frame information */
  phNxpEseProto7816_TransceiveStates_t phNxpEseProto7816_nextTransceiveState; /*!< Next Transceive state. It determines the next
                                                                                                                                         action to be done from host */
  phNxpEseProto7816_State_t phNxpEseProto7816_CurrentState;/*!< Current protocol stack state */
  uint8_t recoveryCounter; /*!< Keeps track of number of error recovery done. Stack exits after it reaches max. count  */
  unsigned long int wtx_counter_limit; /*!< Max. WTX counter limit */
  unsigned long int wtx_counter; /*!< WTX count tracker */
  uint8_t timeoutCounter; /*!< Keeps track of number of timeout happened. Stack exits after it reaches max. count  */
  phNxpEseProto7816_FrameTypes_t lastSentNonErrorframeType; /*!< Copy of the last sent non-error frame type: R-ACK, S-frame, I-frame */
  unsigned long int rnack_retry_limit;
  unsigned long int rnack_retry_counter;
  unsigned long int reset_type;
  uint32_t currentIFSDSize;
  phNxpEseProto7816_ATR_Info_t atrInfo;
  phNxpEseProto7816_ATR_Info2_t extndAtrInfo;
} phNxpEseProto7816_t;

/*!
 * \brief 7816-3 protocol stack init params
 *
 * This structure holds the parameters to be passed to open 7816-3 protocl stack instance
 *
 */
typedef struct phNxpEseProto7816InitParam
{
    unsigned long int wtx_counter_limit; /*!< WTX count limit */
    bool_t interfaceReset;               /*!< INTF reset required or not>*/
    unsigned long int rnack_retry_limit;
}phNxpEseProto7816InitParam_t;

/*!
 * \brief 7816-3 protocol PCB bit level structure
 *
 * This structure holds the bit level information of PCB byte
 * as per 7816-3 protocol
 *
 */
typedef struct phNxpEseProto7816_PCB_bits {
    uint8_t lsb :1; /*!< PCB: lsb */
    uint8_t bit2 :1; /*!< PCB: bit2 */
    uint8_t bit3 :1; /*!< PCB: bit3 */
    uint8_t bit4 :1; /*!< PCB: bit4 */
    uint8_t bit5 :1; /*!< PCB: bit5 */
    uint8_t bit6 :1; /*!< PCB: bit6 */
    uint8_t bit7 :1; /*!< PCB: bit7 */
    uint8_t msb :1; /*!< PCB: msb */
}phNxpEseProto7816_PCB_bits_t;

/*!
 * \brief 7816_3 protocol stack instance
 */
extern phNxpEseProto7816_t phNxpEseProto7816_3_Var;
/*!
 * IFS adjustment configuration value of IFSD for eSE
 * Any value set which is greater than IFSC value will be R-NACKed from JCOP
 * Default IFSC: 0x01FA = (0x0200 - 0x6(header))(As agreed with JCOP)
 */
#define ESE_IFSD_VALUE 0x0200
/*!
 * \brief Max. size of the frame that can be sent
 */
#define IFSC_SIZE_SEND  254
/*!
 * \brief Delay to be used before sending the next frame, after error reported by ESE
 */
#define DELAY_ERROR_RECOVERY 10000
/*!
 * \brief 7816-3 protocol frame header length
 */
#define PH_PROTO_7816_HEADER_LEN 0x03
/*!
 * \brief 7816-3 protocol ext.frame header length
 */
#define PH_PROTO_7816_EXT_HEADER_LEN 0x05
/*!
 * \brief 7816-3 protocol frame CRC length
 */
#define PH_PROTO_7816_CRC_LEN  0x01
/*!
 * \brief 7816-3 Chaining flag bit for masking
 */
#define PH_PROTO_7816_CHAINING  0x20
/*!
 * \brief 7816-3 PCB byte offset
 */
#define PH_PROPTO_7816_PCB_OFFSET 0x01
/*!
 * \brief 7816-3 frame length offset
 */
#define PH_PROPTO_7816_FRAME_LENGTH_OFFSET 0x02
/*!
 * \brief 7816-3 S-block request command mask
 */
#define PH_PROTO_7816_S_BLOCK_REQ    0xC0
/*!
 * \brief 7816-3 S-block response mask
 */
#define PH_PROTO_7816_S_BLOCK_RSP    0xE0
/*!
 * \brief 7816-3 S-block reset command mask
 */
#define PH_PROTO_7816_S_RESET        0x04
/*!
 * \brief 7816-3 S-block End of APDU cmd mask
 */
#define PH_PROTO_7816_S_END_OF_APDU  0x05
/*!
 * \brief 7816-3 S-block WTX mask
 */
#define PH_PROTO_7816_S_WTX          0x03
/*!
 * \brief 7816-3 S-block re-sync mask
 */
#define PH_PROTO_7816_S_RESYNCH      0x00
/*!
 * \brief 7816-3 S-block hard reset cmd mask
 */
#define PH_PROTO_7816_S_HRD_RST_CMD  0x06
/*!
 * \brief 7816-3 protocol max. error retry counter
 */
#if defined LOW_SPI_TEST && defined DEBUG_LOW
#define PH_PROTO_7816_FRAME_RETRY_COUNT 100
#else
#define PH_PROTO_7816_FRAME_RETRY_COUNT 01
#endif
/*!
 * \brief 7816-3 protocol max. WTX default count
 */
#if defined LOW_SPI_TEST && defined DEBUG_LOW
#define PH_PROTO_WTX_DEFAULT_COUNT   100
#else
#define PH_PROTO_WTX_DEFAULT_COUNT   3//500
#endif
/*!
 * \brief 7816-3 protocol max. timeout retry count
 */
#if defined LOW_SPI_TEST && defined DEBUG_LOW
#define PH_PROTO_7816_TIMEOUT_RETRY_COUNT 100
#else
#define PH_PROTO_7816_TIMEOUT_RETRY_COUNT 0
#endif
/*!
 * \brief 7816-3 to represent magic number zero
 */
#define PH_PROTO_7816_VALUE_ZERO 0x00
/*!
 * \brief 7816-3 to represent magic number one
 */
#define PH_PROTO_7816_VALUE_ONE 0x01
/*!
 * \brief 7816-3 for max retry for CRC error
 */
#define MAX_RNACK_RETRY_LIMIT 0x02
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define RESET_TYPE_NONE   0x00
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define EXTENDED_FRAME_MARKER 0xFF
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define PH_PROTO_CLOSE_ALL_SESSION_INF 0x01
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define PH_PROTO_CLOSE_ALL_SESSION_LEN 0x01
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define PH_PROTO_ATR_RSP_VENDOR_ID_LEN 0x05
/*
 * APIs exposed from the 7816-3 protocol layer
 */
#define PH_SE_OS_VERSION_10            0x10
/*!
 * \brief APIs exposed from the 7816-3 protocol layer
 */
#define PH_SE_OS_VERSION_11 0x11
#define PH_SE_OS_VERSION_20 0x20

/*!
 * \delay for hard reset response
 */
#define HARD_RESET_RES_DELAY 4000

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to reset just the current interface
 *
 *
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_IntfReset(void);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to close the 7816 protocol stack instance
 *
 *
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_Close(void);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to open the 7816 protocol stack instance
 *
 * \param[in]      phNxpEseProto7816InitParam_t: Initialization params
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to
 *                  1. Send the raw data received from application after computing LRC
 *                  2. Receive the the response data from ESE, decode, process and
 *                     store the data.
 *                  3. Get the final complete data and sent back to application
 *
 * \param[in]       phNxpEse_data: Command to ESE
 * \param[out]     phNxpEse_data: Response from ESE
 *
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data *pCmd, phNxpEse_data *pRsp);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to reset the 7816 protocol stack instance
 *
 *
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_Reset(void);


/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to set the max T=1 data send size
 *
 * \param[in]   uint16_t IFSC_Size: Max. size of the I-frame
 * \retval On success return true or else false.
 *
 */
ESESTATUS phNxpEseProto7816_SetIfs(uint16_t IFS_Size);
/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to set the endpoint
 *
 * \param[in]   uint8_t uEndPoint: Endpoint
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint);
/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to reset the endpoint
 *
 * \param[in]   uint8_t uEndPoint: Endpoint
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint);
/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to get ATR bytes for the application
 *
 * \param[out] phNxpEse_data: Response ATR bytes from ESE
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_getAtr(phNxpEse_data* pATRRsp);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to set the max T=1 data send size
 *
 * \retval Current IFS adjusted value wrt card.
 *
 */
uint16_t phNxpEseProto7816_GetIfs(void);
/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to set the max T=1 data send size
 *
 * \param[in]   uint16_t IFSC_Size: Max. size of the I-frame
 * \retval On success return TRUE or else FALSE.
 *
*/
ESESTATUS phNxpEseProto7816_SetIfscSize(uint16_t IFSC_Size);

/**
 * \ingroup ISO7816-3_protocol_lib
 * \brief This function is used to check eSE is alive/responding
 *
 *
 * \retval On responding return true or else false.
 *
 */
ESESTATUS phNxpEseProto7816_CloseAllSessions(void);
/** @} */
#endif /* _PHNXPESEPROTO7816_3_H_ */
