Fork of the GitHub

Committer:
DiegoOstuni
Date:
Thu Nov 14 14:34:50 2019 +0000
Revision:
0:75fc82583a41
Add files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DiegoOstuni 0:75fc82583a41 1
DiegoOstuni 0:75fc82583a41 2 /******************************************************************************
DiegoOstuni 0:75fc82583a41 3 * @attention
DiegoOstuni 0:75fc82583a41 4 *
DiegoOstuni 0:75fc82583a41 5 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
DiegoOstuni 0:75fc82583a41 6 *
DiegoOstuni 0:75fc82583a41 7 * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
DiegoOstuni 0:75fc82583a41 8 * You may not use this file except in compliance with the License.
DiegoOstuni 0:75fc82583a41 9 * You may obtain a copy of the License at:
DiegoOstuni 0:75fc82583a41 10 *
DiegoOstuni 0:75fc82583a41 11 * http://www.st.com/myliberty
DiegoOstuni 0:75fc82583a41 12 *
DiegoOstuni 0:75fc82583a41 13 * Unless required by applicable law or agreed to in writing, software
DiegoOstuni 0:75fc82583a41 14 * distributed under the License is distributed on an "AS IS" BASIS,
DiegoOstuni 0:75fc82583a41 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
DiegoOstuni 0:75fc82583a41 16 * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
DiegoOstuni 0:75fc82583a41 17 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
DiegoOstuni 0:75fc82583a41 18 * See the License for the specific language governing permissions and
DiegoOstuni 0:75fc82583a41 19 * limitations under the License.
DiegoOstuni 0:75fc82583a41 20 *
DiegoOstuni 0:75fc82583a41 21 ******************************************************************************/
DiegoOstuni 0:75fc82583a41 22
DiegoOstuni 0:75fc82583a41 23
DiegoOstuni 0:75fc82583a41 24 /*
DiegoOstuni 0:75fc82583a41 25 * PROJECT: NFCC firmware
DiegoOstuni 0:75fc82583a41 26 * LANGUAGE: ISO C99
DiegoOstuni 0:75fc82583a41 27 */
DiegoOstuni 0:75fc82583a41 28
DiegoOstuni 0:75fc82583a41 29 /*! \file rfal_isoDep.c
DiegoOstuni 0:75fc82583a41 30 *
DiegoOstuni 0:75fc82583a41 31 * \author Gustavo Patricio
DiegoOstuni 0:75fc82583a41 32 *
DiegoOstuni 0:75fc82583a41 33 * \brief Implementation of ISO-DEP protocol
DiegoOstuni 0:75fc82583a41 34 *
DiegoOstuni 0:75fc82583a41 35 * This implementation was based on the following specs:
DiegoOstuni 0:75fc82583a41 36 * - ISO/IEC 14443-4 2nd Edition 2008-07-15
DiegoOstuni 0:75fc82583a41 37 * - NFC Forum Digital Protocol 1.1 2014-01-14
DiegoOstuni 0:75fc82583a41 38 *
DiegoOstuni 0:75fc82583a41 39 */
DiegoOstuni 0:75fc82583a41 40
DiegoOstuni 0:75fc82583a41 41 /*
DiegoOstuni 0:75fc82583a41 42 ******************************************************************************
DiegoOstuni 0:75fc82583a41 43 * INCLUDES
DiegoOstuni 0:75fc82583a41 44 ******************************************************************************
DiegoOstuni 0:75fc82583a41 45 */
DiegoOstuni 0:75fc82583a41 46
DiegoOstuni 0:75fc82583a41 47 #include "rfal_isoDep.h"
DiegoOstuni 0:75fc82583a41 48 #include "rfal_rf.h"
DiegoOstuni 0:75fc82583a41 49 #include "utils.h"
DiegoOstuni 0:75fc82583a41 50 #include "platform1.h"
DiegoOstuni 0:75fc82583a41 51
DiegoOstuni 0:75fc82583a41 52
DiegoOstuni 0:75fc82583a41 53 /*
DiegoOstuni 0:75fc82583a41 54 ******************************************************************************
DiegoOstuni 0:75fc82583a41 55 * ENABLE SWITCH
DiegoOstuni 0:75fc82583a41 56 ******************************************************************************
DiegoOstuni 0:75fc82583a41 57 */
DiegoOstuni 0:75fc82583a41 58
DiegoOstuni 0:75fc82583a41 59 #ifndef RFAL_FEATURE_ISO_DEP
DiegoOstuni 0:75fc82583a41 60 #error " RFAL: Module configuration missing. Please enable/disable ISO-DEP module by setting: RFAL_FEATURE_ISO_DEP "
DiegoOstuni 0:75fc82583a41 61 #endif
DiegoOstuni 0:75fc82583a41 62
DiegoOstuni 0:75fc82583a41 63 #if RFAL_FEATURE_ISO_DEP
DiegoOstuni 0:75fc82583a41 64
DiegoOstuni 0:75fc82583a41 65 /* Check for valid I-Block length [RFAL_ISODEP_FSX_16 ; RFAL_ISODEP_FSX_4096]*/
DiegoOstuni 0:75fc82583a41 66 #if( (RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN > 4096 ) || (RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN < 16) )
DiegoOstuni 0:75fc82583a41 67 #error " RFAL: Invalid ISO-DEP IBlock Max length. Please change RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN. "
DiegoOstuni 0:75fc82583a41 68 #endif
DiegoOstuni 0:75fc82583a41 69
DiegoOstuni 0:75fc82583a41 70 /* Check for valid APDU length, It must be n*IBlock */
DiegoOstuni 0:75fc82583a41 71 #if( (RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN < RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN) || (RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN % RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN) )
DiegoOstuni 0:75fc82583a41 72 #error " RFAL: Invalid ISO-DEP APDU Max length. Please change RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN. "
DiegoOstuni 0:75fc82583a41 73 #endif
DiegoOstuni 0:75fc82583a41 74
DiegoOstuni 0:75fc82583a41 75 /*
DiegoOstuni 0:75fc82583a41 76 ******************************************************************************
DiegoOstuni 0:75fc82583a41 77 * DEFINES
DiegoOstuni 0:75fc82583a41 78 ******************************************************************************
DiegoOstuni 0:75fc82583a41 79 */
DiegoOstuni 0:75fc82583a41 80 #define ISODEP_CRC_LEN RFAL_CRC_LEN /*!< ISO1443 CRC Length */
DiegoOstuni 0:75fc82583a41 81
DiegoOstuni 0:75fc82583a41 82
DiegoOstuni 0:75fc82583a41 83 #define ISODEP_PCB_POS (0) /*!< PCB position on message header*/
DiegoOstuni 0:75fc82583a41 84 #define ISODEP_SWTX_INF_POS (1) /*!< INF position in a S-WTX */
DiegoOstuni 0:75fc82583a41 85
DiegoOstuni 0:75fc82583a41 86 #define ISODEP_DID_POS (1) /*!< DID position on message header*/
DiegoOstuni 0:75fc82583a41 87 #define ISODEP_SWTX_PARAM_LEN (1) /*!< SWTX parameter length */
DiegoOstuni 0:75fc82583a41 88
DiegoOstuni 0:75fc82583a41 89 #define ISODEP_DSL_MAX_LEN ( RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN ) /*!< Deselect Req/Res length */
DiegoOstuni 0:75fc82583a41 90
DiegoOstuni 0:75fc82583a41 91 #define ISODEP_PCB_xBLOCK_MASK (0xC0) /*!< Bit mask for Block type */
DiegoOstuni 0:75fc82583a41 92 #define ISODEP_PCB_IBLOCK (0x00) /*!< Bit mask indicating a I-Block */
DiegoOstuni 0:75fc82583a41 93 #define ISODEP_PCB_RBLOCK (0x80) /*!< Bit mask indicating a R-Block */
DiegoOstuni 0:75fc82583a41 94 #define ISODEP_PCB_SBLOCK (0xC0) /*!< Bit mask indicating a S-Block */
DiegoOstuni 0:75fc82583a41 95 #define ISODEP_PCB_INVALID (0x40) /*!< Bit mask of an Invalid PCB */
DiegoOstuni 0:75fc82583a41 96
DiegoOstuni 0:75fc82583a41 97 #define ISODEP_HDR_MAX_LEN (RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN + RFAL_ISODEP_NAD_LEN) /*!< Max header length (PCB + DID + NAD) */
DiegoOstuni 0:75fc82583a41 98
DiegoOstuni 0:75fc82583a41 99 #define ISODEP_PCB_IB_VALID_MASK (ISODEP_PCB_B6_BIT | ISODEP_PCB_B2_BIT) /*!< Bit mask for the MUST bits on I-Block */
DiegoOstuni 0:75fc82583a41 100 #define ISODEP_PCB_IB_VALID_VAL (ISODEP_PCB_B2_BIT) /*!< Value for the MUST bits on I-Block */
DiegoOstuni 0:75fc82583a41 101 #define ISODEP_PCB_RB_VALID_MASK (ISODEP_PCB_B6_BIT | ISODEP_PCB_B3_BIT | ISODEP_PCB_B2_BIT) /*!< Bit mask for the MUST bits on R-Block */
DiegoOstuni 0:75fc82583a41 102 #define ISODEP_PCB_RB_VALID_VAL (ISODEP_PCB_B6_BIT | ISODEP_PCB_B2_BIT) /*!< Value for the MUST bits on R-Block */
DiegoOstuni 0:75fc82583a41 103 #define ISODEP_PCB_SB_VALID_MASK (ISODEP_PCB_B3_BIT | ISODEP_PCB_B2_BIT | ISODEP_PCB_B1_BIT) /*!< Bit mask for the MUST bits on I-Block */
DiegoOstuni 0:75fc82583a41 104 #define ISODEP_PCB_SB_VALID_VAL (ISODEP_PCB_B2_BIT) /*!< Value for the MUST bits on I-Block */
DiegoOstuni 0:75fc82583a41 105
DiegoOstuni 0:75fc82583a41 106
DiegoOstuni 0:75fc82583a41 107 #define ISODEP_PCB_B1_BIT (0x01) /*!< Bit mask for the RFU S Blocks */
DiegoOstuni 0:75fc82583a41 108 #define ISODEP_PCB_B2_BIT (0x02) /*!< Bit mask for the RFU bit2 in I,S,R Blocks */
DiegoOstuni 0:75fc82583a41 109 #define ISODEP_PCB_B3_BIT (0x04) /*!< Bit mask for the RFU bit3 in R Blocks */
DiegoOstuni 0:75fc82583a41 110 #define ISODEP_PCB_B6_BIT (0x20) /*!< Bit mask for the RFU bit2 in R Blocks */
DiegoOstuni 0:75fc82583a41 111 #define ISODEP_PCB_CHAINING_BIT (0x10) /*!< Bit mask for the chaining bit of an ISO DEP I-Block in PCB. */
DiegoOstuni 0:75fc82583a41 112 #define ISODEP_PCB_DID_BIT (0x08) /*!< Bit mask for the DID presence bit of an ISO DEP I,S,R Blocks PCB. */
DiegoOstuni 0:75fc82583a41 113 #define ISODEP_PCB_NAD_BIT (0x04) /*!< Bit mask for the NAD presence bit of an ISO DEP I,S,R Blocks in PCB */
DiegoOstuni 0:75fc82583a41 114 #define ISODEP_PCB_BN_MASK (0x01) /*!< Bit mask for the block number of an ISO DEP I,R Block in PCB */
DiegoOstuni 0:75fc82583a41 115
DiegoOstuni 0:75fc82583a41 116 #define ISODEP_SWTX_PL_MASK (0xC0) /*!< Bit mask for the Power Level bits of the inf byte of an WTX request or response */
DiegoOstuni 0:75fc82583a41 117 #define ISODEP_SWTX_WTXM_MASK (0x3F) /*!< Bit mask for the WTXM bits of the inf byte of an WTX request or response */
DiegoOstuni 0:75fc82583a41 118
DiegoOstuni 0:75fc82583a41 119
DiegoOstuni 0:75fc82583a41 120 #define ISODEP_RBLOCK_INF_LEN (0) /*!< INF length of R-Block Digital 1.1 15.1.3 */
DiegoOstuni 0:75fc82583a41 121 #define ISODEP_SDSL_INF_LEN (0) /*!< INF length of S(DSL) Digital 1.1 15.1.3 */
DiegoOstuni 0:75fc82583a41 122 #define ISODEP_SWTX_INF_LEN (1) /*!< INF length of S(WTX) Digital 1.1 15.2.2 */
DiegoOstuni 0:75fc82583a41 123
DiegoOstuni 0:75fc82583a41 124 #define ISODEP_WTXM_MIN (1) /*!< Minimum allowed value for the WTXM, Digital 1.0 13.2.2 */
DiegoOstuni 0:75fc82583a41 125 #define ISODEP_WTXM_MAX (59) /*!< Maximum allowed value for the WTXM, Digital 1.0 13.2.2 */
DiegoOstuni 0:75fc82583a41 126
DiegoOstuni 0:75fc82583a41 127 #define ISODEP_PCB_Sxx_MASK (0x30) /*!< Bit mask for the S-Block type */
DiegoOstuni 0:75fc82583a41 128 #define ISODEP_PCB_DESELECT (0x00) /*!< Bit mask for S-Block indicating Deselect */
DiegoOstuni 0:75fc82583a41 129 #define ISODEP_PCB_WTX (0x30) /*!< Bit mask for S-Block indicating Waiting Time eXtension */
DiegoOstuni 0:75fc82583a41 130
DiegoOstuni 0:75fc82583a41 131 #define ISODEP_PCB_Rx_MASK (0x10) /*!< Bit mask for the R-Block type */
DiegoOstuni 0:75fc82583a41 132 #define ISODEP_PCB_ACK (0x00) /*!< Bit mask for R-Block indicating ACK */
DiegoOstuni 0:75fc82583a41 133 #define ISODEP_PCB_NAK (0x10) /*!< Bit mask for R-Block indicating NAK */
DiegoOstuni 0:75fc82583a41 134
DiegoOstuni 0:75fc82583a41 135 /*! Maximum length of control message (no INF) */
DiegoOstuni 0:75fc82583a41 136 #define ISODEP_CONTROLMSG_BUF_LEN (RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN + RFAL_ISODEP_NAD_LEN + ISODEP_SWTX_PARAM_LEN)
DiegoOstuni 0:75fc82583a41 137
DiegoOstuni 0:75fc82583a41 138 #define ISODEP_FWT_DEACTIVATION (71680) /*!< FWT to be used after DESELECT, Digital 1.0 A9 */
DiegoOstuni 0:75fc82583a41 139 #define ISODEP_MAX_RERUNS (0x0FFFFFFF)/*!< Maximum rerun retrys for a blocking protocol run*/
DiegoOstuni 0:75fc82583a41 140
DiegoOstuni 0:75fc82583a41 141
DiegoOstuni 0:75fc82583a41 142 #define ISODEP_PCBSBLOCK ( 0x00 | ISODEP_PCB_SBLOCK | ISODEP_PCB_B2_BIT ) /*!< PCB Value of a S-Block */
DiegoOstuni 0:75fc82583a41 143 #define ISODEP_PCB_SDSL ( ISODEP_PCBSBLOCK | ISODEP_PCB_DESELECT ) /*!< PCB Value of a S-Block with DESELECT */
DiegoOstuni 0:75fc82583a41 144 #define ISODEP_PCB_SWTX ( ISODEP_PCBSBLOCK | ISODEP_PCB_WTX ) /*!< PCB Value of a S-Block with WTX */
DiegoOstuni 0:75fc82583a41 145
DiegoOstuni 0:75fc82583a41 146 #define ISODEP_FWI_LIS_MAX_NFC 8 /*!< FWT Listener Max FWIT4ATmax FWIBmax Digital 1.1 A6 & A3 */
DiegoOstuni 0:75fc82583a41 147 #define ISODEP_FWI_LIS_MAX_EMVCO 7 /*!< FWT Listener Max FWIMAX EMVCo 2.6 A.5 */
DiegoOstuni 0:75fc82583a41 148 #define ISODEP_FWI_LIS_MAX ((gIsoDep.compMode == RFAL_COMPLIANCE_MODE_EMV) ? ISODEP_FWI_LIS_MAX_EMVCO : ISODEP_FWI_LIS_MAX_NFC) /*!< FWI Listener Max as NFC / EMVCo */
DiegoOstuni 0:75fc82583a41 149 #define ISODEP_FWT_LIS_MAX rfalIsoDepFWI2FWT(ISODEP_FWI_LIS_MAX) /*!< FWT Listener Max */
DiegoOstuni 0:75fc82583a41 150
DiegoOstuni 0:75fc82583a41 151 #define ISODEP_FWI_MIN_10 (1) /*!< Minimum value for FWI Digital 1.0 11.6.2.17 */
DiegoOstuni 0:75fc82583a41 152 #define ISODEP_FWI_MIN_11 (0) /*!< Default value for FWI Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 153 #define ISODEP_FWI_MAX (14) /*!< Maximum value for FWI Digital 1.0 11.6.2.17 */
DiegoOstuni 0:75fc82583a41 154 #define ISODEP_SFGI_MIN (0) /*!< Default value for FWI Digital 1.1 13.6.2.22 */
DiegoOstuni 0:75fc82583a41 155 #define ISODEP_SFGI_MAX (14) /*!< Maximum value for FWI Digital 1.1 13.6.2.22 */
DiegoOstuni 0:75fc82583a41 156
DiegoOstuni 0:75fc82583a41 157
DiegoOstuni 0:75fc82583a41 158 /**********************************************************************************************************************/
DiegoOstuni 0:75fc82583a41 159 /**********************************************************************************************************************/
DiegoOstuni 0:75fc82583a41 160 #define RFAL_ISODEP_NO_PARAM (0) /*!< No parameter flag for isoDepHandleControlMsg() */
DiegoOstuni 0:75fc82583a41 161
DiegoOstuni 0:75fc82583a41 162 #define RFAL_ISODEP_CMD_RATS (0xE0) /*!< RATS command Digital 1.1 13.6.1 */
DiegoOstuni 0:75fc82583a41 163
DiegoOstuni 0:75fc82583a41 164 #define RFAL_ISODEP_ATS_MIN_LEN (1) /*!< Minimum ATS length Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 165 #define RFAL_ISODEP_ATS_HDR_LEN (5) /*!< ATS headerlength Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 166 #define RFAL_ISODEP_ATS_MAX_LEN (RFAL_ISODEP_ATS_HDR_LEN + RFAL_ISODEP_ATS_HB_MAX_LEN) /*!< Maximum ATS length Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 167 #define RFAL_ISODEP_ATS_T0_FSCI_MASK (0x0F) /*!< ATS T0's FSCI mask Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 168 #define RFAL_ISODEP_ATS_TB_FWI_SHIFT (4) /*!< ATS TB's FWI shift Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 169 #define RFAL_ISODEP_ATS_FWI_MASK (0x0F) /*!< ATS TB's FWI shift Digital 1.1 13.6.2 */
DiegoOstuni 0:75fc82583a41 170
DiegoOstuni 0:75fc82583a41 171
DiegoOstuni 0:75fc82583a41 172 #define RFAL_ISODEP_PPS_SB (0xD0) /*!< PPS REQ PPSS's SB value (no CID) ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 173 #define RFAL_ISODEP_PPS_MASK (0xF0) /*!< PPS REQ PPSS's SB mask ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 174 #define RFAL_ISODEP_PPS_SB_DID_MASK (0x0F) /*!< PPS REQ PPSS's DID|CID mask ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 175 #define RFAL_ISODEP_PPS_PPS0_PPS1_PRESENT (0x11) /*!< PPS REQ PPS0 indicating that PPS1 is present */
DiegoOstuni 0:75fc82583a41 176 #define RFAL_ISODEP_PPS_PPS1 (0x00) /*!< PPS REQ PPS1 fixed value ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 177 #define RFAL_ISODEP_PPS_PPS1_DSI_SHIFT (2) /*!< PPS REQ PPS1 fixed value ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 178 #define RFAL_ISODEP_PPS_PPS1_DXI_MASK (0x0F) /*!< PPS REQ PPS1 fixed value ISO14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 179 #define RFAL_ISODEP_PPS_RES_LEN (1) /*!< PPS Response length ISO14443-4 5.4 */
DiegoOstuni 0:75fc82583a41 180 #define RFAL_ISODEP_PPS_STARTBYTE_POS (0) /*!< PPS REQ PPSS's byte position ISO14443-4 5.4 */
DiegoOstuni 0:75fc82583a41 181 #define RFAL_ISODEP_PPS_PPS0_POS (1) /*!< PPS REQ PPS0's byte position ISO14443-4 5.4 */
DiegoOstuni 0:75fc82583a41 182 #define RFAL_ISODEP_PPS_PPS1_POS (2) /*!< PPS REQ PPS1's byte position ISO14443-4 5.4 */
DiegoOstuni 0:75fc82583a41 183 #define RFAL_ISODEP_PPS0_VALID_MASK (0xEF) /*!< PPS REQ PPS0 valid coding mask ISO14443-4 5.4 */
DiegoOstuni 0:75fc82583a41 184
DiegoOstuni 0:75fc82583a41 185 #define RFAL_ISODEP_CMD_ATTRIB (0x1D) /*!< ATTRIB command Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 186 #define RFAL_ISODEP_ATTRIB_PARAM2_DSI_SHIFT (6) /*!< ATTRIB PARAM2 DSI shift Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 187 #define RFAL_ISODEP_ATTRIB_PARAM2_DRI_SHIFT (4) /*!< ATTRIB PARAM2 DRI shift Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 188 #define RFAL_ISODEP_ATTRIB_PARAM2_DXI_MASK (0xF0) /*!< ATTRIB PARAM2 DxI mask Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 189 #define RFAL_ISODEP_ATTRIB_PARAM2_FSDI_MASK (0x0F) /*!< ATTRIB PARAM2 FSDI mask Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 190 #define RFAL_ISODEP_ATTRIB_PARAM4_DID_MASK (0x0F) /*!< ATTRIB PARAM4 DID mask Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 191 #define RFAL_ISODEP_ATTRIB_HDR_LEN (9) /*!< ATTRIB REQ header length Digital 1.1 14.6.1 */
DiegoOstuni 0:75fc82583a41 192
DiegoOstuni 0:75fc82583a41 193 #define RFAL_ISODEP_ATTRIB_RES_HDR_LEN (1) /*!< ATTRIB RES header length Digital 1.1 14.6.2 */
DiegoOstuni 0:75fc82583a41 194 #define RFAL_ISODEP_ATTRIB_RES_DID_MASK (0x0F) /*!< ATTRIB RES DID mask Digital 1.1 14.6.2 */
DiegoOstuni 0:75fc82583a41 195 #define RFAL_ISODEP_ATTRIB_RES_MLBI_MASK (0x0F) /*!< ATTRIB RES MBLI mask Digital 1.1 14.6.2 */
DiegoOstuni 0:75fc82583a41 196 #define RFAL_ISODEP_ATTRIB_RES_MLBI_SHIFT (4) /*!< ATTRIB RES MBLI shift Digital 1.1 14.6.2 */
DiegoOstuni 0:75fc82583a41 197
DiegoOstuni 0:75fc82583a41 198 #define RFAL_ISODEP_DID_MASK (0x0F) /*!< ISODEP's DID mask */
DiegoOstuni 0:75fc82583a41 199 #define RFAL_ISODEP_DID_00 (0) /*!< ISODEP's DID value 0 */
DiegoOstuni 0:75fc82583a41 200
DiegoOstuni 0:75fc82583a41 201
DiegoOstuni 0:75fc82583a41 202 #define RFAL_ISODEP_RATS_PARAM_FSDI_MASK (0xF0) /*!< Mask bits for FSDI in RATS */
DiegoOstuni 0:75fc82583a41 203 #define RFAL_ISODEP_RATS_PARAM_FSDI_SHIFT (4) /*!< Shift for FSDI in RATS */
DiegoOstuni 0:75fc82583a41 204 #define RFAL_ISODEP_RATS_PARAM_DID_MASK (0x0F) /*!< Mask bits for DID in RATS */
DiegoOstuni 0:75fc82583a41 205
DiegoOstuni 0:75fc82583a41 206 #define RFAL_ISODEP_ATS_TL_OFFSET (0x00) /*!< Offset of TL on ATS */
DiegoOstuni 0:75fc82583a41 207 #define RFAL_ISODEP_ATS_TA_OFFSET (0x02) /*!< Offset of TA if it is present on ATS */
DiegoOstuni 0:75fc82583a41 208 #define RFAL_ISODEP_ATS_TB_OFFSET (0x03) /*!< Offset of TB if both TA and TB is present on ATS */
DiegoOstuni 0:75fc82583a41 209 #define RFAL_ISODEP_ATS_TC_OFFSET (0x04) /*!< Offset of TC if both TA,TB & TC are present on ATS */
DiegoOstuni 0:75fc82583a41 210 #define RFAL_ISODEP_ATS_HIST_OFFSET (0x05) /*!< Offset of Historical Bytes if TA, TB & TC are present on ATS */
DiegoOstuni 0:75fc82583a41 211 #define RFAL_ISODEP_ATS_TC_ADV_FEAT (0x10) /*!< Bit mask indicating support for Advanced protocol features: DID & NAD */
DiegoOstuni 0:75fc82583a41 212 #define RFAL_ISODEP_ATS_TC_DID (0x02) /*!< Bit mask indicating support for DID */
DiegoOstuni 0:75fc82583a41 213 #define RFAL_ISODEP_ATS_TC_NAD (0x01) /*!< Bit mask indicating support for NAD */
DiegoOstuni 0:75fc82583a41 214
DiegoOstuni 0:75fc82583a41 215 #define RFAL_ISODEP_PPS0_PPS1_PRESENT (0x11) /*!< PPS0 byte indicating that PPS1 is present */
DiegoOstuni 0:75fc82583a41 216 #define RFAL_ISODEP_PPS0_PPS1_NOT_PRESENT (0x01) /*!< PPS0 byte indicating that PPS1 is NOT present */
DiegoOstuni 0:75fc82583a41 217 #define RFAL_ISODEP_PPS1_DRI_MASK (0x03) /*!< PPS1 byte DRI mask bits */
DiegoOstuni 0:75fc82583a41 218 #define RFAL_ISODEP_PPS1_DSI_MASK (0x0C) /*!< PPS1 byte DSI mask bits */
DiegoOstuni 0:75fc82583a41 219 #define RFAL_ISODEP_PPS1_DSI_SHIFT (2) /*!< PPS1 byte DSI shift */
DiegoOstuni 0:75fc82583a41 220 #define RFAL_ISODEP_PPS1_DxI_MASK (0x03) /*!< PPS1 byte DSI/DRS mask bits */
DiegoOstuni 0:75fc82583a41 221
DiegoOstuni 0:75fc82583a41 222
DiegoOstuni 0:75fc82583a41 223 /*! Delta Time for polling during Activation (ATS) : 20ms Digital 1.0 11.7.1.1 & A.7 */
DiegoOstuni 0:75fc82583a41 224 #define RFAL_ISODEP_T4T_DTIME_POLL_10 rfalConvMsTo1fc(20)
DiegoOstuni 0:75fc82583a41 225
DiegoOstuni 0:75fc82583a41 226 /*! Delta Time for polling during Activation (ATS) : 16.4ms Digital 1.1 13.8.1.1 & A.6
DiegoOstuni 0:75fc82583a41 227 * Use 16 ms as testcase T4AT_BI_10_03 sends a frame exactly at the border */
DiegoOstuni 0:75fc82583a41 228 #define RFAL_ISODEP_T4T_DTIME_POLL_11 216960
DiegoOstuni 0:75fc82583a41 229
DiegoOstuni 0:75fc82583a41 230 /*! Activation frame waiting time FWT(act) = 71680/fc (~5286us) Digital 1.1 13.8.1.1 & A.6 */
DiegoOstuni 0:75fc82583a41 231 #define RFAL_ISODEP_T4T_FWT_ACTIVATION (71680 + RFAL_ISODEP_T4T_DTIME_POLL_11)
DiegoOstuni 0:75fc82583a41 232
DiegoOstuni 0:75fc82583a41 233
DiegoOstuni 0:75fc82583a41 234 /*! Delta frame waiting time = 16/fc Digital 1.0 11.7.1.3 & A.7*/
DiegoOstuni 0:75fc82583a41 235 #define RFAL_ISODEP_DFWT_10 16
DiegoOstuni 0:75fc82583a41 236
DiegoOstuni 0:75fc82583a41 237 /*! Delta frame waiting time = 16/fc Digital 1.1 13.8.1.3 & A.8*/
DiegoOstuni 0:75fc82583a41 238 #define RFAL_ISODEP_DFWT_11 49152
DiegoOstuni 0:75fc82583a41 239
DiegoOstuni 0:75fc82583a41 240 /*
DiegoOstuni 0:75fc82583a41 241 ******************************************************************************
DiegoOstuni 0:75fc82583a41 242 * MACROS
DiegoOstuni 0:75fc82583a41 243 ******************************************************************************
DiegoOstuni 0:75fc82583a41 244 */
DiegoOstuni 0:75fc82583a41 245
DiegoOstuni 0:75fc82583a41 246 #define isoDep_PCBisIBlock( pcb ) ( (pcb & (ISODEP_PCB_xBLOCK_MASK | ISODEP_PCB_IB_VALID_MASK)) == (ISODEP_PCB_IBLOCK | ISODEP_PCB_IB_VALID_VAL)) /*!< Checks if pcb is a I-Block */
DiegoOstuni 0:75fc82583a41 247 #define isoDep_PCBisRBlock( pcb ) ( (pcb & (ISODEP_PCB_xBLOCK_MASK | ISODEP_PCB_RB_VALID_MASK)) == (ISODEP_PCB_RBLOCK | ISODEP_PCB_RB_VALID_VAL)) /*!< Checks if pcb is a R-Block */
DiegoOstuni 0:75fc82583a41 248 #define isoDep_PCBisSBlock( pcb ) ( (pcb & (ISODEP_PCB_xBLOCK_MASK | ISODEP_PCB_SB_VALID_MASK)) == (ISODEP_PCB_SBLOCK | ISODEP_PCB_SB_VALID_VAL)) /*!< Checks if pcb is a S-Block */
DiegoOstuni 0:75fc82583a41 249
DiegoOstuni 0:75fc82583a41 250 #define isoDep_PCBisChaining( pcb ) ( (pcb & ISODEP_PCB_CHAINING_BIT) == ISODEP_PCB_CHAINING_BIT) /*!< Checks if pcb is indicating chaining */
DiegoOstuni 0:75fc82583a41 251
DiegoOstuni 0:75fc82583a41 252 #define isoDep_PCBisDeselect( pcb ) ( (pcb & ISODEP_PCB_Sxx_MASK) == ISODEP_PCB_DESELECT) /*!< Checks if pcb is indicating DESELECT */
DiegoOstuni 0:75fc82583a41 253 #define isoDep_PCBisWTX( pcb ) ( (pcb & ISODEP_PCB_Sxx_MASK) == ISODEP_PCB_WTX) /*!< Checks if pcb is indicating WTX */
DiegoOstuni 0:75fc82583a41 254
DiegoOstuni 0:75fc82583a41 255 #define isoDep_PCBisACK( pcb ) ( (pcb & ISODEP_PCB_Rx_MASK) == ISODEP_PCB_ACK) /*!< Checks if pcb is indicating ACK */
DiegoOstuni 0:75fc82583a41 256 #define isoDep_PCBisNAK( pcb ) ( (pcb & ISODEP_PCB_Rx_MASK) == ISODEP_PCB_NAK) /*!< Checks if pcb is indicating ACK */
DiegoOstuni 0:75fc82583a41 257
DiegoOstuni 0:75fc82583a41 258 #define isoDep_PCBhasDID( pcb ) ( (pcb & ISODEP_PCB_DID_BIT) == ISODEP_PCB_DID_BIT) /*!< Checks if pcb is indicating DID */
DiegoOstuni 0:75fc82583a41 259 #define isoDep_PCBhasNAD( pcb ) ( (pcb & ISODEP_PCB_NAD_BIT) == ISODEP_PCB_NAD_BIT) /*!< Checks if pcb is indicating NAD */
DiegoOstuni 0:75fc82583a41 260
DiegoOstuni 0:75fc82583a41 261
DiegoOstuni 0:75fc82583a41 262 #define isoDep_PCBisIChaining( pcb ) ( isoDep_PCBisIBlock(pcb) && isoDep_PCBisChaining(pcb) ) /*!< Checks if pcb is I-Block indicating chaining*/
DiegoOstuni 0:75fc82583a41 263
DiegoOstuni 0:75fc82583a41 264 #define isoDep_PCBisSDeselect( pcb ) ( isoDep_PCBisSBlock(pcb) && isoDep_PCBisDeselect(pcb) ) /*!< Checks if pcb is S-Block indicating DESELECT*/
DiegoOstuni 0:75fc82583a41 265 #define isoDep_PCBisSWTX( pcb ) ( isoDep_PCBisSBlock(pcb) && isoDep_PCBisWTX(pcb) ) /*!< Checks if pcb is S-Block indicating WTX */
DiegoOstuni 0:75fc82583a41 266
DiegoOstuni 0:75fc82583a41 267 #define isoDep_PCBisRACK( pcb ) ( isoDep_PCBisRBlock(pcb) && isoDep_PCBisACK(pcb) ) /*!< Checks if pcb is R-Block indicating ACK */
DiegoOstuni 0:75fc82583a41 268 #define isoDep_PCBisRNAK( pcb ) ( isoDep_PCBisRBlock(pcb) && isoDep_PCBisNAK(pcb) ) /*!< Checks if pcb is R-Block indicating NAK */
DiegoOstuni 0:75fc82583a41 269
DiegoOstuni 0:75fc82583a41 270
DiegoOstuni 0:75fc82583a41 271 #define isoDep_PCBIBlock( bn ) ( (uint8_t)( 0x00 | ISODEP_PCB_IBLOCK | ISODEP_PCB_B2_BIT | (bn & ISODEP_PCB_BN_MASK) )) /*!< Returns an I-Block with the given block number (bn) */
DiegoOstuni 0:75fc82583a41 272 #define isoDep_PCBIBlockChaining( bn ) ( (uint8_t)(isoDep_PCBIBlock(bn) | ISODEP_PCB_CHAINING_BIT)) /*!< Returns an I-Block with the given block number (bn) indicating chaining */
DiegoOstuni 0:75fc82583a41 273
DiegoOstuni 0:75fc82583a41 274 #define isoDep_PCBRBlock( bn ) ( (uint8_t)( 0x00 | ISODEP_PCB_RBLOCK | ISODEP_PCB_B6_BIT | ISODEP_PCB_B2_BIT | (bn & ISODEP_PCB_BN_MASK) ) ) /*!< Returns an R-Block with the given block number (bn) */
DiegoOstuni 0:75fc82583a41 275 #define isoDep_PCBRACK( bn ) ( (uint8_t)( isoDep_PCBRBlock( bn ) | ISODEP_PCB_ACK ) ) /*!< Returns an R-Block with the given block number (bn) indicating ACK */
DiegoOstuni 0:75fc82583a41 276 #define isoDep_PCBRNAK( bn ) ( (uint8_t)( isoDep_PCBRBlock( bn ) | ISODEP_PCB_NAK ) ) /*!< Returns an R-Block with the given block number (bn) indicating NAK */
DiegoOstuni 0:75fc82583a41 277
DiegoOstuni 0:75fc82583a41 278
DiegoOstuni 0:75fc82583a41 279 #define isoDep_GetBN( pcb ) ( (uint8_t) ((pcb) & ISODEP_PCB_BN_MASK ) ) /*!< Returns the block number (bn) from the given pcb */
DiegoOstuni 0:75fc82583a41 280 #define isoDep_GetWTXM( inf ) ( (uint8_t) ((inf) & ISODEP_SWTX_WTXM_MASK) ) /*!< Returns the WTX value from the given inf byte */
DiegoOstuni 0:75fc82583a41 281 #define isoDep_isWTXMValid( wtxm ) (((wtxm) >= ISODEP_WTXM_MIN) && ((wtxm) <= ISODEP_WTXM_MAX)) /*!< Checks if the given wtxm is valid */
DiegoOstuni 0:75fc82583a41 282
DiegoOstuni 0:75fc82583a41 283 #define isoDep_WTXMListenerMax( fwt ) ( MIN( (uint8_t)(ISODEP_FWT_LIS_MAX / fwt), ISODEP_WTXM_MAX) ) /*!< Calculates the Max WTXM value for the given fwt as a Listener */
DiegoOstuni 0:75fc82583a41 284
DiegoOstuni 0:75fc82583a41 285 #define isoDepCalcdSGFT( s ) (384 * (uint32_t)(1 << (s))) /*!< Calculates the dSFGT with given SFGI Digital 1.1 13.8.2.1 & A.6*/
DiegoOstuni 0:75fc82583a41 286 #define isoDepCalcSGFT( s ) (4096 * (uint32_t)(1 << (s))) /*!< Calculates the SFGT with given SFGI Digital 1.1 13.8.2 */
DiegoOstuni 0:75fc82583a41 287
DiegoOstuni 0:75fc82583a41 288 #define isoDep_PCBNextBN( bn ) ((uint8_t)((bn^0x01) & ISODEP_PCB_BN_MASK)) /*!< Returns the value of the next block number based on bn */
DiegoOstuni 0:75fc82583a41 289 #define isoDep_PCBPrevBN( bn ) isoDep_PCBNextBN(bn) /*!< Returns the value of the previous block number based on bn */
DiegoOstuni 0:75fc82583a41 290 #define isoDep_ToggleBN( bn ) (bn = ((bn^0x01) & ISODEP_PCB_BN_MASK) ) /*!< Toggles the block number value of the given bn */
DiegoOstuni 0:75fc82583a41 291
DiegoOstuni 0:75fc82583a41 292 #define isoDep_WTXAdjust( v ) (v - (v>>3)) /*!< Adjust WTX timer value to a percentage of the total, current 88% */
DiegoOstuni 0:75fc82583a41 293
DiegoOstuni 0:75fc82583a41 294
DiegoOstuni 0:75fc82583a41 295 /*! ISO 14443-4 7.5.6.2 & Digital 1.1 - 15.2.6.2 The CE SHALL NOT attempt error recovery and remains in Rx mode upon Transmission or a Protocol Error */
DiegoOstuni 0:75fc82583a41 296 #define isoDepReEnableRx( rxB, rxBL, rxL ) rfalTransceiveBlockingTx( NULL, 0, rxB, rxBL, rxL, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FWT_NONE, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )
DiegoOstuni 0:75fc82583a41 297
DiegoOstuni 0:75fc82583a41 298 #define isoDepTimerStart( timer, time_ms ) timer = platformTimerCreate(time_ms) /*!< Configures and starts the WTX timer */
DiegoOstuni 0:75fc82583a41 299 #define isoDepTimerisExpired( timer ) platformTimerIsExpired( timer ) /*!< Checks WTX timer has expired */
DiegoOstuni 0:75fc82583a41 300
DiegoOstuni 0:75fc82583a41 301 /*
DiegoOstuni 0:75fc82583a41 302 ******************************************************************************
DiegoOstuni 0:75fc82583a41 303 * LOCAL DATA TYPES
DiegoOstuni 0:75fc82583a41 304 ******************************************************************************
DiegoOstuni 0:75fc82583a41 305 */
DiegoOstuni 0:75fc82583a41 306
DiegoOstuni 0:75fc82583a41 307 /*! Enumeration of the possible control message types */
DiegoOstuni 0:75fc82583a41 308 typedef enum isoDepControlMsg
DiegoOstuni 0:75fc82583a41 309 {
DiegoOstuni 0:75fc82583a41 310 ISODEP_R_ACK, /*!< R-ACK Acknowledge */
DiegoOstuni 0:75fc82583a41 311 ISODEP_R_NAK, /*!< R-NACK Negative acknowledge */
DiegoOstuni 0:75fc82583a41 312 ISODEP_S_WTX, /*!< S-WTX Waiting Time Extension */
DiegoOstuni 0:75fc82583a41 313 ISODEP_S_DSL /*!< S-DSL Deselect */
DiegoOstuni 0:75fc82583a41 314 } rfalIsoDepControlMsg;
DiegoOstuni 0:75fc82583a41 315
DiegoOstuni 0:75fc82583a41 316 /*! Enumeration of the IsoDep roles */
DiegoOstuni 0:75fc82583a41 317 typedef enum{
DiegoOstuni 0:75fc82583a41 318 ISODEP_ROLE_PCD, /*!< Perform as Reader/PCD */
DiegoOstuni 0:75fc82583a41 319 ISODEP_ROLE_PICC /*!< Perform as Card/PICC */
DiegoOstuni 0:75fc82583a41 320 } rfalIsoDepRole;
DiegoOstuni 0:75fc82583a41 321
DiegoOstuni 0:75fc82583a41 322 /*! ISO-DEP layer states */
DiegoOstuni 0:75fc82583a41 323 typedef enum isoDepState
DiegoOstuni 0:75fc82583a41 324 {
DiegoOstuni 0:75fc82583a41 325 ISODEP_ST_IDLE, /*!< Idle State */
DiegoOstuni 0:75fc82583a41 326 ISODEP_ST_PCD_TX, /*!< PCD Transmission State */
DiegoOstuni 0:75fc82583a41 327 ISODEP_ST_PCD_RX, /*!< PCD Reception State */
DiegoOstuni 0:75fc82583a41 328 ISODEP_ST_PCD_WAIT_DSL, /*!< PCD Wait for DSL response */
DiegoOstuni 0:75fc82583a41 329
DiegoOstuni 0:75fc82583a41 330 ISODEP_ST_PICC_ACT_ATS, /*!< PICC has replied to RATS (ATS) */
DiegoOstuni 0:75fc82583a41 331 ISODEP_ST_PICC_ACT_ATTRIB, /*!< PICC has replied to ATTRIB */
DiegoOstuni 0:75fc82583a41 332 ISODEP_ST_PICC_RX, /*!< PICC REception State */
DiegoOstuni 0:75fc82583a41 333 ISODEP_ST_PICC_SWTX, /*!< PICC Waiting Time eXtension */
DiegoOstuni 0:75fc82583a41 334 ISODEP_ST_PICC_TX, /*!< PICC Transmission State */
DiegoOstuni 0:75fc82583a41 335 } rfalIsoDepState;
DiegoOstuni 0:75fc82583a41 336
DiegoOstuni 0:75fc82583a41 337
DiegoOstuni 0:75fc82583a41 338
DiegoOstuni 0:75fc82583a41 339
DiegoOstuni 0:75fc82583a41 340 /*! Holds all ISO-DEP data(counters, buffers, ID, timeouts, frame size)*/
DiegoOstuni 0:75fc82583a41 341 typedef struct{
DiegoOstuni 0:75fc82583a41 342 rfalIsoDepState state; /*!< ISO-DEP module state */
DiegoOstuni 0:75fc82583a41 343 rfalIsoDepRole role; /*!< Current ISO-DEP role */
DiegoOstuni 0:75fc82583a41 344
DiegoOstuni 0:75fc82583a41 345 uint8_t blockNumber; /*!< Current block number */
DiegoOstuni 0:75fc82583a41 346 uint8_t did; /*!< Current DID */
DiegoOstuni 0:75fc82583a41 347 uint8_t nad; /*!< Current DID */
DiegoOstuni 0:75fc82583a41 348 uint8_t cntIRetrys; /*!< I-Block retry counter */
DiegoOstuni 0:75fc82583a41 349 uint8_t cntRRetrys; /*!< R-Block retry counter */
DiegoOstuni 0:75fc82583a41 350 uint8_t cntSRetrys; /*!< S-Block retry counter */
DiegoOstuni 0:75fc82583a41 351 uint32_t fwt; /*!< Current FWT (Frame Waiting Time) */
DiegoOstuni 0:75fc82583a41 352 uint32_t dFwt; /*!< Current delta FWT */
DiegoOstuni 0:75fc82583a41 353 uint16_t fsx; /*!< Current FSx FSC or FSD (max Frame size) */
DiegoOstuni 0:75fc82583a41 354 bool isTxChaining; /*!< Flag for chaining on Tx */
DiegoOstuni 0:75fc82583a41 355 bool isRxChaining; /*!< Flag for chaining on Rx */
DiegoOstuni 0:75fc82583a41 356 uint8_t* txBuf; /*!< Tx buffer pointer */
DiegoOstuni 0:75fc82583a41 357 uint8_t* rxBuf; /*!< Rx buffer pointer */
DiegoOstuni 0:75fc82583a41 358 uint16_t txBufLen; /*!< Tx buffer length */
DiegoOstuni 0:75fc82583a41 359 uint16_t rxBufLen; /*!< Rx buffer length */
DiegoOstuni 0:75fc82583a41 360 uint8_t txBufInfPos; /*!< Start of payload in txBuf */
DiegoOstuni 0:75fc82583a41 361 uint8_t rxBufInfPos; /*!< Start of payload in rxBuf */
DiegoOstuni 0:75fc82583a41 362
DiegoOstuni 0:75fc82583a41 363
DiegoOstuni 0:75fc82583a41 364 uint16_t ourFsx; /*!< Our current FSx FSC or FSD (Frame size) */
DiegoOstuni 0:75fc82583a41 365 uint8_t lastPCB; /*!< Last PCB sent */
DiegoOstuni 0:75fc82583a41 366 uint8_t lastWTXM; /*!< Last WTXM sent */
DiegoOstuni 0:75fc82583a41 367 uint8_t atsTA; /*!< TA on ATS */
DiegoOstuni 0:75fc82583a41 368 uint8_t hdrLen; /*!< Current ISO-DEP length */
DiegoOstuni 0:75fc82583a41 369 rfalBitRate txBR; /*!< Current Tx Bit Rate */
DiegoOstuni 0:75fc82583a41 370 rfalBitRate rxBR; /*!< Current Rx Bit Rate */
DiegoOstuni 0:75fc82583a41 371 uint16_t *rxLen; /*!< Output parameter ptr to Rx length */
DiegoOstuni 0:75fc82583a41 372 bool *rxChaining; /*!< Output parameter ptr to Rx chaining flag */
DiegoOstuni 0:75fc82583a41 373 uint32_t WTXTimer; /*!< Timer used for WTX */
DiegoOstuni 0:75fc82583a41 374 bool lastDID00; /*!< Last PCD block had DID flag (for DID = 0) */
DiegoOstuni 0:75fc82583a41 375
DiegoOstuni 0:75fc82583a41 376 bool isTxPending; /*!< Flag pending Block while waiting WTX Ack */
DiegoOstuni 0:75fc82583a41 377 bool isWait4WTX; /*!< Flag for waiting WTX Ack */
DiegoOstuni 0:75fc82583a41 378
DiegoOstuni 0:75fc82583a41 379 uint32_t SFGTTimer; /*!< Timer used for SFGT */
DiegoOstuni 0:75fc82583a41 380
DiegoOstuni 0:75fc82583a41 381 uint8_t maxRetriesI; /*!< Number of retries for a I-Block */
DiegoOstuni 0:75fc82583a41 382 uint8_t maxRetriesS; /*!< Number of retries for a S-Block */
DiegoOstuni 0:75fc82583a41 383 uint8_t maxRetriesR; /*!< Number of retries for a R-Block */
DiegoOstuni 0:75fc82583a41 384 uint8_t maxRetriesRATS;/*!< Number of retries for RATS */
DiegoOstuni 0:75fc82583a41 385
DiegoOstuni 0:75fc82583a41 386 rfalComplianceMode compMode; /*!< Compliance mode */
DiegoOstuni 0:75fc82583a41 387
DiegoOstuni 0:75fc82583a41 388 rfalIsoDepListenActvParam actvParam; /*!< Listen Activation context */
DiegoOstuni 0:75fc82583a41 389
DiegoOstuni 0:75fc82583a41 390 rfalIsoDepApduTxRxParam APDUParam; /*!< APDU TxRx params */
DiegoOstuni 0:75fc82583a41 391 uint16_t APDUTxPos; /*!< APDU Tx position */
DiegoOstuni 0:75fc82583a41 392 uint16_t APDURxPos; /*!< APDU Rx position */
DiegoOstuni 0:75fc82583a41 393 bool isAPDURxChaining; /*!< APDU Transceive chaining flag */
DiegoOstuni 0:75fc82583a41 394
DiegoOstuni 0:75fc82583a41 395 }rfalIsoDep;
DiegoOstuni 0:75fc82583a41 396
DiegoOstuni 0:75fc82583a41 397
DiegoOstuni 0:75fc82583a41 398
DiegoOstuni 0:75fc82583a41 399 /*
DiegoOstuni 0:75fc82583a41 400 ******************************************************************************
DiegoOstuni 0:75fc82583a41 401 * LOCAL VARIABLES
DiegoOstuni 0:75fc82583a41 402 ******************************************************************************
DiegoOstuni 0:75fc82583a41 403 */
DiegoOstuni 0:75fc82583a41 404
DiegoOstuni 0:75fc82583a41 405 static rfalIsoDep gIsoDep; /*!< ISO-DEP Module instance */
DiegoOstuni 0:75fc82583a41 406
DiegoOstuni 0:75fc82583a41 407 /*
DiegoOstuni 0:75fc82583a41 408 ******************************************************************************
DiegoOstuni 0:75fc82583a41 409 * LOCAL FUNCTION PROTOTYPES
DiegoOstuni 0:75fc82583a41 410 ******************************************************************************
DiegoOstuni 0:75fc82583a41 411 */
DiegoOstuni 0:75fc82583a41 412 static void isoDepClearCounters( void );
DiegoOstuni 0:75fc82583a41 413 static ReturnCode isoDepTx( uint8_t pcb, uint8_t* txBuf, uint8_t *infBuf, uint16_t infLen, uint32_t fwt, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
DiegoOstuni 0:75fc82583a41 414 static ReturnCode isoDepDataExchangePICC( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
DiegoOstuni 0:75fc82583a41 415 static ReturnCode isoDepDataExchangePCD( uint16_t *outActRxLen, bool *outIsChaining, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
DiegoOstuni 0:75fc82583a41 416 static ReturnCode isoDepHandleControlMsg( rfalIsoDepControlMsg controlMsg, uint8_t param, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
DiegoOstuni 0:75fc82583a41 417 static ReturnCode isoDepReSendControlMsg( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
DiegoOstuni 0:75fc82583a41 418 static void rfalIsoDepCalcBitRate(rfalBitRate maxAllowedBR, uint8_t piccBRCapability, rfalBitRate *dsi, rfalBitRate *dri);
DiegoOstuni 0:75fc82583a41 419 static void rfalIsoDepApdu2IBLockParam( rfalIsoDepApduTxRxParam apduParam, rfalIsoDepTxRxParam *iBlockParam, uint16_t txPos, uint16_t rxPos );
DiegoOstuni 0:75fc82583a41 420
DiegoOstuni 0:75fc82583a41 421
DiegoOstuni 0:75fc82583a41 422 /*
DiegoOstuni 0:75fc82583a41 423 ******************************************************************************
DiegoOstuni 0:75fc82583a41 424 * LOCAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 425 ******************************************************************************
DiegoOstuni 0:75fc82583a41 426 */
DiegoOstuni 0:75fc82583a41 427
DiegoOstuni 0:75fc82583a41 428 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 429 static void isoDepClearCounters( void )
DiegoOstuni 0:75fc82583a41 430 {
DiegoOstuni 0:75fc82583a41 431 gIsoDep.cntIRetrys = 0;
DiegoOstuni 0:75fc82583a41 432 gIsoDep.cntRRetrys = 0;
DiegoOstuni 0:75fc82583a41 433 gIsoDep.cntSRetrys = 0;
DiegoOstuni 0:75fc82583a41 434 }
DiegoOstuni 0:75fc82583a41 435
DiegoOstuni 0:75fc82583a41 436 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 437 static ReturnCode isoDepTx( uint8_t pcb, uint8_t* txBuf, uint8_t *infBuf, uint16_t infLen, uint32_t fwt,SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 438 {
DiegoOstuni 0:75fc82583a41 439 uint8_t *txBlock;
DiegoOstuni 0:75fc82583a41 440 uint16_t txBufLen;
DiegoOstuni 0:75fc82583a41 441
DiegoOstuni 0:75fc82583a41 442
DiegoOstuni 0:75fc82583a41 443 txBlock = infBuf; /* Point to beginning of the INF, and go backwards */
DiegoOstuni 0:75fc82583a41 444 gIsoDep.lastPCB = pcb; /* Store the last PCB sent */
DiegoOstuni 0:75fc82583a41 445
DiegoOstuni 0:75fc82583a41 446
DiegoOstuni 0:75fc82583a41 447 if( infLen > 0 )
DiegoOstuni 0:75fc82583a41 448 {
DiegoOstuni 0:75fc82583a41 449 if((infBuf - txBuf) < gIsoDep.hdrLen ) /* Check that we can fit the header in the given space */
DiegoOstuni 0:75fc82583a41 450 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 451 }
DiegoOstuni 0:75fc82583a41 452
DiegoOstuni 0:75fc82583a41 453
DiegoOstuni 0:75fc82583a41 454 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 455 /* Compute optional PCB bits */
DiegoOstuni 0:75fc82583a41 456 if((gIsoDep.did != RFAL_ISODEP_NO_DID) || ((gIsoDep.did == RFAL_ISODEP_DID_00) && gIsoDep.lastDID00) ) pcb |= ISODEP_PCB_DID_BIT;
DiegoOstuni 0:75fc82583a41 457 if(gIsoDep.nad != RFAL_ISODEP_NO_NAD) pcb |= ISODEP_PCB_NAD_BIT;
DiegoOstuni 0:75fc82583a41 458 if((gIsoDep.isTxChaining) && (isoDep_PCBisIBlock(pcb)) ) pcb |= ISODEP_PCB_CHAINING_BIT;
DiegoOstuni 0:75fc82583a41 459
DiegoOstuni 0:75fc82583a41 460
DiegoOstuni 0:75fc82583a41 461 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 462 /* Compute Payload on the given txBuf, start by the PCB | DID | NAD | before INF */
DiegoOstuni 0:75fc82583a41 463
DiegoOstuni 0:75fc82583a41 464 if(gIsoDep.nad != RFAL_ISODEP_NO_NAD)
DiegoOstuni 0:75fc82583a41 465 *(--txBlock) = gIsoDep.nad; /* NAD is optional */
DiegoOstuni 0:75fc82583a41 466
DiegoOstuni 0:75fc82583a41 467 if( (gIsoDep.did != RFAL_ISODEP_NO_DID) || ((gIsoDep.did == RFAL_ISODEP_DID_00) && gIsoDep.lastDID00) )
DiegoOstuni 0:75fc82583a41 468 *(--txBlock) = gIsoDep.did; /* DID is optional */
DiegoOstuni 0:75fc82583a41 469
DiegoOstuni 0:75fc82583a41 470 *(--txBlock) = pcb; /* PCB always present */
DiegoOstuni 0:75fc82583a41 471
DiegoOstuni 0:75fc82583a41 472
DiegoOstuni 0:75fc82583a41 473 txBufLen = infLen + (infBuf - txBlock); /* Calculate overall buffer size */
DiegoOstuni 0:75fc82583a41 474
DiegoOstuni 0:75fc82583a41 475 if( txBufLen > (gIsoDep.fsx - ISODEP_CRC_LEN) )/* Check if msg length violates the maximum frame size FSC */
DiegoOstuni 0:75fc82583a41 476 return ERR_NOTSUPP;
DiegoOstuni 0:75fc82583a41 477
DiegoOstuni 0:75fc82583a41 478 return rfalTransceiveBlockingTx( txBlock, txBufLen, gIsoDep.rxBuf, gIsoDep.rxBufLen, gIsoDep.rxLen, RFAL_TXRX_FLAGS_DEFAULT, ((gIsoDep.role == ISODEP_ROLE_PICC) ? RFAL_FWT_NONE : fwt ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 479 }
DiegoOstuni 0:75fc82583a41 480
DiegoOstuni 0:75fc82583a41 481 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 482 static ReturnCode isoDepHandleControlMsg( rfalIsoDepControlMsg controlMsg, uint8_t param, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 483 {
DiegoOstuni 0:75fc82583a41 484 uint8_t pcb;
DiegoOstuni 0:75fc82583a41 485 uint8_t contolMsg[ISODEP_CONTROLMSG_BUF_LEN];
DiegoOstuni 0:75fc82583a41 486 uint8_t infLen;
DiegoOstuni 0:75fc82583a41 487 uint32_t fwtTemp;
DiegoOstuni 0:75fc82583a41 488
DiegoOstuni 0:75fc82583a41 489 infLen = 0;
DiegoOstuni 0:75fc82583a41 490 fwtTemp = (gIsoDep.fwt + gIsoDep.dFwt);
DiegoOstuni 0:75fc82583a41 491
DiegoOstuni 0:75fc82583a41 492 switch( controlMsg )
DiegoOstuni 0:75fc82583a41 493 {
DiegoOstuni 0:75fc82583a41 494 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 495 case ISODEP_R_ACK:
DiegoOstuni 0:75fc82583a41 496
DiegoOstuni 0:75fc82583a41 497 if( gIsoDep.cntRRetrys++ > gIsoDep.maxRetriesR )
DiegoOstuni 0:75fc82583a41 498 {
DiegoOstuni 0:75fc82583a41 499 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 500 }
DiegoOstuni 0:75fc82583a41 501
DiegoOstuni 0:75fc82583a41 502 pcb = isoDep_PCBRACK( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 503 break;
DiegoOstuni 0:75fc82583a41 504
DiegoOstuni 0:75fc82583a41 505 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 506 case ISODEP_R_NAK:
DiegoOstuni 0:75fc82583a41 507 if( gIsoDep.cntRRetrys++ > gIsoDep.maxRetriesR )
DiegoOstuni 0:75fc82583a41 508 {
DiegoOstuni 0:75fc82583a41 509 return ERR_TIMEOUT;
DiegoOstuni 0:75fc82583a41 510 }
DiegoOstuni 0:75fc82583a41 511
DiegoOstuni 0:75fc82583a41 512 pcb = isoDep_PCBRNAK( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 513 break;
DiegoOstuni 0:75fc82583a41 514
DiegoOstuni 0:75fc82583a41 515 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 516 case ISODEP_S_WTX:
DiegoOstuni 0:75fc82583a41 517 if( gIsoDep.cntSRetrys++ > gIsoDep.maxRetriesS )
DiegoOstuni 0:75fc82583a41 518 {
DiegoOstuni 0:75fc82583a41 519 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 520 }
DiegoOstuni 0:75fc82583a41 521
DiegoOstuni 0:75fc82583a41 522 /* Check if WTXM is valid */
DiegoOstuni 0:75fc82583a41 523 if( ! isoDep_isWTXMValid(param) )
DiegoOstuni 0:75fc82583a41 524 {
DiegoOstuni 0:75fc82583a41 525 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 526 }
DiegoOstuni 0:75fc82583a41 527
DiegoOstuni 0:75fc82583a41 528 if( gIsoDep.role == ISODEP_ROLE_PCD )
DiegoOstuni 0:75fc82583a41 529 {
DiegoOstuni 0:75fc82583a41 530 /* Calculate temp Wait Time eXtension */
DiegoOstuni 0:75fc82583a41 531 fwtTemp = (gIsoDep.fwt * param);
DiegoOstuni 0:75fc82583a41 532 fwtTemp = MIN( RFAL_ISODEP_MAX_FWT, fwtTemp );
DiegoOstuni 0:75fc82583a41 533 fwtTemp += gIsoDep.dFwt;
DiegoOstuni 0:75fc82583a41 534 }
DiegoOstuni 0:75fc82583a41 535
DiegoOstuni 0:75fc82583a41 536 pcb = ISODEP_PCB_SWTX;
DiegoOstuni 0:75fc82583a41 537 contolMsg[ RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN + infLen++] = param;
DiegoOstuni 0:75fc82583a41 538 break;
DiegoOstuni 0:75fc82583a41 539
DiegoOstuni 0:75fc82583a41 540 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 541 case ISODEP_S_DSL:
DiegoOstuni 0:75fc82583a41 542 if( gIsoDep.cntSRetrys++ > gIsoDep.maxRetriesS )
DiegoOstuni 0:75fc82583a41 543 {
DiegoOstuni 0:75fc82583a41 544 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 545 }
DiegoOstuni 0:75fc82583a41 546
DiegoOstuni 0:75fc82583a41 547 if( gIsoDep.role == ISODEP_ROLE_PCD )
DiegoOstuni 0:75fc82583a41 548 {
DiegoOstuni 0:75fc82583a41 549 /* Digital 1.0 - 13.2.7.3 Poller must wait fwtDEACTIVATION */
DiegoOstuni 0:75fc82583a41 550 fwtTemp = ISODEP_FWT_DEACTIVATION;
DiegoOstuni 0:75fc82583a41 551 gIsoDep.state = ISODEP_ST_PCD_WAIT_DSL;
DiegoOstuni 0:75fc82583a41 552 }
DiegoOstuni 0:75fc82583a41 553 pcb = ISODEP_PCB_SDSL;
DiegoOstuni 0:75fc82583a41 554 break;
DiegoOstuni 0:75fc82583a41 555
DiegoOstuni 0:75fc82583a41 556 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 557 default:
DiegoOstuni 0:75fc82583a41 558 return ERR_INTERNAL;
DiegoOstuni 0:75fc82583a41 559 }
DiegoOstuni 0:75fc82583a41 560
DiegoOstuni 0:75fc82583a41 561 return isoDepTx( pcb, contolMsg, (contolMsg + RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN), infLen, fwtTemp, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 562 }
DiegoOstuni 0:75fc82583a41 563
DiegoOstuni 0:75fc82583a41 564 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 565 static ReturnCode isoDepReSendControlMsg(SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 566 {
DiegoOstuni 0:75fc82583a41 567 if( isoDep_PCBisRACK( gIsoDep.lastPCB ) )
DiegoOstuni 0:75fc82583a41 568 {
DiegoOstuni 0:75fc82583a41 569 return isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 570 }
DiegoOstuni 0:75fc82583a41 571
DiegoOstuni 0:75fc82583a41 572 if( isoDep_PCBisRNAK( gIsoDep.lastPCB ) )
DiegoOstuni 0:75fc82583a41 573 {
DiegoOstuni 0:75fc82583a41 574 return isoDepHandleControlMsg( ISODEP_R_NAK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 575 }
DiegoOstuni 0:75fc82583a41 576
DiegoOstuni 0:75fc82583a41 577 if( isoDep_PCBisSDeselect( gIsoDep.lastPCB ) )
DiegoOstuni 0:75fc82583a41 578 {
DiegoOstuni 0:75fc82583a41 579 return isoDepHandleControlMsg( ISODEP_S_DSL, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 580 }
DiegoOstuni 0:75fc82583a41 581
DiegoOstuni 0:75fc82583a41 582 if( isoDep_PCBisSWTX( gIsoDep.lastPCB ) )
DiegoOstuni 0:75fc82583a41 583 {
DiegoOstuni 0:75fc82583a41 584 return isoDepHandleControlMsg( ISODEP_S_WTX, gIsoDep.lastWTXM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 585 }
DiegoOstuni 0:75fc82583a41 586 return ERR_WRONG_STATE;
DiegoOstuni 0:75fc82583a41 587 }
DiegoOstuni 0:75fc82583a41 588
DiegoOstuni 0:75fc82583a41 589
DiegoOstuni 0:75fc82583a41 590 /*
DiegoOstuni 0:75fc82583a41 591 ******************************************************************************
DiegoOstuni 0:75fc82583a41 592 * GLOBAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 593 ******************************************************************************
DiegoOstuni 0:75fc82583a41 594 */
DiegoOstuni 0:75fc82583a41 595
DiegoOstuni 0:75fc82583a41 596
DiegoOstuni 0:75fc82583a41 597 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 598 void rfalIsoDepInitialize( void )
DiegoOstuni 0:75fc82583a41 599 {
DiegoOstuni 0:75fc82583a41 600 gIsoDep.state = ISODEP_ST_IDLE;
DiegoOstuni 0:75fc82583a41 601 gIsoDep.role = ISODEP_ROLE_PCD;
DiegoOstuni 0:75fc82583a41 602 gIsoDep.did = RFAL_ISODEP_NO_DID;
DiegoOstuni 0:75fc82583a41 603 gIsoDep.nad = RFAL_ISODEP_NO_NAD;
DiegoOstuni 0:75fc82583a41 604 gIsoDep.blockNumber = 0;
DiegoOstuni 0:75fc82583a41 605 gIsoDep.isTxChaining = false;
DiegoOstuni 0:75fc82583a41 606 gIsoDep.isRxChaining = false;
DiegoOstuni 0:75fc82583a41 607 gIsoDep.lastDID00 = false;
DiegoOstuni 0:75fc82583a41 608 gIsoDep.lastPCB = ISODEP_PCB_INVALID;
DiegoOstuni 0:75fc82583a41 609 gIsoDep.fsx = RFAL_ISODEP_FSX_16;
DiegoOstuni 0:75fc82583a41 610 gIsoDep.ourFsx = RFAL_ISODEP_FSX_16;
DiegoOstuni 0:75fc82583a41 611 gIsoDep.hdrLen = RFAL_ISODEP_PCB_LEN;
DiegoOstuni 0:75fc82583a41 612
DiegoOstuni 0:75fc82583a41 613 gIsoDep.rxLen = NULL;
DiegoOstuni 0:75fc82583a41 614 gIsoDep.rxBuf = NULL;
DiegoOstuni 0:75fc82583a41 615
DiegoOstuni 0:75fc82583a41 616 gIsoDep.isTxPending = false;
DiegoOstuni 0:75fc82583a41 617 gIsoDep.isWait4WTX = false;
DiegoOstuni 0:75fc82583a41 618
DiegoOstuni 0:75fc82583a41 619 gIsoDep.compMode = RFAL_COMPLIANCE_MODE_NFC;
DiegoOstuni 0:75fc82583a41 620 gIsoDep.maxRetriesR = RFAL_ISODEP_MAX_R_RETRYS;
DiegoOstuni 0:75fc82583a41 621 gIsoDep.maxRetriesS = RFAL_ISODEP_MAX_S_RETRYS;
DiegoOstuni 0:75fc82583a41 622 gIsoDep.maxRetriesI = RFAL_ISODEP_MAX_I_RETRYS;
DiegoOstuni 0:75fc82583a41 623 gIsoDep.maxRetriesRATS = RFAL_ISODEP_RATS_RETRIES;
DiegoOstuni 0:75fc82583a41 624
DiegoOstuni 0:75fc82583a41 625 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 626 }
DiegoOstuni 0:75fc82583a41 627
DiegoOstuni 0:75fc82583a41 628
DiegoOstuni 0:75fc82583a41 629 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 630 void rfalIsoDepInitializeWithParams( rfalComplianceMode compMode, uint8_t maxRetriesR, uint8_t maxRetriesS, uint8_t maxRetriesI, uint8_t maxRetriesRATS )
DiegoOstuni 0:75fc82583a41 631 {
DiegoOstuni 0:75fc82583a41 632 rfalIsoDepInitialize();
DiegoOstuni 0:75fc82583a41 633
DiegoOstuni 0:75fc82583a41 634 gIsoDep.compMode = compMode;
DiegoOstuni 0:75fc82583a41 635 gIsoDep.maxRetriesR = maxRetriesR;
DiegoOstuni 0:75fc82583a41 636 gIsoDep.maxRetriesS = maxRetriesS;
DiegoOstuni 0:75fc82583a41 637 gIsoDep.maxRetriesI = maxRetriesI;
DiegoOstuni 0:75fc82583a41 638 gIsoDep.maxRetriesRATS = maxRetriesRATS;
DiegoOstuni 0:75fc82583a41 639 }
DiegoOstuni 0:75fc82583a41 640
DiegoOstuni 0:75fc82583a41 641
DiegoOstuni 0:75fc82583a41 642 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 643 static ReturnCode isoDepDataExchangePCD( uint16_t *outActRxLen, bool *outIsChaining,SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 644 {
DiegoOstuni 0:75fc82583a41 645 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 646 uint8_t rxPCB;
DiegoOstuni 0:75fc82583a41 647
DiegoOstuni 0:75fc82583a41 648 /* Check out parameters */
DiegoOstuni 0:75fc82583a41 649 if( (outActRxLen == NULL) || (outIsChaining == NULL) )
DiegoOstuni 0:75fc82583a41 650 {
DiegoOstuni 0:75fc82583a41 651 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 652 }
DiegoOstuni 0:75fc82583a41 653
DiegoOstuni 0:75fc82583a41 654 *outIsChaining = false;
DiegoOstuni 0:75fc82583a41 655
DiegoOstuni 0:75fc82583a41 656 /* Calculate header required and check if the buffers InfPositions are suitable */
DiegoOstuni 0:75fc82583a41 657 gIsoDep.hdrLen = RFAL_ISODEP_PCB_LEN;
DiegoOstuni 0:75fc82583a41 658 if(gIsoDep.did != RFAL_ISODEP_NO_DID) gIsoDep.hdrLen += RFAL_ISODEP_DID_LEN;
DiegoOstuni 0:75fc82583a41 659 if(gIsoDep.nad != RFAL_ISODEP_NO_NAD) gIsoDep.hdrLen += RFAL_ISODEP_NAD_LEN;
DiegoOstuni 0:75fc82583a41 660
DiegoOstuni 0:75fc82583a41 661 /* check if there`s enough space before the infPos to append ISO-DEP headers on rx and tx */
DiegoOstuni 0:75fc82583a41 662 if( (gIsoDep.rxBufInfPos < gIsoDep.hdrLen) || (gIsoDep.txBufInfPos < gIsoDep.hdrLen) )
DiegoOstuni 0:75fc82583a41 663 {
DiegoOstuni 0:75fc82583a41 664 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 665 }
DiegoOstuni 0:75fc82583a41 666
DiegoOstuni 0:75fc82583a41 667 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 668 /* Wait until SFGT has been fulfilled (as a PCD) */
DiegoOstuni 0:75fc82583a41 669 if( (gIsoDep.SFGTTimer != 0) && !isoDepTimerisExpired( gIsoDep.SFGTTimer ) )
DiegoOstuni 0:75fc82583a41 670 {
DiegoOstuni 0:75fc82583a41 671 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 672 }
DiegoOstuni 0:75fc82583a41 673 /* Once done, clear SFGT timer */
DiegoOstuni 0:75fc82583a41 674 gIsoDep.SFGTTimer = 0;
DiegoOstuni 0:75fc82583a41 675
DiegoOstuni 0:75fc82583a41 676
DiegoOstuni 0:75fc82583a41 677 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 678 switch( gIsoDep.state )
DiegoOstuni 0:75fc82583a41 679 {
DiegoOstuni 0:75fc82583a41 680 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 681 case ISODEP_ST_IDLE:
DiegoOstuni 0:75fc82583a41 682 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 683
DiegoOstuni 0:75fc82583a41 684 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 685 case ISODEP_ST_PCD_TX:
DiegoOstuni 0:75fc82583a41 686 ret = isoDepTx( isoDep_PCBIBlock( gIsoDep.blockNumber ), gIsoDep.txBuf, (gIsoDep.txBuf + gIsoDep.txBufInfPos), gIsoDep.txBufLen, (gIsoDep.fwt + gIsoDep.dFwt), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 687 switch( ret )
DiegoOstuni 0:75fc82583a41 688 {
DiegoOstuni 0:75fc82583a41 689 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 690 gIsoDep.state = ISODEP_ST_PCD_RX;
DiegoOstuni 0:75fc82583a41 691 break;
DiegoOstuni 0:75fc82583a41 692
DiegoOstuni 0:75fc82583a41 693 default:
DiegoOstuni 0:75fc82583a41 694 return ret;
DiegoOstuni 0:75fc82583a41 695 }
DiegoOstuni 0:75fc82583a41 696 /* fall through */
DiegoOstuni 0:75fc82583a41 697
DiegoOstuni 0:75fc82583a41 698 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 699 case ISODEP_ST_PCD_WAIT_DSL:
DiegoOstuni 0:75fc82583a41 700 case ISODEP_ST_PCD_RX:
DiegoOstuni 0:75fc82583a41 701
DiegoOstuni 0:75fc82583a41 702 ret = rfalGetTransceiveStatus();
DiegoOstuni 0:75fc82583a41 703 switch( ret )
DiegoOstuni 0:75fc82583a41 704 {
DiegoOstuni 0:75fc82583a41 705 /* Data rcvd with error or timeout -> Send R-NAK */
DiegoOstuni 0:75fc82583a41 706 case ERR_TIMEOUT:
DiegoOstuni 0:75fc82583a41 707 case ERR_CRC:
DiegoOstuni 0:75fc82583a41 708 case ERR_PAR:
DiegoOstuni 0:75fc82583a41 709 case ERR_FRAMING: /* added to handle test cases scenario TC_POL_NFCB_T4AT_BI_82_x_y & TC_POL_NFCB_T4BT_BI_82_x_y */
DiegoOstuni 0:75fc82583a41 710 case ERR_INCOMPLETE_BYTE: /* added to handle test cases scenario TC_POL_NFCB_T4AT_BI_82_x_y & TC_POL_NFCB_T4BT_BI_82_x_y */
DiegoOstuni 0:75fc82583a41 711
DiegoOstuni 0:75fc82583a41 712 if( gIsoDep.isRxChaining )
DiegoOstuni 0:75fc82583a41 713 { /* Rule 5 - In PICC chaining when a invalid/timeout occurs -> R-ACK */
DiegoOstuni 0:75fc82583a41 714 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM ,mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 715 }
DiegoOstuni 0:75fc82583a41 716 else if( gIsoDep.state == ISODEP_ST_PCD_WAIT_DSL )
DiegoOstuni 0:75fc82583a41 717 { /* Rule 8 - If s-Deselect response fails MAY retransmit */
DiegoOstuni 0:75fc82583a41 718 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_S_DSL, RFAL_ISODEP_NO_PARAM,mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 719 }
DiegoOstuni 0:75fc82583a41 720 else
DiegoOstuni 0:75fc82583a41 721 { /* Rule 4 - When a invalid block or timeout occurs -> R-NACK */
DiegoOstuni 0:75fc82583a41 722 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_NAK, RFAL_ISODEP_NO_PARAM,mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 723 }
DiegoOstuni 0:75fc82583a41 724 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 725
DiegoOstuni 0:75fc82583a41 726 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 727 break;
DiegoOstuni 0:75fc82583a41 728
DiegoOstuni 0:75fc82583a41 729 case ERR_BUSY:
DiegoOstuni 0:75fc82583a41 730 return ERR_BUSY; /* Debug purposes */
DiegoOstuni 0:75fc82583a41 731
DiegoOstuni 0:75fc82583a41 732 default:
DiegoOstuni 0:75fc82583a41 733 return ret;
DiegoOstuni 0:75fc82583a41 734 }
DiegoOstuni 0:75fc82583a41 735
DiegoOstuni 0:75fc82583a41 736 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 737 /* No error, process incoming msg */
DiegoOstuni 0:75fc82583a41 738 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 739
DiegoOstuni 0:75fc82583a41 740 (*outActRxLen) = rfalConvBitsToBytes( *outActRxLen );
DiegoOstuni 0:75fc82583a41 741
DiegoOstuni 0:75fc82583a41 742
DiegoOstuni 0:75fc82583a41 743 /* Check rcvd msg length, cannot be less then the expected header */
DiegoOstuni 0:75fc82583a41 744 if( ((*outActRxLen) < gIsoDep.hdrLen) || ((*outActRxLen) >= gIsoDep.ourFsx) )
DiegoOstuni 0:75fc82583a41 745 {
DiegoOstuni 0:75fc82583a41 746 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 747 }
DiegoOstuni 0:75fc82583a41 748
DiegoOstuni 0:75fc82583a41 749 /* Grab rcvd PCB */
DiegoOstuni 0:75fc82583a41 750 rxPCB = gIsoDep.rxBuf[ ISODEP_PCB_POS ];
DiegoOstuni 0:75fc82583a41 751
DiegoOstuni 0:75fc82583a41 752
DiegoOstuni 0:75fc82583a41 753 /* EMVCo doesn't allow usage of for CID or NAD EMVCo 2.6 TAble 10.2 */
DiegoOstuni 0:75fc82583a41 754 if( (gIsoDep.compMode == RFAL_COMPLIANCE_MODE_EMV) && ( isoDep_PCBhasDID(rxPCB) || isoDep_PCBhasNAD(rxPCB)) )
DiegoOstuni 0:75fc82583a41 755 {
DiegoOstuni 0:75fc82583a41 756 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 757 }
DiegoOstuni 0:75fc82583a41 758
DiegoOstuni 0:75fc82583a41 759 /* If we are expecting DID, check if PCB signals its presence and if device ID match*/
DiegoOstuni 0:75fc82583a41 760 if( (gIsoDep.did != RFAL_ISODEP_NO_DID) && ( !isoDep_PCBhasDID(rxPCB) || (gIsoDep.did != gIsoDep.rxBuf[ ISODEP_DID_POS ])) )
DiegoOstuni 0:75fc82583a41 761 {
DiegoOstuni 0:75fc82583a41 762 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 763 }
DiegoOstuni 0:75fc82583a41 764
DiegoOstuni 0:75fc82583a41 765
DiegoOstuni 0:75fc82583a41 766 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 767 /* Process S-Block */
DiegoOstuni 0:75fc82583a41 768 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 769 if( isoDep_PCBisSBlock(rxPCB) )
DiegoOstuni 0:75fc82583a41 770 {
DiegoOstuni 0:75fc82583a41 771 /* Check if is a Wait Time eXtension */
DiegoOstuni 0:75fc82583a41 772 if( isoDep_PCBisSWTX(rxPCB) )
DiegoOstuni 0:75fc82583a41 773 {
DiegoOstuni 0:75fc82583a41 774 /* Rule 3 - respond to S-block: get 1st INF byte S(STW): Power + WTXM */
DiegoOstuni 0:75fc82583a41 775 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_S_WTX, isoDep_GetWTXM(gIsoDep.rxBuf[gIsoDep.hdrLen]), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 776 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 777 }
DiegoOstuni 0:75fc82583a41 778
DiegoOstuni 0:75fc82583a41 779 /* Check if is a deselect response */
DiegoOstuni 0:75fc82583a41 780 if( isoDep_PCBisSDeselect(rxPCB) )
DiegoOstuni 0:75fc82583a41 781 {
DiegoOstuni 0:75fc82583a41 782 if( gIsoDep.state == ISODEP_ST_PCD_WAIT_DSL )
DiegoOstuni 0:75fc82583a41 783 {
DiegoOstuni 0:75fc82583a41 784 rfalIsoDepInitialize(); /* Session finished reInit vars */
DiegoOstuni 0:75fc82583a41 785 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 786 }
DiegoOstuni 0:75fc82583a41 787
DiegoOstuni 0:75fc82583a41 788 /* Deselect response not expected */
DiegoOstuni 0:75fc82583a41 789 /* fall through to PROTO error */
DiegoOstuni 0:75fc82583a41 790 }
DiegoOstuni 0:75fc82583a41 791 /* Unexpected S-Block */
DiegoOstuni 0:75fc82583a41 792 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 793 }
DiegoOstuni 0:75fc82583a41 794
DiegoOstuni 0:75fc82583a41 795 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 796 /* Process R-Block */
DiegoOstuni 0:75fc82583a41 797 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 798 else if( isoDep_PCBisRBlock(rxPCB) )
DiegoOstuni 0:75fc82583a41 799 {
DiegoOstuni 0:75fc82583a41 800 if( isoDep_PCBisRACK(rxPCB) ) /* Check if is a R-ACK */
DiegoOstuni 0:75fc82583a41 801 {
DiegoOstuni 0:75fc82583a41 802 if( isoDep_GetBN(rxPCB) == gIsoDep.blockNumber ) /* Expected block number */
DiegoOstuni 0:75fc82583a41 803 {
DiegoOstuni 0:75fc82583a41 804 /* Rule B - ACK with expected bn -> Increment block number */
DiegoOstuni 0:75fc82583a41 805 gIsoDep.blockNumber = isoDep_PCBNextBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 806
DiegoOstuni 0:75fc82583a41 807 /* R-ACK only allowed when PCD chaining */
DiegoOstuni 0:75fc82583a41 808 if( !gIsoDep.isTxChaining )
DiegoOstuni 0:75fc82583a41 809 {
DiegoOstuni 0:75fc82583a41 810 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 811 }
DiegoOstuni 0:75fc82583a41 812
DiegoOstuni 0:75fc82583a41 813 /* Rule 7 - Chaining transaction done, continue chaining */
DiegoOstuni 0:75fc82583a41 814 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 815 return ERR_NONE; /* This block has been transmitted */
DiegoOstuni 0:75fc82583a41 816 }
DiegoOstuni 0:75fc82583a41 817 else
DiegoOstuni 0:75fc82583a41 818 {
DiegoOstuni 0:75fc82583a41 819 /* Rule 6 - R-ACK with wrong block number retransmit */
DiegoOstuni 0:75fc82583a41 820 if( gIsoDep.cntIRetrys++ < gIsoDep.maxRetriesI )
DiegoOstuni 0:75fc82583a41 821 {
DiegoOstuni 0:75fc82583a41 822 gIsoDep.cntRRetrys = 0; /* Clear R counter only */
DiegoOstuni 0:75fc82583a41 823 gIsoDep.state = ISODEP_ST_PCD_TX;
DiegoOstuni 0:75fc82583a41 824 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 825 }
DiegoOstuni 0:75fc82583a41 826 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 827 }
DiegoOstuni 0:75fc82583a41 828 }
DiegoOstuni 0:75fc82583a41 829 else /* Unexcpected R-Block */
DiegoOstuni 0:75fc82583a41 830 {
DiegoOstuni 0:75fc82583a41 831 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 832 }
DiegoOstuni 0:75fc82583a41 833 }
DiegoOstuni 0:75fc82583a41 834
DiegoOstuni 0:75fc82583a41 835 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 836 /* Process I-Block */
DiegoOstuni 0:75fc82583a41 837 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 838 else if( isoDep_PCBisIBlock(rxPCB) )
DiegoOstuni 0:75fc82583a41 839 {
DiegoOstuni 0:75fc82583a41 840 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 841 /* is PICC performing chaining */
DiegoOstuni 0:75fc82583a41 842 if( isoDep_PCBisChaining(rxPCB) )
DiegoOstuni 0:75fc82583a41 843 {
DiegoOstuni 0:75fc82583a41 844 gIsoDep.isRxChaining = true;
DiegoOstuni 0:75fc82583a41 845 *outIsChaining = true;
DiegoOstuni 0:75fc82583a41 846
DiegoOstuni 0:75fc82583a41 847 if( isoDep_GetBN(rxPCB) == gIsoDep.blockNumber )
DiegoOstuni 0:75fc82583a41 848 {
DiegoOstuni 0:75fc82583a41 849 /* Rule B - ACK with correct block number -> Increase Block number */
DiegoOstuni 0:75fc82583a41 850 isoDep_ToggleBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 851
DiegoOstuni 0:75fc82583a41 852 isoDepClearCounters(); /* Clear counters in case R counter is already at max */
DiegoOstuni 0:75fc82583a41 853
DiegoOstuni 0:75fc82583a41 854 /* Rule 2 - Send ACK */
DiegoOstuni 0:75fc82583a41 855 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 856
DiegoOstuni 0:75fc82583a41 857 /* Received I-Block with chaining, send current data to DH */
DiegoOstuni 0:75fc82583a41 858
DiegoOstuni 0:75fc82583a41 859 /* remove ISO DEP header, check is necessary to move the INF data on the buffer */
DiegoOstuni 0:75fc82583a41 860 *outActRxLen -= gIsoDep.hdrLen;
DiegoOstuni 0:75fc82583a41 861 if( gIsoDep.hdrLen != gIsoDep.rxBufInfPos )
DiegoOstuni 0:75fc82583a41 862 {
DiegoOstuni 0:75fc82583a41 863 ST_MEMMOVE( (gIsoDep.rxBuf + gIsoDep.rxBufInfPos), (gIsoDep.rxBuf + gIsoDep.hdrLen), *outActRxLen );
DiegoOstuni 0:75fc82583a41 864 }
DiegoOstuni 0:75fc82583a41 865
DiegoOstuni 0:75fc82583a41 866 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 867 return ERR_AGAIN; /* Send Again signalling to run again, but some chaining data has arrived */
DiegoOstuni 0:75fc82583a41 868 }
DiegoOstuni 0:75fc82583a41 869 else
DiegoOstuni 0:75fc82583a41 870 {
DiegoOstuni 0:75fc82583a41 871 /* Rule 5 - PICC chaining invalid I-Block -> R-ACK */
DiegoOstuni 0:75fc82583a41 872 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 873 }
DiegoOstuni 0:75fc82583a41 874 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 875 }
DiegoOstuni 0:75fc82583a41 876
DiegoOstuni 0:75fc82583a41 877 gIsoDep.isRxChaining = false; /* clear PICC chaining flag */
DiegoOstuni 0:75fc82583a41 878
DiegoOstuni 0:75fc82583a41 879 if( isoDep_GetBN(rxPCB) == gIsoDep.blockNumber )
DiegoOstuni 0:75fc82583a41 880 {
DiegoOstuni 0:75fc82583a41 881 /* Rule B - I-Block with correct block number -> Increase Block number */
DiegoOstuni 0:75fc82583a41 882 isoDep_ToggleBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 883
DiegoOstuni 0:75fc82583a41 884 /* I-Block transaction done successfully */
DiegoOstuni 0:75fc82583a41 885
DiegoOstuni 0:75fc82583a41 886 /* remove ISO DEP header, check is necessary to move the INF data on the buffer */
DiegoOstuni 0:75fc82583a41 887 *outActRxLen -= gIsoDep.hdrLen;
DiegoOstuni 0:75fc82583a41 888 if( gIsoDep.hdrLen != gIsoDep.rxBufInfPos )
DiegoOstuni 0:75fc82583a41 889 {
DiegoOstuni 0:75fc82583a41 890 ST_MEMMOVE( (gIsoDep.rxBuf + gIsoDep.rxBufInfPos), (gIsoDep.rxBuf + gIsoDep.hdrLen), *outActRxLen );
DiegoOstuni 0:75fc82583a41 891 }
DiegoOstuni 0:75fc82583a41 892
DiegoOstuni 0:75fc82583a41 893 gIsoDep.state = ISODEP_ST_IDLE;
DiegoOstuni 0:75fc82583a41 894 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 895 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 896 }
DiegoOstuni 0:75fc82583a41 897 else
DiegoOstuni 0:75fc82583a41 898 {
DiegoOstuni 0:75fc82583a41 899 if( (gIsoDep.compMode != RFAL_COMPLIANCE_MODE_ISO) )
DiegoOstuni 0:75fc82583a41 900 {
DiegoOstuni 0:75fc82583a41 901 /* Invalid Block (not chaining) -> Raise error Digital 1.1 15.2.6.4 EMVCo 2.6 10.3.5.4 */
DiegoOstuni 0:75fc82583a41 902 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 903 }
DiegoOstuni 0:75fc82583a41 904
DiegoOstuni 0:75fc82583a41 905 /* Rule 4 - Invalid Block -> R-NAK */
DiegoOstuni 0:75fc82583a41 906 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_NAK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 907 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 908 }
DiegoOstuni 0:75fc82583a41 909 }
DiegoOstuni 0:75fc82583a41 910 else /* not S/R/I - Block */
DiegoOstuni 0:75fc82583a41 911 {
DiegoOstuni 0:75fc82583a41 912 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 913 }
DiegoOstuni 0:75fc82583a41 914 /*break;*/
DiegoOstuni 0:75fc82583a41 915
DiegoOstuni 0:75fc82583a41 916 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 917 default:
DiegoOstuni 0:75fc82583a41 918 break;
DiegoOstuni 0:75fc82583a41 919 }
DiegoOstuni 0:75fc82583a41 920
DiegoOstuni 0:75fc82583a41 921 return ERR_INTERNAL;
DiegoOstuni 0:75fc82583a41 922 }
DiegoOstuni 0:75fc82583a41 923
DiegoOstuni 0:75fc82583a41 924 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 925 ReturnCode rfalIsoDepDeselect( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 926 {
DiegoOstuni 0:75fc82583a41 927 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 928 uint32_t cntRerun;
DiegoOstuni 0:75fc82583a41 929 bool dummyB;
DiegoOstuni 0:75fc82583a41 930 uint16_t tmpRcvdLen;
DiegoOstuni 0:75fc82583a41 931 uint8_t tmpRxBuf[ISODEP_CONTROLMSG_BUF_LEN];
DiegoOstuni 0:75fc82583a41 932
DiegoOstuni 0:75fc82583a41 933 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 934 /* Check if rx parameters have been set before, otherwise use local variables *
DiegoOstuni 0:75fc82583a41 935 * To cope with a Deselect after RATS\ATTRIB without any I-Block exchanged */
DiegoOstuni 0:75fc82583a41 936 if( (gIsoDep.rxLen == NULL) || (gIsoDep.rxBuf == NULL) )
DiegoOstuni 0:75fc82583a41 937 {
DiegoOstuni 0:75fc82583a41 938 gIsoDep.rxLen = &tmpRcvdLen;
DiegoOstuni 0:75fc82583a41 939 gIsoDep.rxBuf = tmpRxBuf;
DiegoOstuni 0:75fc82583a41 940 gIsoDep.rxBufLen = ISODEP_CONTROLMSG_BUF_LEN;
DiegoOstuni 0:75fc82583a41 941 gIsoDep.rxBufInfPos = (RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN);
DiegoOstuni 0:75fc82583a41 942 gIsoDep.txBufInfPos = (RFAL_ISODEP_PCB_LEN + RFAL_ISODEP_DID_LEN);
DiegoOstuni 0:75fc82583a41 943 }
DiegoOstuni 0:75fc82583a41 944
DiegoOstuni 0:75fc82583a41 945
DiegoOstuni 0:75fc82583a41 946 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 947 /* The Deselect process is being done blocking, Digital 1.0 - 13.2.7.1 MUST wait response and retry*/
DiegoOstuni 0:75fc82583a41 948 /* Set the maximum reruns while we`ll wait for a response */
DiegoOstuni 0:75fc82583a41 949 cntRerun = ISODEP_MAX_RERUNS;
DiegoOstuni 0:75fc82583a41 950
DiegoOstuni 0:75fc82583a41 951 /* Send DSL request and run protocol until get a response, error or "timeout" */
DiegoOstuni 0:75fc82583a41 952 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_S_DSL, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 953 do{
DiegoOstuni 0:75fc82583a41 954 ret = isoDepDataExchangePCD( gIsoDep.rxLen, &dummyB, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 955 rfalWorker( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 956 }
DiegoOstuni 0:75fc82583a41 957 while( (ERR_NO_MASK(ret) == ERR_BUSY) && cntRerun--);
DiegoOstuni 0:75fc82583a41 958
DiegoOstuni 0:75fc82583a41 959 rfalIsoDepInitialize();
DiegoOstuni 0:75fc82583a41 960 return ((cntRerun == 0) ? ERR_TIMEOUT : ret);
DiegoOstuni 0:75fc82583a41 961 }
DiegoOstuni 0:75fc82583a41 962
DiegoOstuni 0:75fc82583a41 963
DiegoOstuni 0:75fc82583a41 964 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 965 uint32_t rfalIsoDepFWI2FWT( uint8_t fwi )
DiegoOstuni 0:75fc82583a41 966 {
DiegoOstuni 0:75fc82583a41 967 uint32_t result;
DiegoOstuni 0:75fc82583a41 968
DiegoOstuni 0:75fc82583a41 969 /* RFU values -> take the default value
DiegoOstuni 0:75fc82583a41 970 * Digital 1.0 11.6.2.17 FWI[1,14]
DiegoOstuni 0:75fc82583a41 971 * Digital 1.1 7.6.2.22 FWI[0,14]
DiegoOstuni 0:75fc82583a41 972 * EMVCo 2.6 Table A.5 FWI[0,14] */
DiegoOstuni 0:75fc82583a41 973 if( fwi > ISODEP_FWI_MAX )
DiegoOstuni 0:75fc82583a41 974 {
DiegoOstuni 0:75fc82583a41 975 fwi = RFAL_ISODEP_FWI_DEFAULT;
DiegoOstuni 0:75fc82583a41 976 }
DiegoOstuni 0:75fc82583a41 977
DiegoOstuni 0:75fc82583a41 978 /* FWT = (256 × 16/fC) × 2^FWI => 2^(FWI+12) Digital 1.1 13.8.1 & 7.9.1 */
DiegoOstuni 0:75fc82583a41 979
DiegoOstuni 0:75fc82583a41 980 result = (1 << (fwi + 12));
DiegoOstuni 0:75fc82583a41 981 result = MIN( RFAL_ISODEP_MAX_FWT, result); /* Maximum Frame Waiting Time must be fulfilled */
DiegoOstuni 0:75fc82583a41 982
DiegoOstuni 0:75fc82583a41 983 return result;
DiegoOstuni 0:75fc82583a41 984 }
DiegoOstuni 0:75fc82583a41 985
DiegoOstuni 0:75fc82583a41 986
DiegoOstuni 0:75fc82583a41 987 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 988 uint16_t rfalIsoDepFSxI2FSx( uint8_t FSxI )
DiegoOstuni 0:75fc82583a41 989 {
DiegoOstuni 0:75fc82583a41 990 switch( FSxI )
DiegoOstuni 0:75fc82583a41 991 {
DiegoOstuni 0:75fc82583a41 992 case RFAL_ISODEP_FSXI_16: return RFAL_ISODEP_FSX_16;
DiegoOstuni 0:75fc82583a41 993 case RFAL_ISODEP_FSXI_24: return RFAL_ISODEP_FSX_24;
DiegoOstuni 0:75fc82583a41 994 case RFAL_ISODEP_FSXI_32: return RFAL_ISODEP_FSX_32;
DiegoOstuni 0:75fc82583a41 995 case RFAL_ISODEP_FSXI_40: return RFAL_ISODEP_FSX_40;
DiegoOstuni 0:75fc82583a41 996 case RFAL_ISODEP_FSXI_48: return RFAL_ISODEP_FSX_48;
DiegoOstuni 0:75fc82583a41 997 case RFAL_ISODEP_FSXI_64: return RFAL_ISODEP_FSX_64;
DiegoOstuni 0:75fc82583a41 998 case RFAL_ISODEP_FSXI_96: return RFAL_ISODEP_FSX_96;
DiegoOstuni 0:75fc82583a41 999 case RFAL_ISODEP_FSXI_128: return RFAL_ISODEP_FSX_128;
DiegoOstuni 0:75fc82583a41 1000 }
DiegoOstuni 0:75fc82583a41 1001 return RFAL_ISODEP_FSX_256;
DiegoOstuni 0:75fc82583a41 1002 }
DiegoOstuni 0:75fc82583a41 1003
DiegoOstuni 0:75fc82583a41 1004
DiegoOstuni 0:75fc82583a41 1005 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1006 static uint32_t rfalIsoDepSFGI2SFGT( uint8_t sfgi )
DiegoOstuni 0:75fc82583a41 1007 {
DiegoOstuni 0:75fc82583a41 1008 uint32_t sfgt;
DiegoOstuni 0:75fc82583a41 1009
DiegoOstuni 0:75fc82583a41 1010 if (sfgi > ISODEP_SFGI_MAX)
DiegoOstuni 0:75fc82583a41 1011 {
DiegoOstuni 0:75fc82583a41 1012 sfgi = ISODEP_SFGI_MIN;
DiegoOstuni 0:75fc82583a41 1013 }
DiegoOstuni 0:75fc82583a41 1014
DiegoOstuni 0:75fc82583a41 1015 if (sfgi != ISODEP_SFGI_MIN)
DiegoOstuni 0:75fc82583a41 1016 {
DiegoOstuni 0:75fc82583a41 1017 /* If sfgi != 0 wait SFGT + dSFGT Digital 1.1 13.8.2.1 */
DiegoOstuni 0:75fc82583a41 1018 sfgt = (isoDepCalcSGFT(sfgi) + isoDepCalcdSGFT(sfgi));
DiegoOstuni 0:75fc82583a41 1019 }
DiegoOstuni 0:75fc82583a41 1020 /* Otherwise use FDTPoll min Digital 1.1 13.8.2.3*/
DiegoOstuni 0:75fc82583a41 1021 else
DiegoOstuni 0:75fc82583a41 1022 {
DiegoOstuni 0:75fc82583a41 1023 sfgt = RFAL_FDT_POLL_NFCA_POLLER;
DiegoOstuni 0:75fc82583a41 1024 }
DiegoOstuni 0:75fc82583a41 1025
DiegoOstuni 0:75fc82583a41 1026 /* Convert carrier cycles to milli seconds */
DiegoOstuni 0:75fc82583a41 1027 return (rfalConv1fcToMs(sfgt) + 1);
DiegoOstuni 0:75fc82583a41 1028 }
DiegoOstuni 0:75fc82583a41 1029
DiegoOstuni 0:75fc82583a41 1030
DiegoOstuni 0:75fc82583a41 1031 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1032 bool rfalIsoDepIsRats( uint8_t *buf, uint8_t bufLen )
DiegoOstuni 0:75fc82583a41 1033 {
DiegoOstuni 0:75fc82583a41 1034 if(buf != NULL)
DiegoOstuni 0:75fc82583a41 1035 {
DiegoOstuni 0:75fc82583a41 1036 if ((RFAL_ISODEP_CMD_RATS == (uint8_t)*buf) && (sizeof(rfalIsoDepRats) == bufLen))
DiegoOstuni 0:75fc82583a41 1037 {
DiegoOstuni 0:75fc82583a41 1038 return true;
DiegoOstuni 0:75fc82583a41 1039 }
DiegoOstuni 0:75fc82583a41 1040 }
DiegoOstuni 0:75fc82583a41 1041 return false;
DiegoOstuni 0:75fc82583a41 1042 }
DiegoOstuni 0:75fc82583a41 1043
DiegoOstuni 0:75fc82583a41 1044
DiegoOstuni 0:75fc82583a41 1045 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1046 bool rfalIsoDepIsAttrib( uint8_t *buf, uint8_t bufLen )
DiegoOstuni 0:75fc82583a41 1047 {
DiegoOstuni 0:75fc82583a41 1048 if(buf != NULL)
DiegoOstuni 0:75fc82583a41 1049 {
DiegoOstuni 0:75fc82583a41 1050 if ( (RFAL_ISODEP_CMD_ATTRIB == (uint8_t)*buf) &&
DiegoOstuni 0:75fc82583a41 1051 (RFAL_ISODEP_ATTRIB_REQ_MIN_LEN <= bufLen) &&
DiegoOstuni 0:75fc82583a41 1052 ((RFAL_ISODEP_ATTRIB_REQ_MIN_LEN + RFAL_ISODEP_ATTRIB_HLINFO_LEN) >= bufLen) )
DiegoOstuni 0:75fc82583a41 1053 {
DiegoOstuni 0:75fc82583a41 1054 return true;
DiegoOstuni 0:75fc82583a41 1055 }
DiegoOstuni 0:75fc82583a41 1056 }
DiegoOstuni 0:75fc82583a41 1057 return false;
DiegoOstuni 0:75fc82583a41 1058 }
DiegoOstuni 0:75fc82583a41 1059
DiegoOstuni 0:75fc82583a41 1060 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1061 ReturnCode rfalIsoDepListenStartActivation( rfalIsoDepAtsParam *atsParam, rfalIsoDepAttribResParam *attribResParam, uint8_t *buf, uint16_t bufLen, rfalIsoDepListenActvParam actParam, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1062 {
DiegoOstuni 0:75fc82583a41 1063
DiegoOstuni 0:75fc82583a41 1064 uint8_t *txBuf;
DiegoOstuni 0:75fc82583a41 1065 uint8_t bufIt;
DiegoOstuni 0:75fc82583a41 1066
DiegoOstuni 0:75fc82583a41 1067 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1068 bufIt = 0;
DiegoOstuni 0:75fc82583a41 1069 txBuf = (uint8_t*)actParam.rxBuf; /* Use the rxBuf as TxBuf as well, the struct enforces a size enough MAX( NFCA_ATS_MAX_LEN, NFCB_ATTRIB_RES_MAX_LEN ) */
DiegoOstuni 0:75fc82583a41 1070 gIsoDep.txBR = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1071 gIsoDep.rxBR = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1072
DiegoOstuni 0:75fc82583a41 1073 /* Check for a valid buffer pointer */
DiegoOstuni 0:75fc82583a41 1074 if( buf == NULL )
DiegoOstuni 0:75fc82583a41 1075 {
DiegoOstuni 0:75fc82583a41 1076 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1077 }
DiegoOstuni 0:75fc82583a41 1078
DiegoOstuni 0:75fc82583a41 1079 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1080 if( *buf == RFAL_ISODEP_CMD_RATS )
DiegoOstuni 0:75fc82583a41 1081 {
DiegoOstuni 0:75fc82583a41 1082 /* Check ATS parameters */
DiegoOstuni 0:75fc82583a41 1083 if( atsParam == NULL )
DiegoOstuni 0:75fc82583a41 1084 {
DiegoOstuni 0:75fc82583a41 1085 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1086 }
DiegoOstuni 0:75fc82583a41 1087
DiegoOstuni 0:75fc82583a41 1088 /* If requested copy RATS to device info */
DiegoOstuni 0:75fc82583a41 1089 if( actParam.isoDepDev != NULL )
DiegoOstuni 0:75fc82583a41 1090 {
DiegoOstuni 0:75fc82583a41 1091 ST_MEMCPY( (uint8_t*)&actParam.isoDepDev->activation.A.Poller.RATS.CMD, buf, sizeof(rfalIsoDepRats) );
DiegoOstuni 0:75fc82583a41 1092 }
DiegoOstuni 0:75fc82583a41 1093
DiegoOstuni 0:75fc82583a41 1094
DiegoOstuni 0:75fc82583a41 1095 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1096 /* Process RATS */
DiegoOstuni 0:75fc82583a41 1097 buf++;
DiegoOstuni 0:75fc82583a41 1098 gIsoDep.fsx = rfalIsoDepFSxI2FSx( (((*buf) & RFAL_ISODEP_RATS_PARAM_FSDI_MASK) >> RFAL_ISODEP_RATS_PARAM_FSDI_SHIFT) );
DiegoOstuni 0:75fc82583a41 1099 gIsoDep.did = (*buf & RFAL_ISODEP_DID_MASK);
DiegoOstuni 0:75fc82583a41 1100
DiegoOstuni 0:75fc82583a41 1101
DiegoOstuni 0:75fc82583a41 1102 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1103 /* Digital 1.1 13.6.1.8 - DID as to between 0 and 14 */
DiegoOstuni 0:75fc82583a41 1104 if( gIsoDep.did > RFAL_ISODEP_DID_MAX )
DiegoOstuni 0:75fc82583a41 1105 {
DiegoOstuni 0:75fc82583a41 1106 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 1107 }
DiegoOstuni 0:75fc82583a41 1108
DiegoOstuni 0:75fc82583a41 1109 /* Check if we are configured to support DID */
DiegoOstuni 0:75fc82583a41 1110 if( (gIsoDep.did != RFAL_ISODEP_DID_00) && (!atsParam->didSupport) )
DiegoOstuni 0:75fc82583a41 1111 {
DiegoOstuni 0:75fc82583a41 1112 return ERR_NOTSUPP;
DiegoOstuni 0:75fc82583a41 1113 }
DiegoOstuni 0:75fc82583a41 1114
DiegoOstuni 0:75fc82583a41 1115
DiegoOstuni 0:75fc82583a41 1116 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1117 /* Check RFAL supported bit rates */
DiegoOstuni 0:75fc82583a41 1118 if( (!(RFAL_SUPPORT_BR_CE_A_212) && ((atsParam->ta & RFAL_ISODEP_ATS_TA_DPL_212) || (atsParam->ta & RFAL_ISODEP_ATS_TA_DLP_212))) ||
DiegoOstuni 0:75fc82583a41 1119 (!(RFAL_SUPPORT_BR_CE_A_424) && ((atsParam->ta & RFAL_ISODEP_ATS_TA_DPL_424) || (atsParam->ta & RFAL_ISODEP_ATS_TA_DLP_424))) ||
DiegoOstuni 0:75fc82583a41 1120 (!(RFAL_SUPPORT_BR_CE_A_848) && ((atsParam->ta & RFAL_ISODEP_ATS_TA_DPL_848) || (atsParam->ta & RFAL_ISODEP_ATS_TA_DLP_848))) )
DiegoOstuni 0:75fc82583a41 1121 {
DiegoOstuni 0:75fc82583a41 1122 return ERR_NOTSUPP;
DiegoOstuni 0:75fc82583a41 1123 }
DiegoOstuni 0:75fc82583a41 1124
DiegoOstuni 0:75fc82583a41 1125 /* Enforce proper FWI configuration */
DiegoOstuni 0:75fc82583a41 1126 if( atsParam->fwi > ISODEP_FWI_LIS_MAX)
DiegoOstuni 0:75fc82583a41 1127 {
DiegoOstuni 0:75fc82583a41 1128 atsParam->fwi = ISODEP_FWI_LIS_MAX;
DiegoOstuni 0:75fc82583a41 1129 }
DiegoOstuni 0:75fc82583a41 1130
DiegoOstuni 0:75fc82583a41 1131 gIsoDep.atsTA = atsParam->ta;
DiegoOstuni 0:75fc82583a41 1132 gIsoDep.fwt = rfalIsoDepFWI2FWT(atsParam->fwi);
DiegoOstuni 0:75fc82583a41 1133 gIsoDep.ourFsx = rfalIsoDepFSxI2FSx(atsParam->fsci);
DiegoOstuni 0:75fc82583a41 1134
DiegoOstuni 0:75fc82583a41 1135
DiegoOstuni 0:75fc82583a41 1136 /* Ensure proper/maximum Historical Bytes length */
DiegoOstuni 0:75fc82583a41 1137 atsParam->hbLen = MIN( RFAL_ISODEP_ATS_HB_MAX_LEN, atsParam->hbLen );
DiegoOstuni 0:75fc82583a41 1138
DiegoOstuni 0:75fc82583a41 1139 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1140 /* Compute ATS */
DiegoOstuni 0:75fc82583a41 1141
DiegoOstuni 0:75fc82583a41 1142 txBuf[ bufIt++ ] = (RFAL_ISODEP_ATS_HIST_OFFSET + atsParam->hbLen); /* TL */
DiegoOstuni 0:75fc82583a41 1143 txBuf[ bufIt++ ] = ( (RFAL_ISODEP_ATS_T0_TA_PRESENCE_MASK | RFAL_ISODEP_ATS_T0_TB_PRESENCE_MASK |
DiegoOstuni 0:75fc82583a41 1144 RFAL_ISODEP_ATS_T0_TC_PRESENCE_MASK)| atsParam->fsci ); /* T0 */
DiegoOstuni 0:75fc82583a41 1145 txBuf[ bufIt++ ] = atsParam->ta; /* TA */
DiegoOstuni 0:75fc82583a41 1146 txBuf[ bufIt++ ] = ( (atsParam->fwi << RFAL_ISODEP_RATS_PARAM_FSDI_SHIFT) |
DiegoOstuni 0:75fc82583a41 1147 (atsParam->sfgi & RFAL_ISODEP_RATS_PARAM_FSDI_MASK) ); /* TB */
DiegoOstuni 0:75fc82583a41 1148 txBuf[ bufIt++ ] = ((atsParam->didSupport) ? RFAL_ISODEP_ATS_TC_DID : 0); /* TC */
DiegoOstuni 0:75fc82583a41 1149
DiegoOstuni 0:75fc82583a41 1150 ST_MEMCPY( &txBuf[bufIt], atsParam->hb, atsParam->hbLen ); /* T1-Tk */
DiegoOstuni 0:75fc82583a41 1151 bufIt += atsParam->hbLen;
DiegoOstuni 0:75fc82583a41 1152
DiegoOstuni 0:75fc82583a41 1153 gIsoDep.state = ISODEP_ST_PICC_ACT_ATS;
DiegoOstuni 0:75fc82583a41 1154
DiegoOstuni 0:75fc82583a41 1155 }
DiegoOstuni 0:75fc82583a41 1156 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1157 else if( *buf == RFAL_ISODEP_CMD_ATTRIB )
DiegoOstuni 0:75fc82583a41 1158 {
DiegoOstuni 0:75fc82583a41 1159 /* Check ATTRIB parameters */
DiegoOstuni 0:75fc82583a41 1160 if( attribResParam == NULL )
DiegoOstuni 0:75fc82583a41 1161 {
DiegoOstuni 0:75fc82583a41 1162 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1163 }
DiegoOstuni 0:75fc82583a41 1164
DiegoOstuni 0:75fc82583a41 1165 /* REMARK: ATTRIB handling */
DiegoOstuni 0:75fc82583a41 1166 NO_WARNING(attribResParam);
DiegoOstuni 0:75fc82583a41 1167 NO_WARNING(bufLen);
DiegoOstuni 0:75fc82583a41 1168 return ERR_NOT_IMPLEMENTED;
DiegoOstuni 0:75fc82583a41 1169 }
DiegoOstuni 0:75fc82583a41 1170 else
DiegoOstuni 0:75fc82583a41 1171 {
DiegoOstuni 0:75fc82583a41 1172 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1173 }
DiegoOstuni 0:75fc82583a41 1174
DiegoOstuni 0:75fc82583a41 1175 gIsoDep.actvParam = actParam;
DiegoOstuni 0:75fc82583a41 1176
DiegoOstuni 0:75fc82583a41 1177
DiegoOstuni 0:75fc82583a41 1178 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1179 /* If requested copy to ISO-DEP device info */
DiegoOstuni 0:75fc82583a41 1180 if( actParam.isoDepDev != NULL )
DiegoOstuni 0:75fc82583a41 1181 {
DiegoOstuni 0:75fc82583a41 1182 actParam.isoDepDev->info.DID = gIsoDep.did;
DiegoOstuni 0:75fc82583a41 1183 actParam.isoDepDev->info.FSx = gIsoDep.fsx;
DiegoOstuni 0:75fc82583a41 1184 actParam.isoDepDev->info.FWT = gIsoDep.fwt;
DiegoOstuni 0:75fc82583a41 1185 actParam.isoDepDev->info.dFWT = 0;
DiegoOstuni 0:75fc82583a41 1186 actParam.isoDepDev->info.DSI = gIsoDep.txBR;
DiegoOstuni 0:75fc82583a41 1187 actParam.isoDepDev->info.DRI = gIsoDep.rxBR;
DiegoOstuni 0:75fc82583a41 1188 }
DiegoOstuni 0:75fc82583a41 1189
DiegoOstuni 0:75fc82583a41 1190 return rfalTransceiveBlockingTx( txBuf, bufIt, (uint8_t*)actParam.rxBuf, sizeof( rfalIsoDepBufFormat ), actParam.rxLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FWT_NONE, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1191 }
DiegoOstuni 0:75fc82583a41 1192
DiegoOstuni 0:75fc82583a41 1193
DiegoOstuni 0:75fc82583a41 1194 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1195 ReturnCode rfalIsoDepListenGetActivationStatus( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1196 {
DiegoOstuni 0:75fc82583a41 1197 ReturnCode err;
DiegoOstuni 0:75fc82583a41 1198 uint8_t* txBuf;
DiegoOstuni 0:75fc82583a41 1199 uint8_t bufIt;
DiegoOstuni 0:75fc82583a41 1200
DiegoOstuni 0:75fc82583a41 1201 rfalBitRate dsi;
DiegoOstuni 0:75fc82583a41 1202 rfalBitRate dri;
DiegoOstuni 0:75fc82583a41 1203
DiegoOstuni 0:75fc82583a41 1204
DiegoOstuni 0:75fc82583a41 1205 /* Check if Activation is running */
DiegoOstuni 0:75fc82583a41 1206 if( gIsoDep.state < ISODEP_ST_PICC_ACT_ATS )
DiegoOstuni 0:75fc82583a41 1207 {
DiegoOstuni 0:75fc82583a41 1208 return ERR_WRONG_STATE;
DiegoOstuni 0:75fc82583a41 1209 }
DiegoOstuni 0:75fc82583a41 1210
DiegoOstuni 0:75fc82583a41 1211 /* Check if Activation has finished already */
DiegoOstuni 0:75fc82583a41 1212 if( gIsoDep.state >= ISODEP_ST_PICC_RX )
DiegoOstuni 0:75fc82583a41 1213 {
DiegoOstuni 0:75fc82583a41 1214 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1215 }
DiegoOstuni 0:75fc82583a41 1216
DiegoOstuni 0:75fc82583a41 1217
DiegoOstuni 0:75fc82583a41 1218 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1219 /* Check for incoming msg */
DiegoOstuni 0:75fc82583a41 1220 err = rfalGetTransceiveStatus();
DiegoOstuni 0:75fc82583a41 1221 switch( err )
DiegoOstuni 0:75fc82583a41 1222 {
DiegoOstuni 0:75fc82583a41 1223 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1224 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 1225 break;
DiegoOstuni 0:75fc82583a41 1226
DiegoOstuni 0:75fc82583a41 1227 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1228 case ERR_LINK_LOSS:
DiegoOstuni 0:75fc82583a41 1229 case ERR_BUSY:
DiegoOstuni 0:75fc82583a41 1230 return err;
DiegoOstuni 0:75fc82583a41 1231
DiegoOstuni 0:75fc82583a41 1232 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1233 case ERR_CRC:
DiegoOstuni 0:75fc82583a41 1234 case ERR_PAR:
DiegoOstuni 0:75fc82583a41 1235 case ERR_FRAMING:
DiegoOstuni 0:75fc82583a41 1236
DiegoOstuni 0:75fc82583a41 1237 /* ISO14443 4 5.6.2.2 2 If ATS has been replied upon a invalid block, PICC disables the PPS responses */
DiegoOstuni 0:75fc82583a41 1238 if( gIsoDep.state == ISODEP_ST_PICC_ACT_ATS )
DiegoOstuni 0:75fc82583a41 1239 {
DiegoOstuni 0:75fc82583a41 1240 gIsoDep.state = ISODEP_ST_PICC_RX;
DiegoOstuni 0:75fc82583a41 1241 break;
DiegoOstuni 0:75fc82583a41 1242 }
DiegoOstuni 0:75fc82583a41 1243 /* fall through */
DiegoOstuni 0:75fc82583a41 1244
DiegoOstuni 0:75fc82583a41 1245 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1246 default:
DiegoOstuni 0:75fc82583a41 1247 /* ReEnable the receiver and wait for another frame */
DiegoOstuni 0:75fc82583a41 1248 isoDepReEnableRx( (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen );
DiegoOstuni 0:75fc82583a41 1249
DiegoOstuni 0:75fc82583a41 1250 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1251 }
DiegoOstuni 0:75fc82583a41 1252
DiegoOstuni 0:75fc82583a41 1253
DiegoOstuni 0:75fc82583a41 1254 txBuf = (uint8_t*)gIsoDep.actvParam.rxBuf; /* Use the rxBuf as TxBuf as well, the struct enforces a size enough MAX(NFCA_PPS_RES_LEN, ISODEP_DSL_MAX_LEN) */
DiegoOstuni 0:75fc82583a41 1255 dri = RFAL_BR_KEEP; /* The RFAL_BR_KEEP is used to check if PPS with BR change was requested */
DiegoOstuni 0:75fc82583a41 1256 bufIt = 0;
DiegoOstuni 0:75fc82583a41 1257
DiegoOstuni 0:75fc82583a41 1258
DiegoOstuni 0:75fc82583a41 1259 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1260 gIsoDep.role = ISODEP_ROLE_PICC;
DiegoOstuni 0:75fc82583a41 1261
DiegoOstuni 0:75fc82583a41 1262 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1263 if( gIsoDep.state == ISODEP_ST_PICC_ACT_ATS )
DiegoOstuni 0:75fc82583a41 1264 {
DiegoOstuni 0:75fc82583a41 1265 /* Check for a PPS ISO 14443-4 5.3 */
DiegoOstuni 0:75fc82583a41 1266 if( ( ((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_STARTBYTE_POS] & RFAL_ISODEP_PPS_MASK) == RFAL_ISODEP_PPS_SB )
DiegoOstuni 0:75fc82583a41 1267 {
DiegoOstuni 0:75fc82583a41 1268 /* ISO 14443-4 5.3.1 Check if the we are the addressed DID/CID */
DiegoOstuni 0:75fc82583a41 1269 /* ISO 14443-4 5.3.2 Check for a valid PPS0 */
DiegoOstuni 0:75fc82583a41 1270 if( (( ((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_STARTBYTE_POS] & RFAL_ISODEP_DID_MASK) != gIsoDep.did) ||
DiegoOstuni 0:75fc82583a41 1271 (( ((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_PPS0_POS] & RFAL_ISODEP_PPS0_VALID_MASK) != RFAL_ISODEP_PPS0_PPS1_NOT_PRESENT) )
DiegoOstuni 0:75fc82583a41 1272 {
DiegoOstuni 0:75fc82583a41 1273 /* Invalid DID on PPS request or Invalid PPS0, reEnable the receiver and wait another frame */
DiegoOstuni 0:75fc82583a41 1274 isoDepReEnableRx( (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen );
DiegoOstuni 0:75fc82583a41 1275
DiegoOstuni 0:75fc82583a41 1276 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1277 }
DiegoOstuni 0:75fc82583a41 1278
DiegoOstuni 0:75fc82583a41 1279 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1280 /* Check PPS1 presence */
DiegoOstuni 0:75fc82583a41 1281 if( ((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_PPS0_POS] == RFAL_ISODEP_PPS0_PPS1_PRESENT )
DiegoOstuni 0:75fc82583a41 1282 {
DiegoOstuni 0:75fc82583a41 1283 dri = (rfalBitRate) (((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_PPS1_POS] & RFAL_ISODEP_PPS1_DxI_MASK);
DiegoOstuni 0:75fc82583a41 1284 dsi = (rfalBitRate)((((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_PPS1_POS] >> RFAL_ISODEP_PPS1_DSI_SHIFT) & RFAL_ISODEP_PPS1_DxI_MASK);
DiegoOstuni 0:75fc82583a41 1285
DiegoOstuni 0:75fc82583a41 1286 if( (!(RFAL_SUPPORT_BR_CE_A_106) && (( dsi == RFAL_BR_106 ) || ( dri == RFAL_BR_106 ))) ||
DiegoOstuni 0:75fc82583a41 1287 (!(RFAL_SUPPORT_BR_CE_A_212) && (( dsi == RFAL_BR_212 ) || ( dri == RFAL_BR_212 ))) ||
DiegoOstuni 0:75fc82583a41 1288 (!(RFAL_SUPPORT_BR_CE_A_424) && (( dsi == RFAL_BR_424 ) || ( dri == RFAL_BR_424 ))) ||
DiegoOstuni 0:75fc82583a41 1289 (!(RFAL_SUPPORT_BR_CE_A_848) && (( dsi == RFAL_BR_848 ) || ( dri == RFAL_BR_848 ))) )
DiegoOstuni 0:75fc82583a41 1290 {
DiegoOstuni 0:75fc82583a41 1291 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 1292 }
DiegoOstuni 0:75fc82583a41 1293 }
DiegoOstuni 0:75fc82583a41 1294
DiegoOstuni 0:75fc82583a41 1295 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1296 /* Compute and send PPS RES / Ack */
DiegoOstuni 0:75fc82583a41 1297 txBuf[ bufIt++ ] = ((uint8_t*)gIsoDep.actvParam.rxBuf)[RFAL_ISODEP_PPS_STARTBYTE_POS];
DiegoOstuni 0:75fc82583a41 1298
DiegoOstuni 0:75fc82583a41 1299 rfalTransceiveBlockingTx( txBuf, bufIt, (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FWT_NONE, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1300
DiegoOstuni 0:75fc82583a41 1301 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1302 /* Exchange the bit rates if requested */
DiegoOstuni 0:75fc82583a41 1303 if( dri != RFAL_BR_KEEP )
DiegoOstuni 0:75fc82583a41 1304 {
DiegoOstuni 0:75fc82583a41 1305 rfalSetBitRate( dsi, dri, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1306
DiegoOstuni 0:75fc82583a41 1307 gIsoDep.txBR = dsi; /* DSI codes the divisor from PICC to PCD */
DiegoOstuni 0:75fc82583a41 1308 gIsoDep.rxBR = dri; /* DRI codes the divisor from PCD to PICC */
DiegoOstuni 0:75fc82583a41 1309
DiegoOstuni 0:75fc82583a41 1310
DiegoOstuni 0:75fc82583a41 1311 if(gIsoDep.actvParam.isoDepDev != NULL)
DiegoOstuni 0:75fc82583a41 1312 {
DiegoOstuni 0:75fc82583a41 1313 gIsoDep.actvParam.isoDepDev->info.DSI = dsi;
DiegoOstuni 0:75fc82583a41 1314 gIsoDep.actvParam.isoDepDev->info.DRI = dri;
DiegoOstuni 0:75fc82583a41 1315 }
DiegoOstuni 0:75fc82583a41 1316 }
DiegoOstuni 0:75fc82583a41 1317 }
DiegoOstuni 0:75fc82583a41 1318 /* Check for a S-Deselect is done on Data Exchange Activity */
DiegoOstuni 0:75fc82583a41 1319 }
DiegoOstuni 0:75fc82583a41 1320
DiegoOstuni 0:75fc82583a41 1321 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1322 gIsoDep.hdrLen = RFAL_ISODEP_PCB_LEN;
DiegoOstuni 0:75fc82583a41 1323 gIsoDep.hdrLen += RFAL_ISODEP_DID_LEN; /* Always assume DID to be aligned with Digital 1.1 15.1.2 and ISO14443 4 5.6.3 #454 */
DiegoOstuni 0:75fc82583a41 1324 gIsoDep.hdrLen += ((gIsoDep.nad != RFAL_ISODEP_NO_NAD) ? RFAL_ISODEP_NAD_LEN : 0);
DiegoOstuni 0:75fc82583a41 1325
DiegoOstuni 0:75fc82583a41 1326 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1327 /* Rule C - The PICC block number shall be initialized to 1 at activation */
DiegoOstuni 0:75fc82583a41 1328 gIsoDep.blockNumber = 1;
DiegoOstuni 0:75fc82583a41 1329
DiegoOstuni 0:75fc82583a41 1330 /* Activation done, keep the rcvd data in, reMap the activation buffer to the global to be retrieved by the DEP method */
DiegoOstuni 0:75fc82583a41 1331 gIsoDep.rxBuf = (uint8_t*)gIsoDep.actvParam.rxBuf;
DiegoOstuni 0:75fc82583a41 1332 gIsoDep.rxBufLen = sizeof( rfalIsoDepBufFormat );
DiegoOstuni 0:75fc82583a41 1333 gIsoDep.rxBufInfPos = (gIsoDep.actvParam.rxBuf->inf - gIsoDep.actvParam.rxBuf->prologue);
DiegoOstuni 0:75fc82583a41 1334 gIsoDep.rxLen = gIsoDep.actvParam.rxLen;
DiegoOstuni 0:75fc82583a41 1335 gIsoDep.rxChaining = gIsoDep.actvParam.isRxChaining;
DiegoOstuni 0:75fc82583a41 1336
DiegoOstuni 0:75fc82583a41 1337 gIsoDep.state = ISODEP_ST_PICC_RX;
DiegoOstuni 0:75fc82583a41 1338 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1339 }
DiegoOstuni 0:75fc82583a41 1340
DiegoOstuni 0:75fc82583a41 1341
DiegoOstuni 0:75fc82583a41 1342 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1343 uint16_t rfalIsoDepGetMaxInfLen( void )
DiegoOstuni 0:75fc82583a41 1344 {
DiegoOstuni 0:75fc82583a41 1345 /* Check whether all parameters are valid, otherwise return minimum default value */
DiegoOstuni 0:75fc82583a41 1346 if( (gIsoDep.fsx < RFAL_ISODEP_FSX_16) || (gIsoDep.fsx > RFAL_ISODEP_FSX_1024) || (gIsoDep.hdrLen > ISODEP_HDR_MAX_LEN) )
DiegoOstuni 0:75fc82583a41 1347 {
DiegoOstuni 0:75fc82583a41 1348 return (RFAL_ISODEP_FSX_16 - RFAL_ISODEP_PCB_LEN - ISODEP_CRC_LEN);
DiegoOstuni 0:75fc82583a41 1349 }
DiegoOstuni 0:75fc82583a41 1350
DiegoOstuni 0:75fc82583a41 1351 return (gIsoDep.fsx - gIsoDep.hdrLen - ISODEP_CRC_LEN);
DiegoOstuni 0:75fc82583a41 1352 }
DiegoOstuni 0:75fc82583a41 1353
DiegoOstuni 0:75fc82583a41 1354
DiegoOstuni 0:75fc82583a41 1355 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1356 ReturnCode rfalIsoDepStartTransceive( rfalIsoDepTxRxParam param )
DiegoOstuni 0:75fc82583a41 1357 {
DiegoOstuni 0:75fc82583a41 1358 gIsoDep.txBuf = param.txBuf->prologue;
DiegoOstuni 0:75fc82583a41 1359 gIsoDep.txBufInfPos = (param.txBuf->inf - param.txBuf->prologue);
DiegoOstuni 0:75fc82583a41 1360 gIsoDep.txBufLen = param.txBufLen;
DiegoOstuni 0:75fc82583a41 1361 gIsoDep.isTxChaining = param.isTxChaining;
DiegoOstuni 0:75fc82583a41 1362
DiegoOstuni 0:75fc82583a41 1363 gIsoDep.rxBuf = param.rxBuf->prologue;
DiegoOstuni 0:75fc82583a41 1364 gIsoDep.rxBufInfPos = (param.rxBuf->inf - param.rxBuf->prologue);
DiegoOstuni 0:75fc82583a41 1365 gIsoDep.rxBufLen = sizeof(rfalIsoDepBufFormat);
DiegoOstuni 0:75fc82583a41 1366
DiegoOstuni 0:75fc82583a41 1367 gIsoDep.rxLen = param.rxLen;
DiegoOstuni 0:75fc82583a41 1368 gIsoDep.rxChaining = param.isRxChaining;
DiegoOstuni 0:75fc82583a41 1369
DiegoOstuni 0:75fc82583a41 1370
DiegoOstuni 0:75fc82583a41 1371 gIsoDep.fwt = param.FWT;
DiegoOstuni 0:75fc82583a41 1372 gIsoDep.dFwt = param.dFWT;
DiegoOstuni 0:75fc82583a41 1373 gIsoDep.fsx = param.FSx;
DiegoOstuni 0:75fc82583a41 1374 gIsoDep.did = param.DID;
DiegoOstuni 0:75fc82583a41 1375
DiegoOstuni 0:75fc82583a41 1376 /* Only change the FSx from activation if no to Keep */
DiegoOstuni 0:75fc82583a41 1377 gIsoDep.ourFsx = (( param.ourFSx != RFAL_ISODEP_FSX_KEEP ) ? param.ourFSx : gIsoDep.ourFsx);
DiegoOstuni 0:75fc82583a41 1378
DiegoOstuni 0:75fc82583a41 1379 /* Clear inner control params for next dataExchange */
DiegoOstuni 0:75fc82583a41 1380 gIsoDep.isRxChaining = false;
DiegoOstuni 0:75fc82583a41 1381 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 1382
DiegoOstuni 0:75fc82583a41 1383 if(gIsoDep.role == ISODEP_ROLE_PICC)
DiegoOstuni 0:75fc82583a41 1384 {
DiegoOstuni 0:75fc82583a41 1385 if(gIsoDep.txBufLen > 0)
DiegoOstuni 0:75fc82583a41 1386 {
DiegoOstuni 0:75fc82583a41 1387 /* Ensure that an RTOX Ack is not being expected at moment */
DiegoOstuni 0:75fc82583a41 1388 if( !gIsoDep.isWait4WTX )
DiegoOstuni 0:75fc82583a41 1389 {
DiegoOstuni 0:75fc82583a41 1390 gIsoDep.state = ISODEP_ST_PICC_TX;
DiegoOstuni 0:75fc82583a41 1391 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1392 }
DiegoOstuni 0:75fc82583a41 1393 else
DiegoOstuni 0:75fc82583a41 1394 {
DiegoOstuni 0:75fc82583a41 1395 /* If RTOX Ack is expected, signal a pending Tx to be transmitted right after */
DiegoOstuni 0:75fc82583a41 1396 gIsoDep.isTxPending = true;
DiegoOstuni 0:75fc82583a41 1397 }
DiegoOstuni 0:75fc82583a41 1398 }
DiegoOstuni 0:75fc82583a41 1399
DiegoOstuni 0:75fc82583a41 1400 /* Digital 1.1 15.2.5.1 The first block SHALL be sent by the Reader/Writer */
DiegoOstuni 0:75fc82583a41 1401 gIsoDep.state = ISODEP_ST_PICC_RX;
DiegoOstuni 0:75fc82583a41 1402 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1403 }
DiegoOstuni 0:75fc82583a41 1404
DiegoOstuni 0:75fc82583a41 1405 gIsoDep.state = ISODEP_ST_PCD_TX;
DiegoOstuni 0:75fc82583a41 1406 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1407 }
DiegoOstuni 0:75fc82583a41 1408
DiegoOstuni 0:75fc82583a41 1409
DiegoOstuni 0:75fc82583a41 1410 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1411 ReturnCode rfalIsoDepGetTransceiveStatus( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1412 {
DiegoOstuni 0:75fc82583a41 1413 if( gIsoDep.role == ISODEP_ROLE_PICC)
DiegoOstuni 0:75fc82583a41 1414 return isoDepDataExchangePICC( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1415 else
DiegoOstuni 0:75fc82583a41 1416 return isoDepDataExchangePCD( gIsoDep.rxLen, gIsoDep.rxChaining, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1417 }
DiegoOstuni 0:75fc82583a41 1418
DiegoOstuni 0:75fc82583a41 1419
DiegoOstuni 0:75fc82583a41 1420 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1421 ReturnCode isoDepDataExchangePICC( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1422 {
DiegoOstuni 0:75fc82583a41 1423 uint8_t rxPCB;
DiegoOstuni 0:75fc82583a41 1424 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 1425
DiegoOstuni 0:75fc82583a41 1426 switch( gIsoDep.state )
DiegoOstuni 0:75fc82583a41 1427 {
DiegoOstuni 0:75fc82583a41 1428 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1429 case ISODEP_ST_IDLE:
DiegoOstuni 0:75fc82583a41 1430 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1431
DiegoOstuni 0:75fc82583a41 1432
DiegoOstuni 0:75fc82583a41 1433 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1434 case ISODEP_ST_PICC_TX:
DiegoOstuni 0:75fc82583a41 1435
DiegoOstuni 0:75fc82583a41 1436 ret = isoDepTx( isoDep_PCBIBlock( gIsoDep.blockNumber ), gIsoDep.txBuf, (gIsoDep.txBuf + gIsoDep.txBufInfPos), gIsoDep.txBufLen, RFAL_FWT_NONE, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1437
DiegoOstuni 0:75fc82583a41 1438 /* Clear pending Tx flag */
DiegoOstuni 0:75fc82583a41 1439 gIsoDep.isTxPending = false;
DiegoOstuni 0:75fc82583a41 1440
DiegoOstuni 0:75fc82583a41 1441 switch( ret )
DiegoOstuni 0:75fc82583a41 1442 {
DiegoOstuni 0:75fc82583a41 1443 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 1444 gIsoDep.state = ISODEP_ST_PICC_RX;
DiegoOstuni 0:75fc82583a41 1445 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1446
DiegoOstuni 0:75fc82583a41 1447 default:
DiegoOstuni 0:75fc82583a41 1448 break;
DiegoOstuni 0:75fc82583a41 1449 }
DiegoOstuni 0:75fc82583a41 1450 return ret;
DiegoOstuni 0:75fc82583a41 1451
DiegoOstuni 0:75fc82583a41 1452
DiegoOstuni 0:75fc82583a41 1453 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1454 case ISODEP_ST_PICC_RX:
DiegoOstuni 0:75fc82583a41 1455
DiegoOstuni 0:75fc82583a41 1456 ret = rfalGetTransceiveStatus();
DiegoOstuni 0:75fc82583a41 1457 switch( ret )
DiegoOstuni 0:75fc82583a41 1458 {
DiegoOstuni 0:75fc82583a41 1459 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1460 /* Data rcvd with error or timeout -> mute */
DiegoOstuni 0:75fc82583a41 1461 case ERR_TIMEOUT:
DiegoOstuni 0:75fc82583a41 1462 case ERR_CRC:
DiegoOstuni 0:75fc82583a41 1463 case ERR_PAR:
DiegoOstuni 0:75fc82583a41 1464 case ERR_FRAMING:
DiegoOstuni 0:75fc82583a41 1465
DiegoOstuni 0:75fc82583a41 1466 /* Digital 1.1 - 15.2.6.2 The CE SHALL NOT attempt error recovery and remains in Rx mode upon Transmission or a Protocol Error */
DiegoOstuni 0:75fc82583a41 1467 isoDepReEnableRx( (uint8_t*)gIsoDep.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1468
DiegoOstuni 0:75fc82583a41 1469 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1470
DiegoOstuni 0:75fc82583a41 1471 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1472 case ERR_LINK_LOSS:
DiegoOstuni 0:75fc82583a41 1473 return ret; /* Debug purposes */
DiegoOstuni 0:75fc82583a41 1474
DiegoOstuni 0:75fc82583a41 1475 case ERR_BUSY:
DiegoOstuni 0:75fc82583a41 1476 return ret; /* Debug purposes */
DiegoOstuni 0:75fc82583a41 1477
DiegoOstuni 0:75fc82583a41 1478 default:
DiegoOstuni 0:75fc82583a41 1479 return ret;
DiegoOstuni 0:75fc82583a41 1480
DiegoOstuni 0:75fc82583a41 1481 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1482 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 1483 *gIsoDep.rxLen = rfalConvBitsToBytes( *gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1484 break;
DiegoOstuni 0:75fc82583a41 1485 }
DiegoOstuni 0:75fc82583a41 1486 break;
DiegoOstuni 0:75fc82583a41 1487
DiegoOstuni 0:75fc82583a41 1488
DiegoOstuni 0:75fc82583a41 1489 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1490 case ISODEP_ST_PICC_SWTX:
DiegoOstuni 0:75fc82583a41 1491
DiegoOstuni 0:75fc82583a41 1492 if( !isoDepTimerisExpired( gIsoDep.WTXTimer ) ) /* Do nothing until WTX timer has expired */
DiegoOstuni 0:75fc82583a41 1493 {
DiegoOstuni 0:75fc82583a41 1494 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1495 }
DiegoOstuni 0:75fc82583a41 1496
DiegoOstuni 0:75fc82583a41 1497 /* Set waiting for WTX Ack Flag */
DiegoOstuni 0:75fc82583a41 1498 gIsoDep.isWait4WTX = true;
DiegoOstuni 0:75fc82583a41 1499
DiegoOstuni 0:75fc82583a41 1500 /* Digital 1.1 15.2.2.9 - Calculate the WTXM such that FWTtemp <= FWTmax */
DiegoOstuni 0:75fc82583a41 1501 gIsoDep.lastWTXM = isoDep_WTXMListenerMax( gIsoDep.fwt );
DiegoOstuni 0:75fc82583a41 1502 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_S_WTX, gIsoDep.lastWTXM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 1503
DiegoOstuni 0:75fc82583a41 1504 gIsoDep.state = ISODEP_ST_PICC_RX; /* Go back to Rx to process WTX ack */
DiegoOstuni 0:75fc82583a41 1505 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1506
DiegoOstuni 0:75fc82583a41 1507
DiegoOstuni 0:75fc82583a41 1508 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1509 default:
DiegoOstuni 0:75fc82583a41 1510 return ERR_INTERNAL;
DiegoOstuni 0:75fc82583a41 1511 }
DiegoOstuni 0:75fc82583a41 1512
DiegoOstuni 0:75fc82583a41 1513 /* ISO 14443-4 7.5.6.2 CE SHALL NOT attempt error recovery -> clear counters */
DiegoOstuni 0:75fc82583a41 1514 isoDepClearCounters();
DiegoOstuni 0:75fc82583a41 1515
DiegoOstuni 0:75fc82583a41 1516 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1517 /* No error, process incoming msg */
DiegoOstuni 0:75fc82583a41 1518 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1519
DiegoOstuni 0:75fc82583a41 1520 /* Grab rcvd PCB */
DiegoOstuni 0:75fc82583a41 1521 rxPCB = gIsoDep.rxBuf[ ISODEP_PCB_POS ];
DiegoOstuni 0:75fc82583a41 1522
DiegoOstuni 0:75fc82583a41 1523
DiegoOstuni 0:75fc82583a41 1524 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1525 /* When DID=0 PCD may or may not use DID, therefore check whether current PCD request
DiegoOstuni 0:75fc82583a41 1526 * has DID present to be reflected on max INF length #454 */
DiegoOstuni 0:75fc82583a41 1527
DiegoOstuni 0:75fc82583a41 1528 /* ReCalculate Header Length */
DiegoOstuni 0:75fc82583a41 1529 gIsoDep.hdrLen = RFAL_ISODEP_PCB_LEN;
DiegoOstuni 0:75fc82583a41 1530 gIsoDep.hdrLen += ( (isoDep_PCBhasDID(rxPCB)) ? RFAL_ISODEP_DID_LEN : 0 );
DiegoOstuni 0:75fc82583a41 1531 gIsoDep.hdrLen += ( (isoDep_PCBhasNAD(rxPCB)) ? RFAL_ISODEP_NAD_LEN : 0 );
DiegoOstuni 0:75fc82583a41 1532
DiegoOstuni 0:75fc82583a41 1533 /* Store whether last PCD block had DID. for PICC special handling of DID = 0 */
DiegoOstuni 0:75fc82583a41 1534 if( gIsoDep.did == RFAL_ISODEP_DID_00 )
DiegoOstuni 0:75fc82583a41 1535 {
DiegoOstuni 0:75fc82583a41 1536 gIsoDep.lastDID00 = ( (isoDep_PCBhasDID(rxPCB)) ? true : false );
DiegoOstuni 0:75fc82583a41 1537 }
DiegoOstuni 0:75fc82583a41 1538
DiegoOstuni 0:75fc82583a41 1539 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1540 /* Check rcvd msg length, cannot be less then the expected header OR *
DiegoOstuni 0:75fc82583a41 1541 * if the rcvd msg exceeds our announced frame size (FSD) */
DiegoOstuni 0:75fc82583a41 1542 if( ((*gIsoDep.rxLen) < gIsoDep.hdrLen) || ((*gIsoDep.rxLen) > (gIsoDep.ourFsx - ISODEP_CRC_LEN)) )
DiegoOstuni 0:75fc82583a41 1543 {
DiegoOstuni 0:75fc82583a41 1544 isoDepReEnableRx( (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen );
DiegoOstuni 0:75fc82583a41 1545 return ERR_BUSY; /* ERR_PROTO Ignore this protocol request */
DiegoOstuni 0:75fc82583a41 1546 }
DiegoOstuni 0:75fc82583a41 1547
DiegoOstuni 0:75fc82583a41 1548 /* If we are expecting DID, check if PCB signals its presence and if device ID match OR
DiegoOstuni 0:75fc82583a41 1549 * If our DID=0 and DID is sent but with an incorrect value */
DiegoOstuni 0:75fc82583a41 1550 if( ((gIsoDep.did != RFAL_ISODEP_DID_00) && ( !isoDep_PCBhasDID(rxPCB) || (gIsoDep.did != gIsoDep.rxBuf[ ISODEP_DID_POS ]))) ||
DiegoOstuni 0:75fc82583a41 1551 ((gIsoDep.did == RFAL_ISODEP_DID_00) && isoDep_PCBhasDID(rxPCB) && (RFAL_ISODEP_DID_00 != gIsoDep.rxBuf[ ISODEP_DID_POS ]) ) )
DiegoOstuni 0:75fc82583a41 1552 {
DiegoOstuni 0:75fc82583a41 1553 isoDepReEnableRx( (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen );
DiegoOstuni 0:75fc82583a41 1554 return ERR_BUSY; /* Ignore a wrong DID request */
DiegoOstuni 0:75fc82583a41 1555 }
DiegoOstuni 0:75fc82583a41 1556
DiegoOstuni 0:75fc82583a41 1557 /* If we aren't expecting NAD and it's received */
DiegoOstuni 0:75fc82583a41 1558 if( (gIsoDep.nad == RFAL_ISODEP_NO_NAD) && isoDep_PCBhasNAD(rxPCB) )
DiegoOstuni 0:75fc82583a41 1559 {
DiegoOstuni 0:75fc82583a41 1560 isoDepReEnableRx( (uint8_t*)gIsoDep.actvParam.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.actvParam.rxLen );
DiegoOstuni 0:75fc82583a41 1561 return ERR_BUSY; /* Ignore a unexpected NAD request */
DiegoOstuni 0:75fc82583a41 1562 }
DiegoOstuni 0:75fc82583a41 1563
DiegoOstuni 0:75fc82583a41 1564 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1565 /* Process S-Block */
DiegoOstuni 0:75fc82583a41 1566 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1567 if( isoDep_PCBisSBlock(rxPCB) )
DiegoOstuni 0:75fc82583a41 1568 {
DiegoOstuni 0:75fc82583a41 1569 /* Check if is a Wait Time eXtension */
DiegoOstuni 0:75fc82583a41 1570 if( isoDep_PCBisSWTX(rxPCB) )
DiegoOstuni 0:75fc82583a41 1571 {
DiegoOstuni 0:75fc82583a41 1572 /* Check if we're expecting a S-WTX */
DiegoOstuni 0:75fc82583a41 1573 if( isoDep_PCBisWTX( gIsoDep.lastPCB ) )
DiegoOstuni 0:75fc82583a41 1574 {
DiegoOstuni 0:75fc82583a41 1575 /* Digital 1.1 15.2.2.11 S(WTX) Ack with different WTXM -> Protocol Error *
DiegoOstuni 0:75fc82583a41 1576 * Power level indication also should be set to 0 */
DiegoOstuni 0:75fc82583a41 1577 if( ( gIsoDep.rxBuf[ gIsoDep.hdrLen ] == gIsoDep.lastWTXM) && ((*gIsoDep.rxLen - gIsoDep.hdrLen) == ISODEP_SWTX_INF_LEN) )
DiegoOstuni 0:75fc82583a41 1578 {
DiegoOstuni 0:75fc82583a41 1579 /* Clear waiting for RTOX Ack Flag */
DiegoOstuni 0:75fc82583a41 1580 gIsoDep.isWait4WTX = false;
DiegoOstuni 0:75fc82583a41 1581
DiegoOstuni 0:75fc82583a41 1582 /* Check if a Tx is already pending */
DiegoOstuni 0:75fc82583a41 1583 if( gIsoDep.isTxPending )
DiegoOstuni 0:75fc82583a41 1584 {
DiegoOstuni 0:75fc82583a41 1585 /* Has a pending Tx, go immediately to TX */
DiegoOstuni 0:75fc82583a41 1586 gIsoDep.state = ISODEP_ST_PICC_TX;
DiegoOstuni 0:75fc82583a41 1587 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1588 }
DiegoOstuni 0:75fc82583a41 1589
DiegoOstuni 0:75fc82583a41 1590 /* Set WTX timer */
DiegoOstuni 0:75fc82583a41 1591 isoDepTimerStart( gIsoDep.WTXTimer, isoDep_WTXAdjust( (gIsoDep.lastWTXM * rfalConv1fcToMs( gIsoDep.fwt )) ) );
DiegoOstuni 0:75fc82583a41 1592
DiegoOstuni 0:75fc82583a41 1593 gIsoDep.state = ISODEP_ST_PICC_SWTX;
DiegoOstuni 0:75fc82583a41 1594 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1595 }
DiegoOstuni 0:75fc82583a41 1596 }
DiegoOstuni 0:75fc82583a41 1597 /* Unexpected/Incorrect S-WTX, fall into reRenable */
DiegoOstuni 0:75fc82583a41 1598 }
DiegoOstuni 0:75fc82583a41 1599
DiegoOstuni 0:75fc82583a41 1600 /* Check if is a deselect request */
DiegoOstuni 0:75fc82583a41 1601 if( isoDep_PCBisSDeselect(rxPCB) && ((*gIsoDep.rxLen - gIsoDep.hdrLen) == ISODEP_SDSL_INF_LEN) )
DiegoOstuni 0:75fc82583a41 1602 {
DiegoOstuni 0:75fc82583a41 1603 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_S_DSL, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 1604
DiegoOstuni 0:75fc82583a41 1605 rfalIsoDepInitialize(); /* Session finished reInit vars */
DiegoOstuni 0:75fc82583a41 1606 return ERR_SLEEP_REQ;
DiegoOstuni 0:75fc82583a41 1607 }
DiegoOstuni 0:75fc82583a41 1608
DiegoOstuni 0:75fc82583a41 1609 /* Unexpected S-Block, fall into reRenable */
DiegoOstuni 0:75fc82583a41 1610 }
DiegoOstuni 0:75fc82583a41 1611
DiegoOstuni 0:75fc82583a41 1612 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1613 /* Process R-Block */
DiegoOstuni 0:75fc82583a41 1614 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1615 else if( isoDep_PCBisRBlock(rxPCB) && ((*gIsoDep.rxLen - gIsoDep.hdrLen) == ISODEP_RBLOCK_INF_LEN))
DiegoOstuni 0:75fc82583a41 1616 {
DiegoOstuni 0:75fc82583a41 1617 if( isoDep_PCBisRACK(rxPCB) ) /* Check if is a R-ACK */
DiegoOstuni 0:75fc82583a41 1618 {
DiegoOstuni 0:75fc82583a41 1619 if( isoDep_GetBN(rxPCB) == gIsoDep.blockNumber ) /* Check block number */
DiegoOstuni 0:75fc82583a41 1620 {
DiegoOstuni 0:75fc82583a41 1621 /* Rule 11 - R(ACK) with current bn -> re-transmit */
DiegoOstuni 0:75fc82583a41 1622 if( !isoDep_PCBisIBlock(gIsoDep.lastPCB) )
DiegoOstuni 0:75fc82583a41 1623 isoDepReSendControlMsg( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1624 else
DiegoOstuni 0:75fc82583a41 1625 gIsoDep.state = ISODEP_ST_PICC_TX;
DiegoOstuni 0:75fc82583a41 1626
DiegoOstuni 0:75fc82583a41 1627 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1628 }
DiegoOstuni 0:75fc82583a41 1629 else
DiegoOstuni 0:75fc82583a41 1630 {
DiegoOstuni 0:75fc82583a41 1631 if( !gIsoDep.isTxChaining )
DiegoOstuni 0:75fc82583a41 1632 {
DiegoOstuni 0:75fc82583a41 1633 /* Rule 13 violation R(ACK) without performing chaining */
DiegoOstuni 0:75fc82583a41 1634 isoDepReEnableRx( (uint8_t*)gIsoDep.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1635 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1636 }
DiegoOstuni 0:75fc82583a41 1637
DiegoOstuni 0:75fc82583a41 1638 /* Rule E - R(ACK) with not current bn -> toogle bn */
DiegoOstuni 0:75fc82583a41 1639 isoDep_ToggleBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 1640
DiegoOstuni 0:75fc82583a41 1641 /* This block has been transmitted and acknowledged, perform WTX until next data is provided */
DiegoOstuni 0:75fc82583a41 1642
DiegoOstuni 0:75fc82583a41 1643 /* Rule 9 - PICC is allowed to send an S(WTX) instead of an I-block or an R(ACK) */
DiegoOstuni 0:75fc82583a41 1644 isoDepTimerStart( gIsoDep.WTXTimer, isoDep_WTXAdjust( rfalConv1fcToMs( gIsoDep.fwt )) );
DiegoOstuni 0:75fc82583a41 1645 gIsoDep.state = ISODEP_ST_PICC_SWTX;
DiegoOstuni 0:75fc82583a41 1646
DiegoOstuni 0:75fc82583a41 1647 /* Rule 13 - R(ACK) with not current bn -> continue chaining */
DiegoOstuni 0:75fc82583a41 1648 return ERR_NONE; /* This block has been transmitted */
DiegoOstuni 0:75fc82583a41 1649 }
DiegoOstuni 0:75fc82583a41 1650 }
DiegoOstuni 0:75fc82583a41 1651 else if( isoDep_PCBisRNAK(rxPCB) ) /* Check if is a R-NACK */
DiegoOstuni 0:75fc82583a41 1652 {
DiegoOstuni 0:75fc82583a41 1653 if( isoDep_GetBN(rxPCB) == gIsoDep.blockNumber ) /* Check block number */
DiegoOstuni 0:75fc82583a41 1654 {
DiegoOstuni 0:75fc82583a41 1655 /* Rule 11 - R(NAK) with current bn -> re-transmit last x-Block */
DiegoOstuni 0:75fc82583a41 1656 if( !isoDep_PCBisIBlock(gIsoDep.lastPCB) )
DiegoOstuni 0:75fc82583a41 1657 isoDepReSendControlMsg( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1658 else
DiegoOstuni 0:75fc82583a41 1659 gIsoDep.state = ISODEP_ST_PICC_TX;
DiegoOstuni 0:75fc82583a41 1660
DiegoOstuni 0:75fc82583a41 1661 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1662 }
DiegoOstuni 0:75fc82583a41 1663 else
DiegoOstuni 0:75fc82583a41 1664 {
DiegoOstuni 0:75fc82583a41 1665 /* Rule 12 - R(NAK) with not current bn -> R(ACK) */
DiegoOstuni 0:75fc82583a41 1666 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 1667
DiegoOstuni 0:75fc82583a41 1668 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1669 }
DiegoOstuni 0:75fc82583a41 1670 }
DiegoOstuni 0:75fc82583a41 1671
DiegoOstuni 0:75fc82583a41 1672 /* Unexpected R-Block, fall into reRenable */
DiegoOstuni 0:75fc82583a41 1673 }
DiegoOstuni 0:75fc82583a41 1674
DiegoOstuni 0:75fc82583a41 1675 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1676 /* Process I-Block */
DiegoOstuni 0:75fc82583a41 1677 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1678 else if( isoDep_PCBisIBlock(rxPCB) )
DiegoOstuni 0:75fc82583a41 1679 {
DiegoOstuni 0:75fc82583a41 1680 /* Rule D - When an I-block is received, the PICC shall toggle its block number before sending a block */
DiegoOstuni 0:75fc82583a41 1681 isoDep_ToggleBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 1682
DiegoOstuni 0:75fc82583a41 1683 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1684 /* Check if the block number is the one expected */
DiegoOstuni 0:75fc82583a41 1685 /* Check if PCD sent an I-Block instead ACK/NACK when we are chaining */
DiegoOstuni 0:75fc82583a41 1686 if( (isoDep_GetBN(rxPCB) != gIsoDep.blockNumber) || (gIsoDep.isTxChaining) )
DiegoOstuni 0:75fc82583a41 1687 {
DiegoOstuni 0:75fc82583a41 1688 /* Remain in the same Block Number */
DiegoOstuni 0:75fc82583a41 1689 isoDep_ToggleBN( gIsoDep.blockNumber );
DiegoOstuni 0:75fc82583a41 1690
DiegoOstuni 0:75fc82583a41 1691 /* ISO 14443-4 7.5.6.2 & Digital 1.1 - 15.2.6.2 The CE SHALL NOT attempt error recovery and remains in Rx mode upon Transmission or a Protocol Error */
DiegoOstuni 0:75fc82583a41 1692 isoDepReEnableRx( (uint8_t*)gIsoDep.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1693 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1694 }
DiegoOstuni 0:75fc82583a41 1695
DiegoOstuni 0:75fc82583a41 1696 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1697 /* is PCD performing chaining ? */
DiegoOstuni 0:75fc82583a41 1698 if( isoDep_PCBisChaining(rxPCB) )
DiegoOstuni 0:75fc82583a41 1699 {
DiegoOstuni 0:75fc82583a41 1700 gIsoDep.isRxChaining = true;
DiegoOstuni 0:75fc82583a41 1701 *gIsoDep.rxChaining = true; /* Output Parameter*/
DiegoOstuni 0:75fc82583a41 1702
DiegoOstuni 0:75fc82583a41 1703 EXIT_ON_ERR( ret, isoDepHandleControlMsg( ISODEP_R_ACK, RFAL_ISODEP_NO_PARAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 1704
DiegoOstuni 0:75fc82583a41 1705 /* Received I-Block with chaining, send current data to DH */
DiegoOstuni 0:75fc82583a41 1706
DiegoOstuni 0:75fc82583a41 1707 /* remove ISO DEP header, check is necessary to move the INF data on the buffer */
DiegoOstuni 0:75fc82583a41 1708 *gIsoDep.rxLen -= gIsoDep.hdrLen;
DiegoOstuni 0:75fc82583a41 1709 if( gIsoDep.hdrLen != gIsoDep.rxBufInfPos )
DiegoOstuni 0:75fc82583a41 1710 {
DiegoOstuni 0:75fc82583a41 1711 ST_MEMMOVE( (gIsoDep.rxBuf + gIsoDep.rxBufInfPos), (gIsoDep.rxBuf + gIsoDep.hdrLen), *gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1712 }
DiegoOstuni 0:75fc82583a41 1713 return ERR_AGAIN; /* Send Again signalling to run again, but some chaining data has arrived*/
DiegoOstuni 0:75fc82583a41 1714 }
DiegoOstuni 0:75fc82583a41 1715
DiegoOstuni 0:75fc82583a41 1716
DiegoOstuni 0:75fc82583a41 1717 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1718 /* PCD is not performing chaining */
DiegoOstuni 0:75fc82583a41 1719 gIsoDep.isRxChaining = false; /* clear PCD chaining flag */
DiegoOstuni 0:75fc82583a41 1720 *gIsoDep.rxChaining = false; /* Output Parameter */
DiegoOstuni 0:75fc82583a41 1721
DiegoOstuni 0:75fc82583a41 1722 /* remove ISO DEP header, check is necessary to move the INF data on the buffer */
DiegoOstuni 0:75fc82583a41 1723 *gIsoDep.rxLen -= gIsoDep.hdrLen;
DiegoOstuni 0:75fc82583a41 1724 if( gIsoDep.hdrLen != gIsoDep.rxBufInfPos )
DiegoOstuni 0:75fc82583a41 1725 {
DiegoOstuni 0:75fc82583a41 1726 ST_MEMMOVE( (gIsoDep.rxBuf + gIsoDep.rxBufInfPos), (gIsoDep.rxBuf + gIsoDep.hdrLen), *gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1727 }
DiegoOstuni 0:75fc82583a41 1728
DiegoOstuni 0:75fc82583a41 1729
DiegoOstuni 0:75fc82583a41 1730 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1731 /* Reception done, send data back and start WTX timer */
DiegoOstuni 0:75fc82583a41 1732 isoDepTimerStart( gIsoDep.WTXTimer, isoDep_WTXAdjust( rfalConv1fcToMs( gIsoDep.fwt )) );
DiegoOstuni 0:75fc82583a41 1733
DiegoOstuni 0:75fc82583a41 1734 gIsoDep.state = ISODEP_ST_PICC_SWTX;
DiegoOstuni 0:75fc82583a41 1735 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1736 }
DiegoOstuni 0:75fc82583a41 1737
DiegoOstuni 0:75fc82583a41 1738 /* Unexpected/Unknown Block */
DiegoOstuni 0:75fc82583a41 1739 /* ISO 14443-4 7.5.6.2 & Digital 1.1 - 15.2.6.2 The CE SHALL NOT attempt error recovery and remains in Rx mode upon Transmission or a Protocol Error */
DiegoOstuni 0:75fc82583a41 1740 isoDepReEnableRx( (uint8_t*)gIsoDep.rxBuf, sizeof( rfalIsoDepBufFormat ), gIsoDep.rxLen );
DiegoOstuni 0:75fc82583a41 1741
DiegoOstuni 0:75fc82583a41 1742 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 1743 }
DiegoOstuni 0:75fc82583a41 1744
DiegoOstuni 0:75fc82583a41 1745
DiegoOstuni 0:75fc82583a41 1746 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1747 ReturnCode rfalIsoDepRATS( rfalIsoDepFSxI FSDI, uint8_t DID, rfalIsoDepAts *ats , uint8_t *atsLen, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1748 {
DiegoOstuni 0:75fc82583a41 1749 uint16_t rcvLen;
DiegoOstuni 0:75fc82583a41 1750 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 1751 rfalIsoDepRats ratsReq;
DiegoOstuni 0:75fc82583a41 1752
DiegoOstuni 0:75fc82583a41 1753 if( ats == NULL )
DiegoOstuni 0:75fc82583a41 1754 {
DiegoOstuni 0:75fc82583a41 1755 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1756 }
DiegoOstuni 0:75fc82583a41 1757
DiegoOstuni 0:75fc82583a41 1758 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1759 /* Compose RATS */
DiegoOstuni 0:75fc82583a41 1760 ratsReq.CMD = RFAL_ISODEP_CMD_RATS;
DiegoOstuni 0:75fc82583a41 1761 ratsReq.PARAM = ((FSDI << RFAL_ISODEP_RATS_PARAM_FSDI_SHIFT) & RFAL_ISODEP_RATS_PARAM_FSDI_MASK) | (DID & RFAL_ISODEP_RATS_PARAM_DID_MASK);
DiegoOstuni 0:75fc82583a41 1762
DiegoOstuni 0:75fc82583a41 1763 ret = rfalTransceiveBlockingTxRx( (uint8_t*)&ratsReq, sizeof(rfalIsoDepRats), (uint8_t*)ats, sizeof(rfalIsoDepAts), &rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_ISODEP_T4T_FWT_ACTIVATION, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1764
DiegoOstuni 0:75fc82583a41 1765 if( ret == ERR_NONE )
DiegoOstuni 0:75fc82583a41 1766 {
DiegoOstuni 0:75fc82583a41 1767 /* Check for valid ATS length Digital 1.1 13.6.2.1 & 13.6.2.3 */
DiegoOstuni 0:75fc82583a41 1768 if( (rcvLen < RFAL_ISODEP_ATS_MIN_LEN) || (rcvLen > RFAL_ISODEP_ATS_MAX_LEN) || (ats->TL != rcvLen) )
DiegoOstuni 0:75fc82583a41 1769 {
DiegoOstuni 0:75fc82583a41 1770 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 1771 }
DiegoOstuni 0:75fc82583a41 1772
DiegoOstuni 0:75fc82583a41 1773 /* Assign our FSx, in case the a Deselect is send without Transceive */
DiegoOstuni 0:75fc82583a41 1774 gIsoDep.ourFsx = rfalIsoDepFSxI2FSx( FSDI );
DiegoOstuni 0:75fc82583a41 1775 }
DiegoOstuni 0:75fc82583a41 1776
DiegoOstuni 0:75fc82583a41 1777 /* Check and assign if ATS length was requested (length also available on TL) */
DiegoOstuni 0:75fc82583a41 1778 if( atsLen != NULL )
DiegoOstuni 0:75fc82583a41 1779 {
DiegoOstuni 0:75fc82583a41 1780 *atsLen = rcvLen;
DiegoOstuni 0:75fc82583a41 1781 }
DiegoOstuni 0:75fc82583a41 1782
DiegoOstuni 0:75fc82583a41 1783 return ret;
DiegoOstuni 0:75fc82583a41 1784 }
DiegoOstuni 0:75fc82583a41 1785
DiegoOstuni 0:75fc82583a41 1786
DiegoOstuni 0:75fc82583a41 1787 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1788 ReturnCode rfalIsoDepPPS( uint8_t DID, rfalBitRate DSI, rfalBitRate DRI, rfalIsoDepPpsRes *ppsRes, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1789 {
DiegoOstuni 0:75fc82583a41 1790 uint16_t rcvLen;
DiegoOstuni 0:75fc82583a41 1791 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 1792 rfalIsoDepPpsReq ppsReq;
DiegoOstuni 0:75fc82583a41 1793
DiegoOstuni 0:75fc82583a41 1794 if( (ppsRes == NULL) || (DSI > RFAL_BR_848) || (DRI > RFAL_BR_848) || (DID > RFAL_ISODEP_DID_MAX) )
DiegoOstuni 0:75fc82583a41 1795 {
DiegoOstuni 0:75fc82583a41 1796 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1797 }
DiegoOstuni 0:75fc82583a41 1798
DiegoOstuni 0:75fc82583a41 1799 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1800 /* Compose PPS Request */
DiegoOstuni 0:75fc82583a41 1801 ppsReq.PPSS = (RFAL_ISODEP_PPS_SB | (DID & RFAL_ISODEP_PPS_SB_DID_MASK));
DiegoOstuni 0:75fc82583a41 1802 ppsReq.PPS0 = RFAL_ISODEP_PPS_PPS0_PPS1_PRESENT;
DiegoOstuni 0:75fc82583a41 1803 ppsReq.PPS1 = (RFAL_ISODEP_PPS_PPS1 | (((DSI<<RFAL_ISODEP_PPS_PPS1_DSI_SHIFT)|DRI) & RFAL_ISODEP_PPS_PPS1_DXI_MASK));
DiegoOstuni 0:75fc82583a41 1804
DiegoOstuni 0:75fc82583a41 1805 ret = rfalTransceiveBlockingTxRx( (uint8_t*)&ppsReq, sizeof(rfalIsoDepPpsReq), (uint8_t*)ppsRes, sizeof(rfalIsoDepPpsRes), &rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_ISODEP_T4T_FWT_ACTIVATION, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1806
DiegoOstuni 0:75fc82583a41 1807 if( ret == ERR_NONE )
DiegoOstuni 0:75fc82583a41 1808 {
DiegoOstuni 0:75fc82583a41 1809 /* Check for valid PPS Response */
DiegoOstuni 0:75fc82583a41 1810 if( (rcvLen != RFAL_ISODEP_PPS_RES_LEN) || (ppsRes->PPSS != ppsReq.PPSS) )
DiegoOstuni 0:75fc82583a41 1811 {
DiegoOstuni 0:75fc82583a41 1812 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 1813 }
DiegoOstuni 0:75fc82583a41 1814 }
DiegoOstuni 0:75fc82583a41 1815 return ret;
DiegoOstuni 0:75fc82583a41 1816 }
DiegoOstuni 0:75fc82583a41 1817
DiegoOstuni 0:75fc82583a41 1818
DiegoOstuni 0:75fc82583a41 1819 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1820 ReturnCode rfalIsoDepATTRIB( uint8_t* nfcid0, uint8_t PARAM1, rfalBitRate DSI, rfalBitRate DRI, rfalIsoDepFSxI FSDI, uint8_t PARAM3, uint8_t DID, uint8_t* HLInfo, uint8_t HLInfoLen, uint32_t fwt, rfalIsoDepAttribRes *attribRes, uint8_t *attribResLen, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1821 {
DiegoOstuni 0:75fc82583a41 1822 uint16_t rcvLen;
DiegoOstuni 0:75fc82583a41 1823 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 1824 rfalIsoDepAttribCmd attribCmd;
DiegoOstuni 0:75fc82583a41 1825
DiegoOstuni 0:75fc82583a41 1826
DiegoOstuni 0:75fc82583a41 1827 if( (attribRes == NULL) || (attribResLen == NULL) || (DSI > RFAL_BR_848) || (DRI > RFAL_BR_848) || (DID > RFAL_ISODEP_DID_MAX) )
DiegoOstuni 0:75fc82583a41 1828 {
DiegoOstuni 0:75fc82583a41 1829 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 1830 }
DiegoOstuni 0:75fc82583a41 1831
DiegoOstuni 0:75fc82583a41 1832 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1833 /* Compose ATTRIB command */
DiegoOstuni 0:75fc82583a41 1834 attribCmd.cmd = RFAL_ISODEP_CMD_ATTRIB;
DiegoOstuni 0:75fc82583a41 1835 attribCmd.Param.PARAM1 = PARAM1;
DiegoOstuni 0:75fc82583a41 1836 attribCmd.Param.PARAM2 = ( (((DSI<<RFAL_ISODEP_ATTRIB_PARAM2_DSI_SHIFT) | (DRI<<RFAL_ISODEP_ATTRIB_PARAM2_DRI_SHIFT)) & RFAL_ISODEP_ATTRIB_PARAM2_DXI_MASK) | (FSDI & RFAL_ISODEP_ATTRIB_PARAM2_FSDI_MASK) );
DiegoOstuni 0:75fc82583a41 1837 attribCmd.Param.PARAM3 = PARAM3;
DiegoOstuni 0:75fc82583a41 1838 attribCmd.Param.PARAM4 = (DID & RFAL_ISODEP_ATTRIB_PARAM4_DID_MASK);
DiegoOstuni 0:75fc82583a41 1839 ST_MEMCPY(attribCmd.nfcid0, nfcid0, RFAL_NFCB_NFCID0_LEN);
DiegoOstuni 0:75fc82583a41 1840
DiegoOstuni 0:75fc82583a41 1841 /* Append the Higher layer Info if provided */
DiegoOstuni 0:75fc82583a41 1842 if( (HLInfo != NULL) && (HLInfoLen > 0) )
DiegoOstuni 0:75fc82583a41 1843 {
DiegoOstuni 0:75fc82583a41 1844 ST_MEMCPY(attribCmd.HLInfo, HLInfo, MIN(HLInfoLen, RFAL_ISODEP_ATTRIB_HLINFO_LEN) );
DiegoOstuni 0:75fc82583a41 1845 }
DiegoOstuni 0:75fc82583a41 1846
DiegoOstuni 0:75fc82583a41 1847 ret = rfalTransceiveBlockingTxRx( (uint8_t*)&attribCmd, (RFAL_ISODEP_ATTRIB_HDR_LEN + MIN(HLInfoLen, RFAL_ISODEP_ATTRIB_HLINFO_LEN)), (uint8_t*)attribRes, sizeof(rfalIsoDepAttribRes), &rcvLen, RFAL_TXRX_FLAGS_DEFAULT, fwt, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1848
DiegoOstuni 0:75fc82583a41 1849 *attribResLen = (uint8_t)rcvLen;
DiegoOstuni 0:75fc82583a41 1850
DiegoOstuni 0:75fc82583a41 1851 if( ret == ERR_NONE )
DiegoOstuni 0:75fc82583a41 1852 {
DiegoOstuni 0:75fc82583a41 1853 /* Check a for valid ATTRIB Response Digital 1.1 15.6.2.1 */
DiegoOstuni 0:75fc82583a41 1854 if( (rcvLen < RFAL_ISODEP_ATTRIB_RES_HDR_LEN) || ((attribRes->mbliDid & RFAL_ISODEP_ATTRIB_RES_DID_MASK) != DID) )
DiegoOstuni 0:75fc82583a41 1855 {
DiegoOstuni 0:75fc82583a41 1856 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 1857 }
DiegoOstuni 0:75fc82583a41 1858 }
DiegoOstuni 0:75fc82583a41 1859
DiegoOstuni 0:75fc82583a41 1860 return ret;
DiegoOstuni 0:75fc82583a41 1861 }
DiegoOstuni 0:75fc82583a41 1862
DiegoOstuni 0:75fc82583a41 1863
DiegoOstuni 0:75fc82583a41 1864 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1865 ReturnCode rfalIsoDepPollAHandleActivation( rfalIsoDepFSxI FSDI, uint8_t DID, rfalBitRate maxBR, rfalIsoDepDevice *isoDepDev, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 1866 {
DiegoOstuni 0:75fc82583a41 1867 uint8_t RATSretries;
DiegoOstuni 0:75fc82583a41 1868 uint8_t msgIt;
DiegoOstuni 0:75fc82583a41 1869 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 1870 rfalIsoDepPpsRes ppsRes;
DiegoOstuni 0:75fc82583a41 1871
DiegoOstuni 0:75fc82583a41 1872 if( isoDepDev == NULL )
DiegoOstuni 0:75fc82583a41 1873 {
DiegoOstuni 0:75fc82583a41 1874 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 1875 }
DiegoOstuni 0:75fc82583a41 1876
DiegoOstuni 0:75fc82583a41 1877 /* Enable EMD handling according Digital 1.1 4.1.1.1 ; EMVCo 2.6 4.9.2 */
DiegoOstuni 0:75fc82583a41 1878 rfalSetErrorHandling( RFAL_ERRORHANDLING_EMVCO );
DiegoOstuni 0:75fc82583a41 1879
DiegoOstuni 0:75fc82583a41 1880 RATSretries = gIsoDep.maxRetriesRATS;
DiegoOstuni 0:75fc82583a41 1881
DiegoOstuni 0:75fc82583a41 1882 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 1883 /* Send RATS */
DiegoOstuni 0:75fc82583a41 1884 do
DiegoOstuni 0:75fc82583a41 1885 {
DiegoOstuni 0:75fc82583a41 1886 /* Digital 1.1 13.7.1.1 and ISO 14443-4 5.6.1.1 - Upon a failed RATS it may be retransmited [0,1] */
DiegoOstuni 0:75fc82583a41 1887 ret = rfalIsoDepRATS( FSDI, DID, &isoDepDev->activation.A.Listener.ATS, &isoDepDev->activation.A.Listener.ATSLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1888
DiegoOstuni 0:75fc82583a41 1889 /* EMVCo 2.6 9.6.1.1 & 9.6.1.2 If a timeout error is detected retransmit, on transmission error abort */
DiegoOstuni 0:75fc82583a41 1890 if( (gIsoDep.compMode == RFAL_COMPLIANCE_MODE_EMV) && (ret != ERR_NONE) && (ret != ERR_TIMEOUT) )
DiegoOstuni 0:75fc82583a41 1891 {
DiegoOstuni 0:75fc82583a41 1892 break;
DiegoOstuni 0:75fc82583a41 1893 }
DiegoOstuni 0:75fc82583a41 1894
DiegoOstuni 0:75fc82583a41 1895 platformDelay(1);
DiegoOstuni 0:75fc82583a41 1896 }
DiegoOstuni 0:75fc82583a41 1897 while( (RATSretries--) && (ret != ERR_NONE) );
DiegoOstuni 0:75fc82583a41 1898
DiegoOstuni 0:75fc82583a41 1899
DiegoOstuni 0:75fc82583a41 1900
DiegoOstuni 0:75fc82583a41 1901 /* Switch between NFC Forum and ISO14443-4 behaviour #595
DiegoOstuni 0:75fc82583a41 1902 * ISO14443-4 5.6.1 If RATS fails, a Deactivation sequence should be performed as defined on clause 8
DiegoOstuni 0:75fc82583a41 1903 * Activity 1.1 9.6 Device Deactivation Activity is to be only performed when there's an active device */
DiegoOstuni 0:75fc82583a41 1904 if( ret != ERR_NONE )
DiegoOstuni 0:75fc82583a41 1905 {
DiegoOstuni 0:75fc82583a41 1906 if( gIsoDep.compMode == RFAL_COMPLIANCE_MODE_ISO )
DiegoOstuni 0:75fc82583a41 1907 {
DiegoOstuni 0:75fc82583a41 1908 rfalIsoDepDeselect( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1909 }
DiegoOstuni 0:75fc82583a41 1910 return ret;
DiegoOstuni 0:75fc82583a41 1911 }
DiegoOstuni 0:75fc82583a41 1912
DiegoOstuni 0:75fc82583a41 1913 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1914 /* Process ATS Response */
DiegoOstuni 0:75fc82583a41 1915 isoDepDev->info.FWI = RFAL_ISODEP_FWI_DEFAULT; /* Default value EMVCo 2.6 5.7.2.6 */
DiegoOstuni 0:75fc82583a41 1916 isoDepDev->info.SFGI = 0;
DiegoOstuni 0:75fc82583a41 1917 isoDepDev->info.MBL = 0;
DiegoOstuni 0:75fc82583a41 1918 isoDepDev->info.DSI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1919 isoDepDev->info.DRI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1920 isoDepDev->info.FSxI = RFAL_ISODEP_FSXI_32; /* FSC default value is 32 bytes ISO14443-A 5.2.3 */
DiegoOstuni 0:75fc82583a41 1921
DiegoOstuni 0:75fc82583a41 1922
DiegoOstuni 0:75fc82583a41 1923 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1924 /* Check for ATS optional fields */
DiegoOstuni 0:75fc82583a41 1925 if( isoDepDev->activation.A.Listener.ATS.TL > RFAL_ISODEP_ATS_MIN_LEN )
DiegoOstuni 0:75fc82583a41 1926 {
DiegoOstuni 0:75fc82583a41 1927 msgIt = RFAL_ISODEP_ATS_MIN_LEN;
DiegoOstuni 0:75fc82583a41 1928
DiegoOstuni 0:75fc82583a41 1929 /* Format byte T0 is optional, if present assign FSDI */
DiegoOstuni 0:75fc82583a41 1930 isoDepDev->info.FSxI = (isoDepDev->activation.A.Listener.ATS.T0 & RFAL_ISODEP_ATS_T0_FSCI_MASK);
DiegoOstuni 0:75fc82583a41 1931
DiegoOstuni 0:75fc82583a41 1932 /* T0 has already been processed, always the same position */
DiegoOstuni 0:75fc82583a41 1933 msgIt++;
DiegoOstuni 0:75fc82583a41 1934
DiegoOstuni 0:75fc82583a41 1935 /* Check if TA is present */
DiegoOstuni 0:75fc82583a41 1936 if( isoDepDev->activation.A.Listener.ATS.T0 & RFAL_ISODEP_ATS_T0_TA_PRESENCE_MASK )
DiegoOstuni 0:75fc82583a41 1937 {
DiegoOstuni 0:75fc82583a41 1938 rfalIsoDepCalcBitRate( maxBR, *((uint8_t*)&isoDepDev->activation.A.Listener.ATS + msgIt++), &isoDepDev->info.DSI, &isoDepDev->info.DRI );
DiegoOstuni 0:75fc82583a41 1939 }
DiegoOstuni 0:75fc82583a41 1940
DiegoOstuni 0:75fc82583a41 1941 /* Check if TB is present */
DiegoOstuni 0:75fc82583a41 1942 if( isoDepDev->activation.A.Listener.ATS.T0 & RFAL_ISODEP_ATS_T0_TB_PRESENCE_MASK )
DiegoOstuni 0:75fc82583a41 1943 {
DiegoOstuni 0:75fc82583a41 1944 isoDepDev->info.SFGI = *((uint8_t*)&isoDepDev->activation.A.Listener.ATS + msgIt++);
DiegoOstuni 0:75fc82583a41 1945 isoDepDev->info.FWI = ((isoDepDev->info.SFGI >> RFAL_ISODEP_ATS_TB_FWI_SHIFT) & RFAL_ISODEP_ATS_FWI_MASK);
DiegoOstuni 0:75fc82583a41 1946 isoDepDev->info.SFGI &= RFAL_ISODEP_ATS_TB_SFGI_MASK;
DiegoOstuni 0:75fc82583a41 1947 }
DiegoOstuni 0:75fc82583a41 1948
DiegoOstuni 0:75fc82583a41 1949 /* Check if TC is present */
DiegoOstuni 0:75fc82583a41 1950 if( isoDepDev->activation.A.Listener.ATS.T0 & RFAL_ISODEP_ATS_T0_TC_PRESENCE_MASK )
DiegoOstuni 0:75fc82583a41 1951 {
DiegoOstuni 0:75fc82583a41 1952 /* Check for Protocol features support */
DiegoOstuni 0:75fc82583a41 1953 /* Advanced protocol features defined on Digital 1.0 Table 69, removed after */
DiegoOstuni 0:75fc82583a41 1954 isoDepDev->info.supAdFt = ((*((uint8_t*)&isoDepDev->activation.A.Listener.ATS + msgIt) & RFAL_ISODEP_ATS_TC_ADV_FEAT) ? true : false);
DiegoOstuni 0:75fc82583a41 1955 isoDepDev->info.supDID = ((*((uint8_t*)&isoDepDev->activation.A.Listener.ATS + msgIt) & RFAL_ISODEP_ATS_TC_DID) ? true : false);
DiegoOstuni 0:75fc82583a41 1956 isoDepDev->info.supNAD = ((*((uint8_t*)&isoDepDev->activation.A.Listener.ATS + msgIt++) & RFAL_ISODEP_ATS_TC_NAD) ? true : false);
DiegoOstuni 0:75fc82583a41 1957 }
DiegoOstuni 0:75fc82583a41 1958 }
DiegoOstuni 0:75fc82583a41 1959
DiegoOstuni 0:75fc82583a41 1960 isoDepDev->info.FSx = rfalIsoDepFSxI2FSx(isoDepDev->info.FSxI);
DiegoOstuni 0:75fc82583a41 1961
DiegoOstuni 0:75fc82583a41 1962 isoDepDev->info.SFGT = rfalIsoDepSFGI2SFGT( isoDepDev->info.SFGI );
DiegoOstuni 0:75fc82583a41 1963 isoDepTimerStart( gIsoDep.SFGTTimer, isoDepDev->info.SFGT );
DiegoOstuni 0:75fc82583a41 1964
DiegoOstuni 0:75fc82583a41 1965 isoDepDev->info.FWT = rfalIsoDepFWI2FWT( isoDepDev->info.FWI );
DiegoOstuni 0:75fc82583a41 1966 isoDepDev->info.dFWT = RFAL_ISODEP_DFWT_10;
DiegoOstuni 0:75fc82583a41 1967
DiegoOstuni 0:75fc82583a41 1968 isoDepDev->info.DID = ( (isoDepDev->info.supDID) ? DID : RFAL_ISODEP_NO_DID);
DiegoOstuni 0:75fc82583a41 1969 isoDepDev->info.NAD = RFAL_ISODEP_NO_NAD;
DiegoOstuni 0:75fc82583a41 1970
DiegoOstuni 0:75fc82583a41 1971
DiegoOstuni 0:75fc82583a41 1972 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1973 /* If higher bit rates are supported by both devices, send PPS */
DiegoOstuni 0:75fc82583a41 1974 if( (isoDepDev->info.DSI != RFAL_BR_106) || (isoDepDev->info.DRI != RFAL_BR_106) )
DiegoOstuni 0:75fc82583a41 1975 {
DiegoOstuni 0:75fc82583a41 1976 /* Wait until SFGT has been fulfilled */
DiegoOstuni 0:75fc82583a41 1977 while( !isoDepTimerisExpired( gIsoDep.SFGTTimer ) );
DiegoOstuni 0:75fc82583a41 1978
DiegoOstuni 0:75fc82583a41 1979 ret = rfalIsoDepPPS( isoDepDev->info.DID, isoDepDev->info.DSI, isoDepDev->info.DRI, &ppsRes, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1980
DiegoOstuni 0:75fc82583a41 1981 if( ret == ERR_NONE )
DiegoOstuni 0:75fc82583a41 1982 {
DiegoOstuni 0:75fc82583a41 1983 /* DSI code the divisor from PICC to PCD */
DiegoOstuni 0:75fc82583a41 1984 /* DRI code the divisor from PCD to PICC */
DiegoOstuni 0:75fc82583a41 1985 rfalSetBitRate( isoDepDev->info.DRI, isoDepDev->info.DSI, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 1986 }
DiegoOstuni 0:75fc82583a41 1987 else
DiegoOstuni 0:75fc82583a41 1988 {
DiegoOstuni 0:75fc82583a41 1989 isoDepDev->info.DSI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1990 isoDepDev->info.DRI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 1991 }
DiegoOstuni 0:75fc82583a41 1992 }
DiegoOstuni 0:75fc82583a41 1993
DiegoOstuni 0:75fc82583a41 1994 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 1995 /* Store already FS info, rfalIsoDepGetMaxInfLen() may be called before setting TxRx params */
DiegoOstuni 0:75fc82583a41 1996 gIsoDep.fsx = isoDepDev->info.FSx;
DiegoOstuni 0:75fc82583a41 1997 gIsoDep.ourFsx = rfalIsoDepFSxI2FSx( FSDI );
DiegoOstuni 0:75fc82583a41 1998
DiegoOstuni 0:75fc82583a41 1999 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 2000 }
DiegoOstuni 0:75fc82583a41 2001
DiegoOstuni 0:75fc82583a41 2002
DiegoOstuni 0:75fc82583a41 2003 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2004 ReturnCode rfalIsoDepPollBHandleActivation( rfalIsoDepFSxI FSDI, uint8_t DID, rfalBitRate maxBR, uint8_t PARAM1, rfalNfcbListenDevice *nfcbDev, uint8_t* HLInfo, uint8_t HLInfoLen, rfalIsoDepDevice *isoDepDev, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 2005 {
DiegoOstuni 0:75fc82583a41 2006 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 2007 uint8_t mlbi;
DiegoOstuni 0:75fc82583a41 2008
DiegoOstuni 0:75fc82583a41 2009 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2010 /* Initialize ISO-DEP Device with info from SENSB_RES */
DiegoOstuni 0:75fc82583a41 2011 isoDepDev->info.FWI = ((nfcbDev->sensbRes.protInfo.FwiAdcFo >> RFAL_NFCB_SENSB_RES_FWI_SHIFT) & RFAL_NFCB_SENSB_RES_FWI_MASK);
DiegoOstuni 0:75fc82583a41 2012 isoDepDev->info.FWT = rfalIsoDepFWI2FWT( isoDepDev->info.FWI );
DiegoOstuni 0:75fc82583a41 2013 isoDepDev->info.dFWT = RFAL_NFCB_DFWT_10;
DiegoOstuni 0:75fc82583a41 2014 isoDepDev->info.SFGI = ((nfcbDev->sensbRes.protInfo.SFGI >> RFAL_NFCB_SENSB_RES_SFGI_SHIFT) & RFAL_NFCB_SENSB_RES_SFGI_MASK);
DiegoOstuni 0:75fc82583a41 2015 isoDepDev->info.SFGT = rfalIsoDepSFGI2SFGT( isoDepDev->info.SFGI );
DiegoOstuni 0:75fc82583a41 2016 isoDepDev->info.FSxI = ((nfcbDev->sensbRes.protInfo.FsciProType >> RFAL_NFCB_SENSB_RES_FSCI_SHIFT) & RFAL_NFCB_SENSB_RES_FSCI_MASK);
DiegoOstuni 0:75fc82583a41 2017 isoDepDev->info.FSx = rfalIsoDepFSxI2FSx(isoDepDev->info.FSxI);
DiegoOstuni 0:75fc82583a41 2018 isoDepDev->info.DID = DID;
DiegoOstuni 0:75fc82583a41 2019 isoDepDev->info.supDID = (( nfcbDev->sensbRes.protInfo.FwiAdcFo & RFAL_NFCB_SENSB_RES_FO_DID_MASK ) ? true : false);
DiegoOstuni 0:75fc82583a41 2020 isoDepDev->info.supNAD = (( nfcbDev->sensbRes.protInfo.FwiAdcFo & RFAL_NFCB_SENSB_RES_FO_NAD_MASK ) ? true : false);
DiegoOstuni 0:75fc82583a41 2021
DiegoOstuni 0:75fc82583a41 2022
DiegoOstuni 0:75fc82583a41 2023 /* Check if DID requested is supported by PICC */
DiegoOstuni 0:75fc82583a41 2024 if( (DID != RFAL_ISODEP_NO_DID) && (!isoDepDev->info.supDID) )
DiegoOstuni 0:75fc82583a41 2025 {
DiegoOstuni 0:75fc82583a41 2026 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 2027 }
DiegoOstuni 0:75fc82583a41 2028
DiegoOstuni 0:75fc82583a41 2029 /* Enable EMD handling according Digital 1.1 4.1.1.1 ; EMVCo 2.6 4.9.2 */
DiegoOstuni 0:75fc82583a41 2030 rfalSetErrorHandling( RFAL_ERRORHANDLING_EMVCO );
DiegoOstuni 0:75fc82583a41 2031
DiegoOstuni 0:75fc82583a41 2032 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2033 /* Apply minimum TR2 from SENSB_RES */
DiegoOstuni 0:75fc82583a41 2034 rfalSetFDTPoll( rfalNfcbTR2ToFDT(((nfcbDev->sensbRes.protInfo.FsciProType >>RFAL_NFCB_SENSB_RES_PROTO_TR2_SHIFT) & RFAL_NFCB_SENSB_RES_PROTO_TR2_MASK)) );
DiegoOstuni 0:75fc82583a41 2035
DiegoOstuni 0:75fc82583a41 2036
DiegoOstuni 0:75fc82583a41 2037 /* Calculate max Bit Rate */
DiegoOstuni 0:75fc82583a41 2038 rfalIsoDepCalcBitRate( maxBR, nfcbDev->sensbRes.protInfo.BRC, &isoDepDev->info.DSI, &isoDepDev->info.DRI );
DiegoOstuni 0:75fc82583a41 2039
DiegoOstuni 0:75fc82583a41 2040 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2041 /* Send ATTRIB Command */
DiegoOstuni 0:75fc82583a41 2042 ret = rfalIsoDepATTRIB( (uint8_t*)&nfcbDev->sensbRes.nfcid0,
DiegoOstuni 0:75fc82583a41 2043 ((nfcbDev->sensbRes.protInfo.FwiAdcFo & RFAL_NFCB_SENSB_RES_ADC_ADV_FEATURE_MASK) ? PARAM1 : RFAL_ISODEP_ATTRIB_REQ_PARAM1_DEFAULT),
DiegoOstuni 0:75fc82583a41 2044 isoDepDev->info.DSI,
DiegoOstuni 0:75fc82583a41 2045 isoDepDev->info.DRI,
DiegoOstuni 0:75fc82583a41 2046 FSDI,
DiegoOstuni 0:75fc82583a41 2047 (gIsoDep.compMode == RFAL_COMPLIANCE_MODE_EMV) ? RFAL_NFCB_SENSB_RES_PROTO_ISO_MASK : (nfcbDev->sensbRes.protInfo.FsciProType & ( (RFAL_NFCB_SENSB_RES_PROTO_TR2_MASK<<RFAL_NFCB_SENSB_RES_PROTO_TR2_SHIFT) | RFAL_NFCB_SENSB_RES_PROTO_ISO_MASK)), /* EMVCo 2.6 6.4.1.9 */
DiegoOstuni 0:75fc82583a41 2048 DID,
DiegoOstuni 0:75fc82583a41 2049 HLInfo,
DiegoOstuni 0:75fc82583a41 2050 HLInfoLen,
DiegoOstuni 0:75fc82583a41 2051 (isoDepDev->info.FWT + isoDepDev->info.dFWT),
DiegoOstuni 0:75fc82583a41 2052 &isoDepDev->activation.B.Listener.ATTRIB_RES,
DiegoOstuni 0:75fc82583a41 2053 &isoDepDev->activation.B.Listener.ATTRIB_RESLen, mspiChannel, mST25, gpio_cs, IRQ,
DiegoOstuni 0:75fc82583a41 2054 fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06
DiegoOstuni 0:75fc82583a41 2055 );
DiegoOstuni 0:75fc82583a41 2056
DiegoOstuni 0:75fc82583a41 2057 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2058 /* Process ATTRIB Response */
DiegoOstuni 0:75fc82583a41 2059 if( ret == ERR_NONE )
DiegoOstuni 0:75fc82583a41 2060 {
DiegoOstuni 0:75fc82583a41 2061 /* Digital 1.1 14.6.2.3 - Check if received DID match */
DiegoOstuni 0:75fc82583a41 2062 if( (isoDepDev->activation.B.Listener.ATTRIB_RES.mbliDid & RFAL_ISODEP_ATTRIB_RES_DID_MASK) != DID )
DiegoOstuni 0:75fc82583a41 2063 {
DiegoOstuni 0:75fc82583a41 2064 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 2065 }
DiegoOstuni 0:75fc82583a41 2066
DiegoOstuni 0:75fc82583a41 2067 /* Retrieve MBLI and calculate new FDS/MBL (Maximum Buffer Length) */
DiegoOstuni 0:75fc82583a41 2068 mlbi = ((isoDepDev->activation.B.Listener.ATTRIB_RES.mbliDid >> RFAL_ISODEP_ATTRIB_RES_MLBI_SHIFT) & RFAL_ISODEP_ATTRIB_RES_MLBI_MASK);
DiegoOstuni 0:75fc82583a41 2069 if( mlbi > 0)
DiegoOstuni 0:75fc82583a41 2070 {
DiegoOstuni 0:75fc82583a41 2071 /* Digital 1.1 14.6.2 Calculate Maximum Buffer Length MBL = FSC × 2^(MBLI-1) */
DiegoOstuni 0:75fc82583a41 2072 isoDepDev->info.MBL = (isoDepDev->info.FSx * (1<<(mlbi-1)));
DiegoOstuni 0:75fc82583a41 2073 }
DiegoOstuni 0:75fc82583a41 2074
DiegoOstuni 0:75fc82583a41 2075 /* DSI code the divisor from PICC to PCD */
DiegoOstuni 0:75fc82583a41 2076 /* DRI code the divisor from PCD to PICC */
DiegoOstuni 0:75fc82583a41 2077 rfalSetBitRate( isoDepDev->info.DRI, isoDepDev->info.DSI, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 2078
DiegoOstuni 0:75fc82583a41 2079
DiegoOstuni 0:75fc82583a41 2080 if( (nfcbDev->sensbRes.protInfo.FwiAdcFo & RFAL_NFCB_SENSB_RES_ADC_ADV_FEATURE_MASK) )
DiegoOstuni 0:75fc82583a41 2081 {
DiegoOstuni 0:75fc82583a41 2082 /* REMARK: SoF EoF TR0 and TR1 are not passed on to RF layer */
DiegoOstuni 0:75fc82583a41 2083 }
DiegoOstuni 0:75fc82583a41 2084
DiegoOstuni 0:75fc82583a41 2085 /* Start the SFGT timer */
DiegoOstuni 0:75fc82583a41 2086 isoDepTimerStart( gIsoDep.SFGTTimer, isoDepDev->info.SFGT );
DiegoOstuni 0:75fc82583a41 2087 }
DiegoOstuni 0:75fc82583a41 2088 else
DiegoOstuni 0:75fc82583a41 2089 {
DiegoOstuni 0:75fc82583a41 2090 isoDepDev->info.DSI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 2091 isoDepDev->info.DRI = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 2092 }
DiegoOstuni 0:75fc82583a41 2093
DiegoOstuni 0:75fc82583a41 2094 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2095 /* Store already FS info, rfalIsoDepGetMaxInfLen() may be called before setting TxRx params */
DiegoOstuni 0:75fc82583a41 2096 gIsoDep.fsx = isoDepDev->info.FSx;
DiegoOstuni 0:75fc82583a41 2097 gIsoDep.ourFsx = rfalIsoDepFSxI2FSx( FSDI );
DiegoOstuni 0:75fc82583a41 2098
DiegoOstuni 0:75fc82583a41 2099 return ret;
DiegoOstuni 0:75fc82583a41 2100 }
DiegoOstuni 0:75fc82583a41 2101
DiegoOstuni 0:75fc82583a41 2102
DiegoOstuni 0:75fc82583a41 2103 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2104 static void rfalIsoDepCalcBitRate( rfalBitRate maxAllowedBR, uint8_t piccBRCapability, rfalBitRate *dsi, rfalBitRate *dri )
DiegoOstuni 0:75fc82583a41 2105 {
DiegoOstuni 0:75fc82583a41 2106 uint8_t driMask;
DiegoOstuni 0:75fc82583a41 2107 uint8_t dsiMask;
DiegoOstuni 0:75fc82583a41 2108 uint8_t bitrateFound;
DiegoOstuni 0:75fc82583a41 2109 int8_t i;
DiegoOstuni 0:75fc82583a41 2110
DiegoOstuni 0:75fc82583a41 2111 do
DiegoOstuni 0:75fc82583a41 2112 {
DiegoOstuni 0:75fc82583a41 2113 bitrateFound = true;
DiegoOstuni 0:75fc82583a41 2114
DiegoOstuni 0:75fc82583a41 2115 (*dsi) = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 2116 (*dri) = RFAL_BR_106;
DiegoOstuni 0:75fc82583a41 2117
DiegoOstuni 0:75fc82583a41 2118 /* Digital 1.0 5.6.2.5 & 11.6.2.14: A received RFU value of b4 = 1b MUST be interpreted as if b7 to b1 ? 0000000b (only 106 kbits/s in both direction) */
DiegoOstuni 0:75fc82583a41 2119 if( (RFAL_ISODEP_BITRATE_RFU_MASK & piccBRCapability) )
DiegoOstuni 0:75fc82583a41 2120 {
DiegoOstuni 0:75fc82583a41 2121 return;
DiegoOstuni 0:75fc82583a41 2122 }
DiegoOstuni 0:75fc82583a41 2123
DiegoOstuni 0:75fc82583a41 2124 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2125 /* Determine Listen->Poll bit rate */
DiegoOstuni 0:75fc82583a41 2126 dsiMask = (piccBRCapability & RFAL_ISODEP_BSI_MASK);
DiegoOstuni 0:75fc82583a41 2127 for( i = 2; i >= 0; i-- ) /* Check supported bit rate from the highest */
DiegoOstuni 0:75fc82583a41 2128 {
DiegoOstuni 0:75fc82583a41 2129 if ((dsiMask & (0x10 << i)) && (((rfalBitRate)(i+1)) <= maxAllowedBR))
DiegoOstuni 0:75fc82583a41 2130 {
DiegoOstuni 0:75fc82583a41 2131 (*dsi) = ((rfalBitRate)(i+1));
DiegoOstuni 0:75fc82583a41 2132 break;
DiegoOstuni 0:75fc82583a41 2133 }
DiegoOstuni 0:75fc82583a41 2134 }
DiegoOstuni 0:75fc82583a41 2135
DiegoOstuni 0:75fc82583a41 2136 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2137 /* Determine Poll->Listen bit rate */
DiegoOstuni 0:75fc82583a41 2138 driMask = (piccBRCapability & RFAL_ISODEP_BRI_MASK);
DiegoOstuni 0:75fc82583a41 2139 for( i = 2; i >= 0; i-- ) /* Check supported bit rate from the highest */
DiegoOstuni 0:75fc82583a41 2140 {
DiegoOstuni 0:75fc82583a41 2141 if ((driMask & (0x01 << i)) && (((rfalBitRate)(i+1)) <= maxAllowedBR))
DiegoOstuni 0:75fc82583a41 2142 {
DiegoOstuni 0:75fc82583a41 2143 (*dri) = ((rfalBitRate)(i+1));
DiegoOstuni 0:75fc82583a41 2144 break;
DiegoOstuni 0:75fc82583a41 2145 }
DiegoOstuni 0:75fc82583a41 2146 }
DiegoOstuni 0:75fc82583a41 2147
DiegoOstuni 0:75fc82583a41 2148 /***************************************************************************/
DiegoOstuni 0:75fc82583a41 2149 /* Check if different bit rate is supported */
DiegoOstuni 0:75fc82583a41 2150
DiegoOstuni 0:75fc82583a41 2151 /* Digital 1.0 Table 67: if b8=1b, then only the same bit rate divisor for both directions is supported */
DiegoOstuni 0:75fc82583a41 2152 if( piccBRCapability & RFAL_ISODEP_SAME_BITRATE_MASK )
DiegoOstuni 0:75fc82583a41 2153 {
DiegoOstuni 0:75fc82583a41 2154 (*dsi) = MIN((*dsi), (*dri));
DiegoOstuni 0:75fc82583a41 2155 (*dri) = (*dsi);
DiegoOstuni 0:75fc82583a41 2156 /* Check that the baudrate is supported */
DiegoOstuni 0:75fc82583a41 2157 if( (RFAL_BR_106 != (*dsi)) && ( !((dsiMask & (0x10 << ((*dsi) - 1))) &&(driMask & (0x01 << ((*dri) - 1)))) ) )
DiegoOstuni 0:75fc82583a41 2158 {
DiegoOstuni 0:75fc82583a41 2159 bitrateFound = false;
DiegoOstuni 0:75fc82583a41 2160 maxAllowedBR = (*dsi); /* set allowed bitrate to be lowest and determine bit rate again */
DiegoOstuni 0:75fc82583a41 2161 }
DiegoOstuni 0:75fc82583a41 2162 }
DiegoOstuni 0:75fc82583a41 2163 } while (!(bitrateFound));
DiegoOstuni 0:75fc82583a41 2164
DiegoOstuni 0:75fc82583a41 2165 }
DiegoOstuni 0:75fc82583a41 2166
DiegoOstuni 0:75fc82583a41 2167
DiegoOstuni 0:75fc82583a41 2168 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2169 static void rfalIsoDepApdu2IBLockParam( rfalIsoDepApduTxRxParam apduParam, rfalIsoDepTxRxParam *iBlockParam, uint16_t txPos, uint16_t rxPos )
DiegoOstuni 0:75fc82583a41 2170 {
DiegoOstuni 0:75fc82583a41 2171 NO_WARNING(rxPos); /* Keep this param for future use */
DiegoOstuni 0:75fc82583a41 2172
DiegoOstuni 0:75fc82583a41 2173 iBlockParam->DID = apduParam.DID;
DiegoOstuni 0:75fc82583a41 2174 iBlockParam->FSx = apduParam.FSx;
DiegoOstuni 0:75fc82583a41 2175 iBlockParam->ourFSx = apduParam.ourFSx;
DiegoOstuni 0:75fc82583a41 2176 iBlockParam->FWT = apduParam.FWT;
DiegoOstuni 0:75fc82583a41 2177 iBlockParam->dFWT = apduParam.dFWT;
DiegoOstuni 0:75fc82583a41 2178
DiegoOstuni 0:75fc82583a41 2179 if( (apduParam.txBufLen - txPos) > rfalIsoDepGetMaxInfLen() )
DiegoOstuni 0:75fc82583a41 2180 {
DiegoOstuni 0:75fc82583a41 2181 iBlockParam->isTxChaining = true;
DiegoOstuni 0:75fc82583a41 2182 iBlockParam->txBufLen = rfalIsoDepGetMaxInfLen();
DiegoOstuni 0:75fc82583a41 2183 }
DiegoOstuni 0:75fc82583a41 2184 else
DiegoOstuni 0:75fc82583a41 2185 {
DiegoOstuni 0:75fc82583a41 2186 iBlockParam->isTxChaining = false;
DiegoOstuni 0:75fc82583a41 2187 iBlockParam->txBufLen = (apduParam.txBufLen - txPos);
DiegoOstuni 0:75fc82583a41 2188 }
DiegoOstuni 0:75fc82583a41 2189
DiegoOstuni 0:75fc82583a41 2190 /* TxBuf is moved to the beginning for every I-Block */
DiegoOstuni 0:75fc82583a41 2191 iBlockParam->txBuf = (rfalIsoDepBufFormat*)apduParam.txBuf;
DiegoOstuni 0:75fc82583a41 2192 iBlockParam->rxBuf = apduParam.tmpBuf; /* Simply using the apdu buffer is not possible because of current ACK handling */
DiegoOstuni 0:75fc82583a41 2193 iBlockParam->isRxChaining = &gIsoDep.isAPDURxChaining;
DiegoOstuni 0:75fc82583a41 2194 iBlockParam->rxLen = apduParam.rxLen;
DiegoOstuni 0:75fc82583a41 2195 }
DiegoOstuni 0:75fc82583a41 2196
DiegoOstuni 0:75fc82583a41 2197
DiegoOstuni 0:75fc82583a41 2198 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2199 ReturnCode rfalIsoDepStartApduTransceive( rfalIsoDepApduTxRxParam param )
DiegoOstuni 0:75fc82583a41 2200 {
DiegoOstuni 0:75fc82583a41 2201 rfalIsoDepTxRxParam txRxParam;
DiegoOstuni 0:75fc82583a41 2202
DiegoOstuni 0:75fc82583a41 2203 /* Initialize and store APDU context */
DiegoOstuni 0:75fc82583a41 2204 gIsoDep.APDUParam = param;
DiegoOstuni 0:75fc82583a41 2205 gIsoDep.APDUTxPos = 0;
DiegoOstuni 0:75fc82583a41 2206 gIsoDep.APDURxPos = 0;
DiegoOstuni 0:75fc82583a41 2207
DiegoOstuni 0:75fc82583a41 2208 /* Assign current FSx to calculate INF length */
DiegoOstuni 0:75fc82583a41 2209 gIsoDep.ourFsx = param.ourFSx;
DiegoOstuni 0:75fc82583a41 2210 gIsoDep.fsx = param.FSx;
DiegoOstuni 0:75fc82583a41 2211
DiegoOstuni 0:75fc82583a41 2212 /* Convert APDU TxRxParams to I-Block TxRxParams */
DiegoOstuni 0:75fc82583a41 2213 rfalIsoDepApdu2IBLockParam( gIsoDep.APDUParam, &txRxParam, gIsoDep.APDUTxPos, gIsoDep.APDURxPos );
DiegoOstuni 0:75fc82583a41 2214
DiegoOstuni 0:75fc82583a41 2215 return rfalIsoDepStartTransceive( txRxParam );
DiegoOstuni 0:75fc82583a41 2216 }
DiegoOstuni 0:75fc82583a41 2217
DiegoOstuni 0:75fc82583a41 2218
DiegoOstuni 0:75fc82583a41 2219 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2220 ReturnCode rfalIsoDepGetApduTransceiveStatus( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
DiegoOstuni 0:75fc82583a41 2221 {
DiegoOstuni 0:75fc82583a41 2222 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 2223 rfalIsoDepTxRxParam txRxParam;
DiegoOstuni 0:75fc82583a41 2224
DiegoOstuni 0:75fc82583a41 2225 ret = rfalIsoDepGetTransceiveStatus( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 2226 switch( ret )
DiegoOstuni 0:75fc82583a41 2227 {
DiegoOstuni 0:75fc82583a41 2228 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2229 case ERR_NONE:
DiegoOstuni 0:75fc82583a41 2230
DiegoOstuni 0:75fc82583a41 2231 /* Check if we are still doing chaining on Tx */
DiegoOstuni 0:75fc82583a41 2232 if( gIsoDep.isTxChaining )
DiegoOstuni 0:75fc82583a41 2233 {
DiegoOstuni 0:75fc82583a41 2234 /* Add already Tx bytes */
DiegoOstuni 0:75fc82583a41 2235 gIsoDep.APDUTxPos += gIsoDep.txBufLen;
DiegoOstuni 0:75fc82583a41 2236
DiegoOstuni 0:75fc82583a41 2237 /* Convert APDU TxRxParams to I-Block TxRxParams */
DiegoOstuni 0:75fc82583a41 2238 rfalIsoDepApdu2IBLockParam( gIsoDep.APDUParam, &txRxParam, gIsoDep.APDUTxPos, gIsoDep.APDURxPos );
DiegoOstuni 0:75fc82583a41 2239
DiegoOstuni 0:75fc82583a41 2240 /* Move next I-Block to beginning of APDU Tx buffer */
DiegoOstuni 0:75fc82583a41 2241 ST_MEMCPY( gIsoDep.APDUParam.txBuf->apdu, &gIsoDep.APDUParam.txBuf->apdu[gIsoDep.APDUTxPos], txRxParam.txBufLen );
DiegoOstuni 0:75fc82583a41 2242
DiegoOstuni 0:75fc82583a41 2243 rfalIsoDepStartTransceive( txRxParam );
DiegoOstuni 0:75fc82583a41 2244 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 2245 }
DiegoOstuni 0:75fc82583a41 2246
DiegoOstuni 0:75fc82583a41 2247 /* Copy packet from tmp buffer to APDU buffer */
DiegoOstuni 0:75fc82583a41 2248 ST_MEMCPY( &gIsoDep.APDUParam.rxBuf->apdu[gIsoDep.APDURxPos], gIsoDep.APDUParam.tmpBuf->inf, *gIsoDep.APDUParam.rxLen );
DiegoOstuni 0:75fc82583a41 2249 gIsoDep.APDURxPos += *gIsoDep.APDUParam.rxLen;
DiegoOstuni 0:75fc82583a41 2250
DiegoOstuni 0:75fc82583a41 2251 /* APDU TxRx is done */
DiegoOstuni 0:75fc82583a41 2252 break;
DiegoOstuni 0:75fc82583a41 2253
DiegoOstuni 0:75fc82583a41 2254 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2255 case ERR_AGAIN:
DiegoOstuni 0:75fc82583a41 2256 /* Copy chained packet from tmp buffer to APDU buffer */
DiegoOstuni 0:75fc82583a41 2257 ST_MEMCPY( &gIsoDep.APDUParam.rxBuf->apdu[gIsoDep.APDURxPos], gIsoDep.APDUParam.tmpBuf->inf, *gIsoDep.APDUParam.rxLen );
DiegoOstuni 0:75fc82583a41 2258 gIsoDep.APDURxPos += *gIsoDep.APDUParam.rxLen;
DiegoOstuni 0:75fc82583a41 2259
DiegoOstuni 0:75fc82583a41 2260 /* Wait for next I-Block */
DiegoOstuni 0:75fc82583a41 2261 return ERR_BUSY;
DiegoOstuni 0:75fc82583a41 2262
DiegoOstuni 0:75fc82583a41 2263 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 2264 default:
DiegoOstuni 0:75fc82583a41 2265 return ret;
DiegoOstuni 0:75fc82583a41 2266 }
DiegoOstuni 0:75fc82583a41 2267
DiegoOstuni 0:75fc82583a41 2268 *gIsoDep.APDUParam.rxLen = gIsoDep.APDURxPos;
DiegoOstuni 0:75fc82583a41 2269
DiegoOstuni 0:75fc82583a41 2270 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 2271 }
DiegoOstuni 0:75fc82583a41 2272
DiegoOstuni 0:75fc82583a41 2273 #endif /* RFAL_FEATURE_ISO_DEP */