对比新文件 |
| | |
| | | #ifndef _7816_3_T1_T1_H_ |
| | | #define _7816_3_T1_T1_H_ |
| | | |
| | | #include <stdbool.h> |
| | | #include <stdint.h> |
| | | #include <stdlib.h> |
| | | |
| | | #include "se_common.h" |
| | | |
| | | #define CRC_PRESET 0xFFFF |
| | | #define CRC_POLYNOMIAL 0x8408 |
| | | |
| | | #define T1_DEFAULT_IFS 0xFE |
| | | |
| | | // Node address device to card |
| | | #define NAD_D2C 0x5A |
| | | // Node address card to device |
| | | #define NAD_C2DT 0xA5 |
| | | |
| | | // T1 prologue field length and offset [start] |
| | | #define T1_HEADER_LEN 0x03 |
| | | // ext frame's length is 2 bytes, refer to "GPC APDU Transport over SPI / I2C Version 1.0" |
| | | // The LEN and CRC fields shall have their Most Significant Byte sent first (i.e. big-endian order). |
| | | #define T1_EXT_HEADER_LEN 0x04 |
| | | // T1 protocol frame LRC length is 1 byte |
| | | #define T1_LRC_LEN 0x01 |
| | | // T1 protocol frame CRC length is 2 bytes |
| | | #define T1_CRC_LEN 0x02 |
| | | |
| | | #define T1_NAD_OFFSET 0x00 |
| | | #define T1_PCB_OFFSET 0x01 |
| | | #define T1_FRAME_LEN_OFFSET 0x02 |
| | | #define T1_FRAME_LEN_OFFSET2 0x03 |
| | | // T1 prologue field length and offset [end] |
| | | |
| | | // T1 flags bit for masking [start] |
| | | #define T1_CHAINING_MASK 0x20 |
| | | #define T1_S_BLOCK_REQ_MASK 0xC0 |
| | | #define T1_S_BLOCK_RSP_MASK 0xE0 |
| | | #define T1_I_BLOCK_SEQ_NO_MASK 0x40 |
| | | #define T1_R_BLOCK_SEQ_NO_MASK 0x10 |
| | | |
| | | #define T1_S_BLOCK_SUB_TYPE_MASK 0x3F |
| | | |
| | | // reference to ATR definition field: capbilities |
| | | #define T1_EXT_HEADER_LEN_MASK 0x04 |
| | | |
| | | typedef enum |
| | | { |
| | | LRC = 0x00, |
| | | CRC = 0x01, |
| | | CHK_INVALID, |
| | | } chk_code_types; |
| | | |
| | | /* atr info: ISO7816 ATR Information bytes |
| | | * This structure holds ATR information bytes, contains ATR length. |
| | | */ |
| | | typedef struct |
| | | { |
| | | uint8_t len; // ATR length in bytes |
| | | uint8_t vendor_ID[5]; // Vendor_ID according to ISO7816-5 |
| | | uint8_t dll_IC; // Data Link Layer - Interface Character |
| | | uint8_t bgt[2]; // Minimum guard time in milliseconds for |
| | | // T=1 blocks sent in opposite directions. |
| | | |
| | | uint8_t bwt[2]; // Maximum allowed command processing |
| | | // time in milliseconds before card has sent either |
| | | // command response or S(WTX) requesting processing time extension |
| | | |
| | | uint8_t max_freq[2]; // Max supported clock frequency in kHz |
| | | uint8_t checksum; // Checksum (0 = LRC / 1 = CRC) |
| | | uint8_t default_IFSC; // Default IFS size--Recommended value is 0x0102(258), APDU(256) + sw1sw2(2) |
| | | |
| | | uint8_t num_channels; // Number of logical connections supported |
| | | uint8_t max_IFSC[2]; // Maximum size of IFS supported |
| | | uint8_t capbilities[2]; // 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 |
| | | } atr_info; |
| | | |
| | | typedef struct |
| | | { |
| | | 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 |
| | | } T1_pcb_bits; |
| | | |
| | | /** T1 Frame types **/ |
| | | typedef enum |
| | | { |
| | | FRAME_TYPE_INVALID_MIN, // Frame type: INVALID |
| | | IFRAME, // Frame type: I-frame |
| | | RFRAME, // Frame type: R-frame |
| | | SFRAME, // Frame type: S-frame |
| | | FRAME_TYPE_INVALID_MAX, // Frame type: INVALID |
| | | } T1_frame_types; |
| | | |
| | | /** T1 S-Frame sub-types **/ |
| | | typedef enum |
| | | { |
| | | RESYNC_REQ = 0x00, // Re-synchronisation request between host and ESE |
| | | RESYNC_RSP = 0x20, // Re-synchronisation response between host and ESE |
| | | IFS_REQ = 0x01, // IFSC size request |
| | | IFS_RSP = 0x21, // IFSC size response |
| | | ABORT_REQ = 0x02, // Abort request |
| | | ABORT_RSP = 0x22, // Abort response |
| | | WTX_REQ = 0x03, // WTX request |
| | | WTX_RSP = 0x23, // WTX response |
| | | CIP_REQ = 0x04, // Interface reset request(Communication Interface Parameters request) |
| | | CIP_RSP = 0x24, // Interface reset response(Communication Interface Parameters 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 |
| | | SFRAME_TYPE_INVALID, // Invalid request |
| | | } Sframe_types; |
| | | |
| | | /** T1 R-Frame sub-types **/ |
| | | typedef enum |
| | | { |
| | | RACK = 0x00, // R-frame Acknowledgement frame indicator, an error-free acknowledgement |
| | | RNACK_PARITY_ERROR = 0x01, // R-frame Negative-Acknowledgement frame indicator, |
| | | // a redundancy code error or a character parity error. |
| | | RNACK_OTHER_ERROR = 0x02, // R-frame Negative-Acknowledgement frame indicator, other errors. |
| | | RNACK_INVALID_ERROR = 0xFF, // Invalid R-block request |
| | | } Rframe_types; |
| | | |
| | | typedef enum |
| | | { |
| | | STATE_IDEL = 0, |
| | | I_BLK, |
| | | R_ACK, |
| | | R_PARITY_ERR, |
| | | R_OTHER_ERR, |
| | | S_RESYNC_REQ, |
| | | S_IFS_REQ, |
| | | S_IFS_RSP, |
| | | S_ABORT_REQ, |
| | | S_ABORT_RSP, |
| | | S_WTX_REQ, |
| | | S_WTX_RSP, |
| | | S_CIP_REQ, |
| | | S_PROP_END_APDU_REQ, |
| | | S_ATR_REQ, |
| | | } T1_transmit_receive_state; |
| | | |
| | | /** T1 protocol param **/ |
| | | typedef struct |
| | | { |
| | | bool is_device_chaining; |
| | | bool is_card_chaining; |
| | | |
| | | uint8_t recovery_cnt; |
| | | |
| | | uint8_t resync_CIP_req_cnt; |
| | | |
| | | uint8_t blk_retry_cnt; |
| | | |
| | | uint8_t wtx_cnt; |
| | | |
| | | uint8_t wtx_info; |
| | | |
| | | T1_frame_types tx_frame_type; |
| | | Sframe_types tx_sub_Sframe_type; |
| | | Rframe_types tx_sub_Rframe_type; |
| | | |
| | | // for recovery |
| | | T1_frame_types last_rx_frame_type; |
| | | Sframe_types last_rx_sub_Sframe_type; |
| | | Rframe_types last_rx_sub_Rframe_type; |
| | | T1_pcb_bits last_rx_pcb_bits; |
| | | |
| | | // only I-block used |
| | | uint8_t *p_data_tx; |
| | | uint16_t tx_len; |
| | | uint8_t *p_data_tx_part; |
| | | uint16_t tx_len_part; |
| | | uint16_t tx_data_offset; |
| | | // end only I-block used |
| | | } T1_params; |
| | | |
| | | ESESTATUS t1_transmit_receive_apdu(uint8_t *p_cmd_apdu, uint16_t cmd_len); |
| | | ESESTATUS t1_CIP_req(void); |
| | | ESESTATUS t1_ATR_req(void); |
| | | ESESTATUS t1_IFSD_req(void); |
| | | ESESTATUS t1_prop_end_apdu_req(void); |
| | | ESESTATUS t1_receive_data_and_get(uint8_t **pp_Data, uint16_t *data_len); |
| | | |
| | | extern uint32_t g_recv_total_len; |
| | | extern uint8_t gp_data_rx[270]; |
| | | extern atr_info g_atr; |
| | | |
| | | ESESTATUS response_process(void); |
| | | ESESTATUS Transmit_receive_process(void); |
| | | ESESTATUS t1_send_Sframe(void); |
| | | ESESTATUS t1_send_Iframe(void); |
| | | ESESTATUS t1_send_Rframe(void); |
| | | ESESTATUS t1_chk_epilogue(uint8_t *p_data, uint16_t offset, uint16_t len); |
| | | ESESTATUS t1_decode_frame(uint16_t data_len); |
| | | uint8_t get_header_len(bool contains_epilogue); |
| | | ESESTATUS init_Iframe_from_cmd_apdu(uint8_t *p_cmd_apdu, uint16_t cmd_len); |
| | | void deinit_Iframe_from_cmd_apdu(void); |
| | | ESESTATUS do_T1_recovery_at_undecode(void); |
| | | ESESTATUS t1_transmit_only_apdu(uint8_t *p_cmd_apdu, uint16_t cmd_len); |
| | | ESESTATUS t1_receive_only_apdu(void); |
| | | |
| | | #endif /* _T1PROTOCOL_H_ */ |