| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2003-2009, Broadcom Corporation |
|---|
| 3 | * All Rights Reserved |
|---|
| 4 | * Confidential Property of Broadcom Corporation |
|---|
| 5 | * |
|---|
| 6 | * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE |
|---|
| 7 | * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR |
|---|
| 8 | * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 9 | * |
|---|
| 10 | * $brcm_Workfile: bscd_emvpriv.c $ |
|---|
| 11 | * $brcm_Revision: Hydra_Software_Devel/17 $ |
|---|
| 12 | * $brcm_Date: 11/19/09 4:54p $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: This file contains Broadcom smart card Porting |
|---|
| 15 | * Interface EMV private functions. |
|---|
| 16 | * |
|---|
| 17 | * |
|---|
| 18 | * Revision History: |
|---|
| 19 | * |
|---|
| 20 | * $brcm_Log: /magnum/portinginterface/scd/7125/bscd_emvpriv.c $ |
|---|
| 21 | * |
|---|
| 22 | * Hydra_Software_Devel/17 11/19/09 4:54p qxie |
|---|
| 23 | * SW7125-113:Smartcard:add support to 7125 |
|---|
| 24 | * |
|---|
| 25 | * Hydra_Software_Devel/16 4/28/08 12:03p qxie |
|---|
| 26 | * PR42234: Smartcard: add EMV2000 support under 36M external clock |
|---|
| 27 | * |
|---|
| 28 | * Hydra_Software_Devel/15 5/27/05 10:05p btan |
|---|
| 29 | * PR 15680: Added smartcard support for 3560. |
|---|
| 30 | * |
|---|
| 31 | * Hydra_Software_Devel/14 4/9/05 2:48p btan |
|---|
| 32 | * PR 14698: Removed unused parameter warnings. |
|---|
| 33 | * |
|---|
| 34 | * Hydra_Software_Devel/13 3/16/05 12:08p btan |
|---|
| 35 | * PR 14493: Dont't include bchp_7038.h. |
|---|
| 36 | * |
|---|
| 37 | * Hydra_Software_Devel/12 9/9/04 12:45p btan |
|---|
| 38 | * PR 12607: Smartcard: T=0 protocol takes too long to time out and time |
|---|
| 39 | * out happens after all bytes are received. |
|---|
| 40 | * |
|---|
| 41 | * Hydra_Software_Devel/11 8/4/04 10:24a btan |
|---|
| 42 | * PR 12164: Fixed smartcard compilation warning |
|---|
| 43 | * |
|---|
| 44 | * Hydra_Software_Devel/10 7/29/04 4:53p btan |
|---|
| 45 | * PR 12079, PR 12114: Removed warning. Added NDS DSS support on 7038 |
|---|
| 46 | * |
|---|
| 47 | * Hydra_Software_Devel/9 7/20/04 2:12p btan |
|---|
| 48 | * PR 10898: Pass EMV 2000 tests with either event interrupt or WWT to |
|---|
| 49 | * detect CWT +4 |
|---|
| 50 | * |
|---|
| 51 | * Hydra_Software_Devel/8 6/8/04 3:16p btan |
|---|
| 52 | * PR 10898: Added support for EMV 2000. |
|---|
| 53 | * |
|---|
| 54 | * Hydra_Software_Devel/7 5/17/04 4:53p btan |
|---|
| 55 | * PR 10898: Added support for 7038 B0. |
|---|
| 56 | * |
|---|
| 57 | * Hydra_Software_Devel/6 12/31/03 3:37p btan |
|---|
| 58 | * PR 9168: Fixed compilation warnings. |
|---|
| 59 | * |
|---|
| 60 | * Hydra_Software_Devel/5 11/26/03 5:01p btan |
|---|
| 61 | * Fixes for EMV T=0 |
|---|
| 62 | * |
|---|
| 63 | * Hydra_Software_Devel/3 11/18/03 5:09p btan |
|---|
| 64 | * Fixed a timer bug. |
|---|
| 65 | * |
|---|
| 66 | * Hydra_Software_Devel/2 10/28/03 5:03p btan |
|---|
| 67 | * Fixed the bugs after the first round test. |
|---|
| 68 | * |
|---|
| 69 | * Hydra_Software_Devel/1 10/13/03 12:23p btan |
|---|
| 70 | * Initial Creation |
|---|
| 71 | * |
|---|
| 72 | ***************************************************************************/ |
|---|
| 73 | #include "bstd.h" |
|---|
| 74 | #include "bkni.h" |
|---|
| 75 | #include "bkni_multi.h" |
|---|
| 76 | #if (BCHP_CHIP!=7125)||((BCHP_CHIP==7125)&& (BCHP_VER>=BCHP_VER_C0)) |
|---|
| 77 | #include "bchp_sca.h" |
|---|
| 78 | #else |
|---|
| 79 | #include "bchp_scb.h" |
|---|
| 80 | #endif |
|---|
| 81 | #include "bscd.h" |
|---|
| 82 | #include "bscd_priv.h" |
|---|
| 83 | #include "bscd_emvpriv.h" |
|---|
| 84 | |
|---|
| 85 | BDBG_MODULE(BSCD); |
|---|
| 86 | |
|---|
| 87 | BERR_Code BSCD_Channel_P_EMVATRReadNextByte( |
|---|
| 88 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 89 | unsigned char *outp_ucData, |
|---|
| 90 | unsigned long *outp_ulTotalAtrByteTimeInETU, |
|---|
| 91 | unsigned char *outp_ucParityErrorDetected |
|---|
| 92 | ) |
|---|
| 93 | { |
|---|
| 94 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 95 | uint32_t ulValue; |
|---|
| 96 | |
|---|
| 97 | BDBG_ENTER(BSCD_Channel_P_EMVATRReadNextByte); |
|---|
| 98 | BSCD_P_CHECK_ERR_CODE_CONDITION( errCode, BSCD_STATUS_FAILED, |
|---|
| 99 | (in_channelHandle->ulRxLen == BSCD_MAX_ATR_SIZE ) ); |
|---|
| 100 | |
|---|
| 101 | #if 1 |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | /*EMV2000*/ |
|---|
| 105 | if (in_channelHandle->currentChannelSettings.scStandard == BSCD_Standard_eEMV2000) { |
|---|
| 106 | BSCD_P_CHECK_ERR_CODE_FUNC2(errCode, BSCD_STATUS_DEACTIVATE, |
|---|
| 107 | BSCD_Channel_P_EMVATRByteRead(in_channelHandle, outp_ucData, |
|---|
| 108 | BSCD_MAX_ETU_PER_ATR_BYTE_EMV2000, |
|---|
| 109 | BSCD_MAX_EMV_ETU_FOR_ALL_ATR_BYTES_EMV2000, |
|---|
| 110 | outp_ulTotalAtrByteTimeInETU)); |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | else { /* EMV 96 */ |
|---|
| 114 | BSCD_P_CHECK_ERR_CODE_FUNC2(errCode, BSCD_STATUS_DEACTIVATE, |
|---|
| 115 | BSCD_Channel_P_EMVATRByteRead(in_channelHandle, outp_ucData, |
|---|
| 116 | BSCD_MAX_ETU_PER_ATR_BYTE, |
|---|
| 117 | BSCD_MAX_EMV_ETU_FOR_ALL_ATR_BYTES, |
|---|
| 118 | outp_ulTotalAtrByteTimeInETU)); |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | #endif |
|---|
| 122 | |
|---|
| 123 | #if 0 |
|---|
| 124 | errCode = BERR_TRACE(BSCD_Channel_P_EMVATRByteRead(in_channelHandle, outp_ucData, |
|---|
| 125 | BSCD_MAX_ETU_PER_ATR_BYTE, |
|---|
| 126 | BSCD_MAX_EMV_ETU_FOR_ALL_ATR_BYTES, |
|---|
| 127 | outp_ulTotalAtrByteTimeInETU)); |
|---|
| 128 | BDBG_MSG(("In atqwe errCode = %d\n", errCode)); |
|---|
| 129 | if (errCode != BERR_SUCCESS) |
|---|
| 130 | { |
|---|
| 131 | BDBG_MSG(("In BSCD_P_CHECK_ERR_CODE_CONDITION errCode = %d\n", errCode)); |
|---|
| 132 | errCode = BSCD_STATUS_DEACTIVATE; |
|---|
| 133 | BDBG_MSG(("After BSCD_P_CHECK_ERR_CODE_CONDITION errCode = %d\n", errCode)); |
|---|
| 134 | goto BSCD_P_DONE_LABEL; |
|---|
| 135 | } |
|---|
| 136 | #endif |
|---|
| 137 | |
|---|
| 138 | #if 0 |
|---|
| 139 | if ( (errCode = BSCD_Channel_P_EMVATRByteRead(in_channelHandle, outp_ucData, |
|---|
| 140 | BSCD_MAX_ETU_PER_ATR_BYTE, |
|---|
| 141 | BSCD_MAX_EMV_ETU_FOR_ALL_ATR_BYTES, |
|---|
| 142 | outp_ulTotalAtrByteTimeInETU)) != BERR_SUCCESS) { |
|---|
| 143 | |
|---|
| 144 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_DEACTIVATE, true); |
|---|
| 145 | } |
|---|
| 146 | #endif |
|---|
| 147 | |
|---|
| 148 | BDBG_MSG(("After EMVATRByteRead errCode = %d\n", errCode)); |
|---|
| 149 | |
|---|
| 150 | ulValue = BREG_Read32( |
|---|
| 151 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 152 | (in_channelHandle->ulRegStartAddr + BSCD_P_STATUS_2)); |
|---|
| 153 | |
|---|
| 154 | /* |
|---|
| 155 | If a parity error is detected, then continue to read in entire |
|---|
| 156 | ATR, but immediately after doing so, return BSCD_STATUS_FAILED to |
|---|
| 157 | deactivate as per EMV spec |
|---|
| 158 | */ |
|---|
| 159 | if ((ulValue & BCHP_SCA_SC_STATUS_2_rpar_err_MASK) == |
|---|
| 160 | BCHP_SCA_SC_STATUS_2_rpar_err_MASK) { |
|---|
| 161 | |
|---|
| 162 | BDBG_MSG(("Parity Error found in ATR byte")); |
|---|
| 163 | /* |
|---|
| 164 | Clear this retry interrupt so that we could continue reading. |
|---|
| 165 | Test 1726 x=2 need this |
|---|
| 166 | */ |
|---|
| 167 | BKNI_EnterCriticalSection(); |
|---|
| 168 | in_channelHandle->ulIntrStatus1 &= ~BCHP_SCA_SC_INTR_STAT_1_retry_intr_MASK; |
|---|
| 169 | BKNI_LeaveCriticalSection(); |
|---|
| 170 | *outp_ucParityErrorDetected = 1; |
|---|
| 171 | } |
|---|
| 172 | BSCD_P_DONE_LABEL: |
|---|
| 173 | |
|---|
| 174 | BDBG_LEAVE(BSCD_Channel_P_EMVATRReadNextByte); |
|---|
| 175 | BDBG_MSG(("Leave EMVATRReadNextByte errCode = 0x%x\n", errCode)); |
|---|
| 176 | return( errCode ); |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | |
|---|
| 180 | BERR_Code BSCD_Channel_P_EMVATRCheckForAdditionalATRBytes( |
|---|
| 181 | BSCD_ChannelHandle in_channelHandle |
|---|
| 182 | ) |
|---|
| 183 | { |
|---|
| 184 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 185 | #ifdef BSCD_EMV2000_CWT_PLUS_4_EVENT_INTR |
|---|
| 186 | uint32_t ulVal; |
|---|
| 187 | #endif |
|---|
| 188 | unsigned char bval; |
|---|
| 189 | unsigned long ulTotalAtrByteTimeInETU = 0; |
|---|
| 190 | unsigned int unAdditionalByteCount = 0; |
|---|
| 191 | |
|---|
| 192 | |
|---|
| 193 | BDBG_MSG(("In BSCD_Channel_P_EMVATRCheckForAdditionalATRBytes\n")); |
|---|
| 194 | while (errCode == BERR_SUCCESS) { |
|---|
| 195 | |
|---|
| 196 | /* |
|---|
| 197 | Since GP is used for total ATR time and WWT is used for WWT, we use |
|---|
| 198 | event2_intr for this 200 ETU checking |
|---|
| 199 | */ |
|---|
| 200 | |
|---|
| 201 | #ifdef BSCD_EMV2000_CWT_PLUS_4_EVENT_INTR |
|---|
| 202 | /* 200 ETU */ |
|---|
| 203 | BREG_Write32( |
|---|
| 204 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 205 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMP), |
|---|
| 206 | 200); |
|---|
| 207 | |
|---|
| 208 | /* start event src */ |
|---|
| 209 | BREG_Write32( |
|---|
| 210 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 211 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_3), |
|---|
| 212 | BSCD_P_RX_ETU_TICK_EVENT_SRC); |
|---|
| 213 | |
|---|
| 214 | /* increment event src */ |
|---|
| 215 | BREG_Write32( |
|---|
| 216 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 217 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_2), |
|---|
| 218 | BSCD_P_RX_ETU_TICK_EVENT_SRC); |
|---|
| 219 | |
|---|
| 220 | /* reset event src */ |
|---|
| 221 | BREG_Write32( |
|---|
| 222 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 223 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_1), |
|---|
| 224 | BSCD_P_NO_EVENT_EVENT_SRC); |
|---|
| 225 | |
|---|
| 226 | /* event_en, intr_mode, run_after_reset and run_after_compare*/ |
|---|
| 227 | ulVal = BCHP_SCA_SC_EVENT2_CMD_4_event_en_MASK | |
|---|
| 228 | BCHP_SCA_SC_EVENT2_CMD_4_intr_after_compare_MASK | |
|---|
| 229 | BCHP_SCA_SC_EVENT2_CMD_4_run_after_reset_MASK | |
|---|
| 230 | BCHP_SCA_SC_EVENT2_CMD_4_run_after_compare_MASK; |
|---|
| 231 | |
|---|
| 232 | ulVal &= ~(BCHP_SCA_SC_EVENT2_CMD_4_intr_after_reset_MASK); |
|---|
| 233 | BREG_Write32( |
|---|
| 234 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 235 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_4), |
|---|
| 236 | ulVal); |
|---|
| 237 | |
|---|
| 238 | |
|---|
| 239 | BSCD_Channel_EnableIntrCallback_isr ( |
|---|
| 240 | in_channelHandle, BSCD_IntType_eEvent2Int, |
|---|
| 241 | BSCD_Channel_P_Event2CB_isr); |
|---|
| 242 | |
|---|
| 243 | #endif |
|---|
| 244 | |
|---|
| 245 | errCode = BSCD_Channel_P_EMVATRByteRead(in_channelHandle, &bval, 200, |
|---|
| 246 | BSCD_MAX_EMV_ETU_FOR_ALL_ATR_BYTES, |
|---|
| 247 | &ulTotalAtrByteTimeInETU); |
|---|
| 248 | |
|---|
| 249 | #ifdef BSCD_EMV2000_CWT_PLUS_4_EVENT_INTR |
|---|
| 250 | /* Disable event2 */ |
|---|
| 251 | ulVal = BREG_Read32( |
|---|
| 252 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 253 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_4)); |
|---|
| 254 | ulVal &= ~(BCHP_SCA_SC_EVENT2_CMD_4_event_en_MASK); |
|---|
| 255 | BREG_Write32( |
|---|
| 256 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 257 | (in_channelHandle->ulRegStartAddr + BSCD_P_EVENT2_CMD_4), |
|---|
| 258 | ulVal); |
|---|
| 259 | #endif |
|---|
| 260 | |
|---|
| 261 | if (errCode == BERR_SUCCESS) { |
|---|
| 262 | BDBG_MSG(("In SmartCardATRCheckForAdditionalATRBytes: Extra Byte Detected\n")); |
|---|
| 263 | unAdditionalByteCount++; |
|---|
| 264 | } |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | |
|---|
| 268 | if (unAdditionalByteCount) |
|---|
| 269 | return BSCD_STATUS_FAILED; |
|---|
| 270 | else |
|---|
| 271 | return BERR_SUCCESS; |
|---|
| 272 | } |
|---|
| 273 | |
|---|
| 274 | |
|---|
| 275 | |
|---|
| 276 | BERR_Code BSCD_Channel_P_EMVATRReceiveAndDecode( |
|---|
| 277 | BSCD_ChannelHandle in_channelHandle |
|---|
| 278 | ) |
|---|
| 279 | { |
|---|
| 280 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 281 | /* unsigned char ucTDCount = 0; */ |
|---|
| 282 | unsigned char ucFfactor = 1, ucDFactor = 1; |
|---|
| 283 | |
|---|
| 284 | /* Used to store value of T0, and TDx's as applicable */ |
|---|
| 285 | |
|---|
| 286 | /* unsigned char ucGenChecksum = 0; |
|---|
| 287 | unsigned int unGuardTime = 0; */ |
|---|
| 288 | unsigned int unNumHistoricalBytes = 0; |
|---|
| 289 | |
|---|
| 290 | unsigned char ucT0Byte = 0, ucTD1Byte = 0, ucTD2Byte = 0, ucTD3Byte = 0, ucTC1Byte = 0; |
|---|
| 291 | unsigned long ulTotalAtrByteTimeInETU = 0; |
|---|
| 292 | unsigned char ucParityErrorDetected = 0; |
|---|
| 293 | unsigned int i; |
|---|
| 294 | bool bFailedATR = false; |
|---|
| 295 | /* bool bInvalidTS = false; */ |
|---|
| 296 | bool bTCKRequired = false; |
|---|
| 297 | uint32_t ulValue; |
|---|
| 298 | |
|---|
| 299 | BSCD_Timer timer = {BSCD_TimerType_eWaitTimer, {BSCD_GPTimerMode_eIMMEDIATE}, false, true}; |
|---|
| 300 | BSCD_Timer wwtTimer = {BSCD_TimerType_eWaitTimer, {BSCD_GPTimerMode_eIMMEDIATE}, false, false}; |
|---|
| 301 | |
|---|
| 302 | |
|---|
| 303 | BDBG_ENTER(BSCD_Channel_P_EMVATRReceiveAndDecode); |
|---|
| 304 | |
|---|
| 305 | in_channelHandle->ulRxLen = 0; |
|---|
| 306 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 307 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 308 | &ulTotalAtrByteTimeInETU, |
|---|
| 309 | &ucParityErrorDetected); |
|---|
| 310 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 311 | errCode = BERR_TRACE(errCode); |
|---|
| 312 | goto BSCD_P_DONE_LABEL; |
|---|
| 313 | } |
|---|
| 314 | |
|---|
| 315 | BSCD_P_CHECK_ERR_CODE_FUNC2(errCode, BSCD_STATUS_DEACTIVATE, |
|---|
| 316 | BSCD_Channel_P_EMVValidateTSByte( |
|---|
| 317 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++])); |
|---|
| 318 | |
|---|
| 319 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 320 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 321 | &ulTotalAtrByteTimeInETU, |
|---|
| 322 | &ucParityErrorDetected); |
|---|
| 323 | |
|---|
| 324 | BDBG_MSG(("After T0 EMVATRReadNextByte errCode = 0x%x\n", errCode)); |
|---|
| 325 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 326 | errCode = BERR_TRACE(errCode); |
|---|
| 327 | goto BSCD_P_DONE_LABEL; |
|---|
| 328 | } |
|---|
| 329 | |
|---|
| 330 | errCode = BSCD_Channel_P_EMVValidateT0Byte( |
|---|
| 331 | in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen], |
|---|
| 332 | &unNumHistoricalBytes); |
|---|
| 333 | ucT0Byte = in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]; |
|---|
| 334 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 335 | bFailedATR = true; |
|---|
| 336 | |
|---|
| 337 | if (ucT0Byte & 0x10 ) { /* TA1 is present */ |
|---|
| 338 | |
|---|
| 339 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 340 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 341 | &ulTotalAtrByteTimeInETU, |
|---|
| 342 | &ucParityErrorDetected); |
|---|
| 343 | BDBG_MSG(("After T0 EMVATRReadNextByte errCode = 0x%x\n", errCode)); |
|---|
| 344 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 345 | errCode = BERR_TRACE(errCode); |
|---|
| 346 | goto BSCD_P_DONE_LABEL; |
|---|
| 347 | } |
|---|
| 348 | |
|---|
| 349 | errCode= BSCD_Channel_P_EMVValidateTA1Byte(in_channelHandle, |
|---|
| 350 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 351 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 352 | bFailedATR = true; |
|---|
| 353 | |
|---|
| 354 | /* |
|---|
| 355 | Since BSCD_Channel_P_EMVValidateTA1Byte passed successfully at this point, |
|---|
| 356 | we may obtain local copies of the F & D values for future use |
|---|
| 357 | */ |
|---|
| 358 | ucFfactor = in_channelHandle->currentChannelSettings.ucFFactor; |
|---|
| 359 | ucDFactor = in_channelHandle->currentChannelSettings.ucDFactor; |
|---|
| 360 | |
|---|
| 361 | |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | else { |
|---|
| 365 | /* |
|---|
| 366 | If TA1 is absent, use ucFfactor = 1, ucDFactor = 1, |
|---|
| 367 | which corresponds to D = 1, F = 372 |
|---|
| 368 | */ |
|---|
| 369 | /* |
|---|
| 370 | If TA1 is absent, use ucFfactor = 1, ucDFactor = 1, |
|---|
| 371 | which corresponds to D = 1, F = 372 |
|---|
| 372 | */ |
|---|
| 373 | in_channelHandle->currentChannelSettings.ucFFactor = ucFfactor; |
|---|
| 374 | in_channelHandle->currentChannelSettings.ucDFactor = ucDFactor; |
|---|
| 375 | |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | if (ucT0Byte & 0x20) { /* TB1 is present */ |
|---|
| 379 | |
|---|
| 380 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 381 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 382 | &ulTotalAtrByteTimeInETU, |
|---|
| 383 | &ucParityErrorDetected); |
|---|
| 384 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 385 | errCode = BERR_TRACE(errCode); |
|---|
| 386 | goto BSCD_P_DONE_LABEL; |
|---|
| 387 | } |
|---|
| 388 | |
|---|
| 389 | errCode= BSCD_Channel_P_EMVValidateTB1Byte(in_channelHandle, |
|---|
| 390 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 391 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 392 | bFailedATR = true; |
|---|
| 393 | } |
|---|
| 394 | |
|---|
| 395 | else if (in_channelHandle->resetType == BSCD_ResetType_eCold) { |
|---|
| 396 | |
|---|
| 397 | /* Cold Reset must have a TB1 value specified for EMV */ |
|---|
| 398 | BDBG_ERR (("Cold Reset & Missing TB1 - not allowed for EMV\n")); |
|---|
| 399 | errCode = BERR_TRACE(BSCD_STATUS_FAILED); |
|---|
| 400 | bFailedATR = true; |
|---|
| 401 | } |
|---|
| 402 | |
|---|
| 403 | if (ucT0Byte & 0x40) { /* TC1 is present */ |
|---|
| 404 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 405 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 406 | &ulTotalAtrByteTimeInETU, |
|---|
| 407 | &ucParityErrorDetected); |
|---|
| 408 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 409 | errCode = BERR_TRACE(errCode); |
|---|
| 410 | goto BSCD_P_DONE_LABEL; |
|---|
| 411 | } |
|---|
| 412 | |
|---|
| 413 | ucTC1Byte = in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]; |
|---|
| 414 | |
|---|
| 415 | } |
|---|
| 416 | |
|---|
| 417 | else { |
|---|
| 418 | /* TC1 is absent from the ATR, so simply program guardtime of zero ETUs */ |
|---|
| 419 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue = 0; |
|---|
| 420 | in_channelHandle->currentChannelSettings.extraGuardTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 421 | BREG_Write32( |
|---|
| 422 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 423 | (in_channelHandle->ulRegStartAddr + BSCD_P_TGUARD), |
|---|
| 424 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue); |
|---|
| 425 | |
|---|
| 426 | BDBG_MSG(("\nSmartCardValidateTC1Byte: ulGuardTime = 0x%x \n", |
|---|
| 427 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue)); |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | if (ucT0Byte & 0x80) { /* TD1 is present */ |
|---|
| 431 | |
|---|
| 432 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 433 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 434 | &ulTotalAtrByteTimeInETU, |
|---|
| 435 | &ucParityErrorDetected); |
|---|
| 436 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 437 | errCode = BERR_TRACE(errCode); |
|---|
| 438 | goto BSCD_P_DONE_LABEL; |
|---|
| 439 | } |
|---|
| 440 | |
|---|
| 441 | ucTD1Byte = in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]; /* Store ucTD1Byte */ |
|---|
| 442 | |
|---|
| 443 | errCode= BSCD_Channel_P_EMVValidateTD1Byte(in_channelHandle, |
|---|
| 444 | ucTD1Byte, &bTCKRequired); |
|---|
| 445 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 446 | bFailedATR = true; |
|---|
| 447 | |
|---|
| 448 | } |
|---|
| 449 | |
|---|
| 450 | |
|---|
| 451 | /* Check TC1 here, so that we can take care of TC1=255 and T=1 case */ |
|---|
| 452 | if (ucTC1Byte != 0) { |
|---|
| 453 | errCode= BSCD_Channel_P_EMVValidateTC1Byte(in_channelHandle, |
|---|
| 454 | ucTC1Byte); |
|---|
| 455 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 456 | bFailedATR = true; |
|---|
| 457 | } |
|---|
| 458 | |
|---|
| 459 | |
|---|
| 460 | if (ucTD1Byte & 0x10) { /* TA2 is present */ |
|---|
| 461 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 462 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 463 | &ulTotalAtrByteTimeInETU, |
|---|
| 464 | &ucParityErrorDetected); |
|---|
| 465 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 466 | errCode = BERR_TRACE(errCode); |
|---|
| 467 | goto BSCD_P_DONE_LABEL; |
|---|
| 468 | } |
|---|
| 469 | |
|---|
| 470 | errCode= BSCD_Channel_P_EMVValidateTA2Byte( |
|---|
| 471 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 472 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 473 | bFailedATR = true; |
|---|
| 474 | } |
|---|
| 475 | else { |
|---|
| 476 | /* If TA1 is present and TA2 is absent, we should use F=1 and D=372 */ |
|---|
| 477 | in_channelHandle->currentChannelSettings.ucFFactor = ucFfactor = 1; |
|---|
| 478 | in_channelHandle->currentChannelSettings.ucDFactor = ucDFactor = 1; |
|---|
| 479 | } |
|---|
| 480 | |
|---|
| 481 | /* EMV 2000 */ |
|---|
| 482 | in_channelHandle->currentChannelSettings.ucEtuClkDiv = |
|---|
| 483 | BSCD_P_GetETUClkDiv(in_channelHandle, in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 484 | in_channelHandle->currentChannelSettings.ucFFactor); |
|---|
| 485 | |
|---|
| 486 | in_channelHandle->currentChannelSettings.ucScClkDiv = |
|---|
| 487 | BSCD_P_GetClkDiv(in_channelHandle, in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 488 | in_channelHandle->currentChannelSettings.ucFFactor) ; |
|---|
| 489 | |
|---|
| 490 | in_channelHandle->currentChannelSettings.unPrescale = |
|---|
| 491 | BSCD_P_GetPrescale(in_channelHandle, in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 492 | in_channelHandle->currentChannelSettings.ucFFactor) * |
|---|
| 493 | in_channelHandle->currentChannelSettings.ucExternalClockDivisor + |
|---|
| 494 | (in_channelHandle->currentChannelSettings.ucExternalClockDivisor - 1); |
|---|
| 495 | |
|---|
| 496 | in_channelHandle->currentChannelSettings.ucBaudDiv = |
|---|
| 497 | BSCD_P_GetBaudDiv(in_channelHandle, in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 498 | in_channelHandle->currentChannelSettings.ucFFactor) ; |
|---|
| 499 | |
|---|
| 500 | in_channelHandle->currentChannelSettings.currentBaudRate = |
|---|
| 501 | in_channelHandle->moduleHandle->currentSettings.moduleClkFreq.ulClkFreq / |
|---|
| 502 | in_channelHandle->currentChannelSettings.ucEtuClkDiv/ |
|---|
| 503 | (in_channelHandle->currentChannelSettings.unPrescale+1)/ |
|---|
| 504 | in_channelHandle->currentChannelSettings.ucBaudDiv; |
|---|
| 505 | |
|---|
| 506 | /* Call SmartCardFDAdjust to adjust clock and bit rate. */ |
|---|
| 507 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 508 | BSCD_P_AdjustWWT(in_channelHandle, ucFfactor, ucDFactor, |
|---|
| 509 | BSCD_ISO_DEFAULT_WORK_WAIT_TIME_INTEGER)); |
|---|
| 510 | |
|---|
| 511 | |
|---|
| 512 | if (ucTD1Byte & 0x20) { /* TB2 is present */ |
|---|
| 513 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 514 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 515 | &ulTotalAtrByteTimeInETU, |
|---|
| 516 | &ucParityErrorDetected); |
|---|
| 517 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 518 | errCode = BERR_TRACE(errCode); |
|---|
| 519 | goto BSCD_P_DONE_LABEL; |
|---|
| 520 | } |
|---|
| 521 | |
|---|
| 522 | errCode= BSCD_Channel_P_EMVValidateTB2Byte( |
|---|
| 523 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 524 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 525 | bFailedATR = true; |
|---|
| 526 | |
|---|
| 527 | } |
|---|
| 528 | |
|---|
| 529 | if (ucTD1Byte & 0x40) { /* TC2 is present */ |
|---|
| 530 | |
|---|
| 531 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 532 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 533 | &ulTotalAtrByteTimeInETU, |
|---|
| 534 | &ucParityErrorDetected); |
|---|
| 535 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 536 | errCode = BERR_TRACE(errCode); |
|---|
| 537 | goto BSCD_P_DONE_LABEL; |
|---|
| 538 | } |
|---|
| 539 | |
|---|
| 540 | errCode= BSCD_Channel_P_EMVValidateTC2Byte(in_channelHandle, |
|---|
| 541 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 542 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 543 | bFailedATR = true; |
|---|
| 544 | } |
|---|
| 545 | |
|---|
| 546 | else { /* TC2 is absent, so use default WI = 10 */ |
|---|
| 547 | |
|---|
| 548 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 549 | BSCD_P_AdjustWWT(in_channelHandle, |
|---|
| 550 | in_channelHandle->currentChannelSettings.ucFFactor, |
|---|
| 551 | in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 552 | BSCD_ISO_DEFAULT_WORK_WAIT_TIME_INTEGER)); |
|---|
| 553 | |
|---|
| 554 | |
|---|
| 555 | } |
|---|
| 556 | |
|---|
| 557 | /*EMV2000*/ |
|---|
| 558 | /* |
|---|
| 559 | if (in_channelHandle->currentChannelSettings.scStandard == BSCD_Standard_eEMV2000) |
|---|
| 560 | timeValue.ulValue = in_channelHandle->currentChannelSettings.workWaitTime.ulValue |
|---|
| 561 | + in_channelHandle->currentChannelSettings.ucDFactor * |
|---|
| 562 | BSCD_DEFAULT_EXTRA_WORK_WAITING_TIME_EMV2000; |
|---|
| 563 | else |
|---|
| 564 | */ |
|---|
| 565 | /* BSYT???: May not need this */ |
|---|
| 566 | |
|---|
| 567 | /* |
|---|
| 568 | timeValue.ulValue = in_channelHandle->currentChannelSettings.workWaitTime.ulValue; |
|---|
| 569 | timer.eTimerType = BSCD_TimerType_eWaitTimer; |
|---|
| 570 | timer.timerMode.eWaitTimerMode = BSCD_WaitTimerMode_eWorkWaitTime; |
|---|
| 571 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 572 | BSCD_Channel_ConfigTimer(in_channelHandle, &timer, &timeValue)); |
|---|
| 573 | */ |
|---|
| 574 | |
|---|
| 575 | if (ucTD1Byte & 0x80) { /* TD2 is present */ |
|---|
| 576 | |
|---|
| 577 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 578 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 579 | &ulTotalAtrByteTimeInETU, |
|---|
| 580 | &ucParityErrorDetected); |
|---|
| 581 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 582 | errCode = BERR_TRACE(errCode); |
|---|
| 583 | goto BSCD_P_DONE_LABEL; |
|---|
| 584 | } |
|---|
| 585 | |
|---|
| 586 | ucTD2Byte = in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]; /* Store ucTD1Byte */ |
|---|
| 587 | |
|---|
| 588 | errCode= BSCD_Channel_P_EMVValidateTD2Byte(in_channelHandle, ucTD2Byte, |
|---|
| 589 | ucTD1Byte, &bTCKRequired); |
|---|
| 590 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 591 | bFailedATR = true; |
|---|
| 592 | } |
|---|
| 593 | |
|---|
| 594 | if (ucTD2Byte & 0x10) { /* TA3 is present */ |
|---|
| 595 | |
|---|
| 596 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 597 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 598 | &ulTotalAtrByteTimeInETU, |
|---|
| 599 | &ucParityErrorDetected); |
|---|
| 600 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 601 | errCode = BERR_TRACE(errCode); |
|---|
| 602 | goto BSCD_P_DONE_LABEL; |
|---|
| 603 | } |
|---|
| 604 | |
|---|
| 605 | errCode= BSCD_Channel_P_EMVValidateTA3Byte(in_channelHandle, |
|---|
| 606 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 607 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 608 | bFailedATR = true; |
|---|
| 609 | } |
|---|
| 610 | |
|---|
| 611 | else { |
|---|
| 612 | |
|---|
| 613 | /* |
|---|
| 614 | Continue card session using value of '0x20' |
|---|
| 615 | for TA3 as per EMV'96 spec |
|---|
| 616 | */ |
|---|
| 617 | in_channelHandle->currentChannelSettings.unCurrentIFSD = BSCD_DEFAULT_EMV_INFORMATION_FIELD_SIZE; |
|---|
| 618 | |
|---|
| 619 | } |
|---|
| 620 | |
|---|
| 621 | if (ucTD2Byte & 0x20) { /* TB3 is present */ |
|---|
| 622 | |
|---|
| 623 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 624 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 625 | &ulTotalAtrByteTimeInETU, |
|---|
| 626 | &ucParityErrorDetected); |
|---|
| 627 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 628 | errCode = BERR_TRACE(errCode); |
|---|
| 629 | goto BSCD_P_DONE_LABEL; |
|---|
| 630 | } |
|---|
| 631 | |
|---|
| 632 | errCode= BSCD_Channel_P_EMVValidateTB3Byte(in_channelHandle, |
|---|
| 633 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++], |
|---|
| 634 | in_channelHandle->currentChannelSettings.ucFFactor, |
|---|
| 635 | in_channelHandle->currentChannelSettings.ucDFactor ); |
|---|
| 636 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 637 | bFailedATR = true; |
|---|
| 638 | |
|---|
| 639 | } |
|---|
| 640 | |
|---|
| 641 | else { |
|---|
| 642 | /* |
|---|
| 643 | if TB3 is absent, then we must be in T = 0 mode, |
|---|
| 644 | otherwise reject ATR |
|---|
| 645 | */ |
|---|
| 646 | if (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e1) { |
|---|
| 647 | BDBG_MSG(("Failing in SmartCardEMVATRDecode - TB3 \n")); |
|---|
| 648 | |
|---|
| 649 | /* Cannot just return BSCD_STATUS_FAILED. Test 1800 needs to read the TCK */ |
|---|
| 650 | bFailedATR = true; |
|---|
| 651 | } |
|---|
| 652 | } |
|---|
| 653 | |
|---|
| 654 | if (ucTD2Byte & 0x40) { /* TC3 is present */ |
|---|
| 655 | |
|---|
| 656 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 657 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 658 | &ulTotalAtrByteTimeInETU, |
|---|
| 659 | &ucParityErrorDetected); |
|---|
| 660 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 661 | errCode = BERR_TRACE(errCode); |
|---|
| 662 | goto BSCD_P_DONE_LABEL; |
|---|
| 663 | } |
|---|
| 664 | |
|---|
| 665 | errCode= BSCD_Channel_P_EMVValidateTC3Byte( |
|---|
| 666 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 667 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 668 | bFailedATR = true; |
|---|
| 669 | } |
|---|
| 670 | |
|---|
| 671 | |
|---|
| 672 | /* EMV 2000 */ |
|---|
| 673 | if (ucTD2Byte & 0x80) { /* TD3 is present */ |
|---|
| 674 | |
|---|
| 675 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 676 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 677 | &ulTotalAtrByteTimeInETU, |
|---|
| 678 | &ucParityErrorDetected); |
|---|
| 679 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 680 | errCode = BERR_TRACE(errCode); |
|---|
| 681 | goto BSCD_P_DONE_LABEL; |
|---|
| 682 | } |
|---|
| 683 | |
|---|
| 684 | ucTD3Byte = in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]; /* Store ucTD1Byte */ |
|---|
| 685 | |
|---|
| 686 | /* |
|---|
| 687 | errCode= BSCD_Channel_P_EMVValidateTD3Byte(in_channelHandle, ucTD2Byte, |
|---|
| 688 | ucTD1Byte, &bTCKRequired); |
|---|
| 689 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 690 | bFailedATR = true; |
|---|
| 691 | */ |
|---|
| 692 | } |
|---|
| 693 | |
|---|
| 694 | if (ucTD3Byte & 0x10) { /* TA4 is present */ |
|---|
| 695 | |
|---|
| 696 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 697 | &(in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]), |
|---|
| 698 | &ulTotalAtrByteTimeInETU, |
|---|
| 699 | &ucParityErrorDetected); |
|---|
| 700 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 701 | errCode = BERR_TRACE(errCode); |
|---|
| 702 | goto BSCD_P_DONE_LABEL; |
|---|
| 703 | } |
|---|
| 704 | |
|---|
| 705 | /* |
|---|
| 706 | errCode= BSCD_Channel_P_EMVValidateTA4Byte(in_channelHandle, |
|---|
| 707 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 708 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 709 | bFailedATR = true; |
|---|
| 710 | */ |
|---|
| 711 | } |
|---|
| 712 | |
|---|
| 713 | if (ucTD3Byte & 0x20) { /* TB4 is present */ |
|---|
| 714 | |
|---|
| 715 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 716 | &(in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]), |
|---|
| 717 | &ulTotalAtrByteTimeInETU, |
|---|
| 718 | &ucParityErrorDetected); |
|---|
| 719 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 720 | errCode = BERR_TRACE(errCode); |
|---|
| 721 | goto BSCD_P_DONE_LABEL; |
|---|
| 722 | } |
|---|
| 723 | |
|---|
| 724 | /* |
|---|
| 725 | errCode= BSCD_Channel_P_EMVValidateTB4Byte(in_channelHandle, |
|---|
| 726 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++], |
|---|
| 727 | in_channelHandle->currentChannelSettings.ucFFactor, |
|---|
| 728 | in_channelHandle->currentChannelSettings.ucDFactor ); |
|---|
| 729 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 730 | bFailedATR = true; |
|---|
| 731 | */ |
|---|
| 732 | |
|---|
| 733 | } |
|---|
| 734 | |
|---|
| 735 | if (ucTD3Byte & 0x40) { /* TC4 is present */ |
|---|
| 736 | |
|---|
| 737 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 738 | &(in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]), |
|---|
| 739 | &ulTotalAtrByteTimeInETU, |
|---|
| 740 | &ucParityErrorDetected); |
|---|
| 741 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 742 | errCode = BERR_TRACE(errCode); |
|---|
| 743 | goto BSCD_P_DONE_LABEL; |
|---|
| 744 | } |
|---|
| 745 | |
|---|
| 746 | /* |
|---|
| 747 | errCode= BSCD_Channel_P_EMVValidateTC3Byte( |
|---|
| 748 | in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]); |
|---|
| 749 | if (errCode == BSCD_STATUS_FAILED) |
|---|
| 750 | bFailedATR = true; |
|---|
| 751 | */ |
|---|
| 752 | } |
|---|
| 753 | |
|---|
| 754 | |
|---|
| 755 | /* EMV 2000 */ |
|---|
| 756 | |
|---|
| 757 | if (unNumHistoricalBytes) { |
|---|
| 758 | |
|---|
| 759 | for (i = 0; i < unNumHistoricalBytes; i++) { |
|---|
| 760 | |
|---|
| 761 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 762 | &(in_channelHandle->aucRxBuf[(in_channelHandle->ulRxLen)++]), |
|---|
| 763 | &ulTotalAtrByteTimeInETU, |
|---|
| 764 | &ucParityErrorDetected); |
|---|
| 765 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 766 | errCode = BERR_TRACE(errCode); |
|---|
| 767 | goto BSCD_P_DONE_LABEL; |
|---|
| 768 | } |
|---|
| 769 | |
|---|
| 770 | } |
|---|
| 771 | } |
|---|
| 772 | |
|---|
| 773 | if (bTCKRequired) { |
|---|
| 774 | BDBG_MSG (("Checking for TCK Byte")); |
|---|
| 775 | errCode = BSCD_Channel_P_EMVATRReadNextByte(in_channelHandle, |
|---|
| 776 | &(in_channelHandle->aucRxBuf[in_channelHandle->ulRxLen]), |
|---|
| 777 | &ulTotalAtrByteTimeInETU, |
|---|
| 778 | &ucParityErrorDetected); |
|---|
| 779 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 780 | errCode = BERR_TRACE(errCode); |
|---|
| 781 | goto BSCD_P_DONE_LABEL; |
|---|
| 782 | } |
|---|
| 783 | |
|---|
| 784 | /* if in T = 1 mode, then TCK byte must be present and validated */ |
|---|
| 785 | errCode = BSCD_Channel_P_EMVValidateTCKByte(in_channelHandle, |
|---|
| 786 | in_channelHandle->aucRxBuf, (in_channelHandle->ulRxLen)++); |
|---|
| 787 | if (errCode == BSCD_STATUS_DEACTIVATE) { |
|---|
| 788 | errCode = BERR_TRACE(errCode); |
|---|
| 789 | goto BSCD_P_DONE_LABEL; |
|---|
| 790 | } |
|---|
| 791 | |
|---|
| 792 | } |
|---|
| 793 | |
|---|
| 794 | /* |
|---|
| 795 | Only after reading entire ATR, now if a parity error has been |
|---|
| 796 | detected, return BSCD_STATUS_FAILED |
|---|
| 797 | */ |
|---|
| 798 | if (ucParityErrorDetected) |
|---|
| 799 | return BSCD_STATUS_DEACTIVATE; |
|---|
| 800 | |
|---|
| 801 | |
|---|
| 802 | errCode = BSCD_Channel_P_EMVATRCheckForAdditionalATRBytes(in_channelHandle); |
|---|
| 803 | if (errCode == BSCD_STATUS_FAILED) { |
|---|
| 804 | errCode = BERR_TRACE(errCode); |
|---|
| 805 | goto BSCD_P_DONE_LABEL; |
|---|
| 806 | } |
|---|
| 807 | |
|---|
| 808 | /* Disable timer, which was enable upon receiving atr_intr */ |
|---|
| 809 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &timer); |
|---|
| 810 | |
|---|
| 811 | /* disable WWT. This was enabled in activating time */ |
|---|
| 812 | wwtTimer.timerMode.eWaitTimerMode = BSCD_WaitTimerMode_eWorkWaitTime; |
|---|
| 813 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &wwtTimer); |
|---|
| 814 | |
|---|
| 815 | /* Print ATR message. */ |
|---|
| 816 | BSCD_P_HexDump("ATR Data", |
|---|
| 817 | in_channelHandle->aucRxBuf, |
|---|
| 818 | in_channelHandle->ulRxLen); |
|---|
| 819 | |
|---|
| 820 | if (bFailedATR) |
|---|
| 821 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 822 | |
|---|
| 823 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 824 | BSCD_P_FDAdjust(in_channelHandle, ucFfactor, ucDFactor)); |
|---|
| 825 | |
|---|
| 826 | if ( (errCode = BSCD_Channel_EnableInterrupts(in_channelHandle)) != BERR_SUCCESS) { |
|---|
| 827 | errCode = BERR_TRACE(errCode); |
|---|
| 828 | goto BSCD_P_DONE_LABEL; |
|---|
| 829 | } |
|---|
| 830 | |
|---|
| 831 | /* Update the BSCD_P_UART_CMD_2 here. If we need to update more, make this a function */ |
|---|
| 832 | ulValue = BREG_Read32( |
|---|
| 833 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 834 | (in_channelHandle->ulRegStartAddr + BSCD_P_UART_CMD_2)); |
|---|
| 835 | BDBG_MSG(("orig EMVATRReceiveAndDecode: BSCD_P_UART_CMD_2 = 0x%x\n", ulValue)); |
|---|
| 836 | |
|---|
| 837 | ulValue &= (BCHP_SCA_SC_UART_CMD_2_convention_MASK); |
|---|
| 838 | |
|---|
| 839 | if (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e0 ) { |
|---|
| 840 | |
|---|
| 841 | ulValue |= (in_channelHandle->currentChannelSettings.ucRxRetries << BCHP_SCA_SC_UART_CMD_2_rpar_retry_SHIFT) | |
|---|
| 842 | (in_channelHandle->currentChannelSettings.ucTxRetries); |
|---|
| 843 | } |
|---|
| 844 | else if ( (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e1 ) || |
|---|
| 845 | (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e14_IRDETO ) ) { |
|---|
| 846 | /* No OP */ ; |
|---|
| 847 | } |
|---|
| 848 | BREG_Write32( |
|---|
| 849 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 850 | (in_channelHandle->ulRegStartAddr + BSCD_P_UART_CMD_2), |
|---|
| 851 | ulValue); |
|---|
| 852 | |
|---|
| 853 | BDBG_MSG(("EMVATRReceiveAndDecode: BSCD_P_UART_CMD_2 = 0x%x\n", ulValue)); |
|---|
| 854 | |
|---|
| 855 | |
|---|
| 856 | |
|---|
| 857 | BSCD_P_DONE_LABEL: |
|---|
| 858 | |
|---|
| 859 | |
|---|
| 860 | /* Disable timer, which was enable upon receiving atr_intr */ |
|---|
| 861 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &timer); |
|---|
| 862 | |
|---|
| 863 | /* disable WWT. This was enabled in activating time */ |
|---|
| 864 | wwtTimer.timerMode.eWaitTimerMode = BSCD_WaitTimerMode_eWorkWaitTime; |
|---|
| 865 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &wwtTimer); |
|---|
| 866 | |
|---|
| 867 | BDBG_MSG(("Leave EMVATRReceiveAndDecode errCode = 0x%x\n", errCode)); |
|---|
| 868 | BDBG_LEAVE(BSCD_Channel_P_EMVATRReceiveAndDecode); |
|---|
| 869 | return( errCode ); |
|---|
| 870 | |
|---|
| 871 | } |
|---|
| 872 | |
|---|
| 873 | BERR_Code BSCD_Channel_P_EMVValidateTSByte( |
|---|
| 874 | unsigned char in_ucTSByte |
|---|
| 875 | ) |
|---|
| 876 | { |
|---|
| 877 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 878 | |
|---|
| 879 | if (in_ucTSByte == 0x3f) { |
|---|
| 880 | BDBG_MSG(("TS = %02x, Inverse Convention\n", in_ucTSByte)); |
|---|
| 881 | return BERR_SUCCESS; |
|---|
| 882 | } |
|---|
| 883 | |
|---|
| 884 | else if (in_ucTSByte == 0x3b) { |
|---|
| 885 | BDBG_MSG(("TS = %02x, Direct Convention\n", in_ucTSByte)); |
|---|
| 886 | return BERR_SUCCESS; |
|---|
| 887 | } |
|---|
| 888 | |
|---|
| 889 | else { |
|---|
| 890 | BDBG_ERR(("TS = %02x, Unknown Convention\n", in_ucTSByte)); |
|---|
| 891 | errCode = BERR_TRACE(BSCD_STATUS_FAILED); |
|---|
| 892 | return BSCD_STATUS_FAILED; |
|---|
| 893 | } |
|---|
| 894 | } |
|---|
| 895 | |
|---|
| 896 | BERR_Code BSCD_Channel_P_EMVValidateT0Byte( |
|---|
| 897 | unsigned char ucT0Byte, |
|---|
| 898 | unsigned int *unNumHistoricalBytes |
|---|
| 899 | ) |
|---|
| 900 | { |
|---|
| 901 | *unNumHistoricalBytes = (unsigned int)(ucT0Byte & 0x0F); |
|---|
| 902 | return BERR_SUCCESS; |
|---|
| 903 | } |
|---|
| 904 | |
|---|
| 905 | BERR_Code BSCD_Channel_P_EMVValidateTA1Byte( |
|---|
| 906 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 907 | unsigned char in_ucTA1Byte |
|---|
| 908 | ) |
|---|
| 909 | { |
|---|
| 910 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 911 | unsigned char ucFfactor, ucDFactor; |
|---|
| 912 | |
|---|
| 913 | BDBG_ENTER(BSCD_Channel_P_EMVValidateTA1Byte); |
|---|
| 914 | |
|---|
| 915 | BDBG_MSG(("in_ucTA1Byte = %d\n", in_ucTA1Byte)); |
|---|
| 916 | |
|---|
| 917 | /* Decode TA1 (F and D adjustment). */ |
|---|
| 918 | ucFfactor = (in_ucTA1Byte >> 4) & 0x0f; |
|---|
| 919 | ucDFactor = in_ucTA1Byte & 0x0f; |
|---|
| 920 | |
|---|
| 921 | if ( ((ucFfactor == 1) && (ucDFactor == 1)) || |
|---|
| 922 | ((ucFfactor == 1) && (ucDFactor == 2)) || |
|---|
| 923 | ((ucFfactor == 1) && (ucDFactor == 3)) ) { |
|---|
| 924 | |
|---|
| 925 | /* |
|---|
| 926 | FOR EMV ONLY |
|---|
| 927 | Acceptable FI value is 1, acceptable DI value is 1, 2, or 3 - |
|---|
| 928 | */ |
|---|
| 929 | in_channelHandle->currentChannelSettings.ucFFactor = ucFfactor; |
|---|
| 930 | in_channelHandle->currentChannelSettings.ucDFactor = ucDFactor; |
|---|
| 931 | BDBG_MSG(("Clock rate conversion factor, ucFfactor = %1d\n",ucFfactor)); |
|---|
| 932 | BDBG_MSG(("Bit rate adjustment factor, ucDFactor = %1d\n",ucDFactor)); |
|---|
| 933 | } |
|---|
| 934 | |
|---|
| 935 | else { |
|---|
| 936 | BDBG_ERR(("Invalid adjustment factor = %02x\n",in_ucTA1Byte)); |
|---|
| 937 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 938 | } |
|---|
| 939 | |
|---|
| 940 | BSCD_P_DONE_LABEL: |
|---|
| 941 | |
|---|
| 942 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA1Byte); |
|---|
| 943 | return( errCode ); |
|---|
| 944 | |
|---|
| 945 | } |
|---|
| 946 | |
|---|
| 947 | BERR_Code BSCD_Channel_P_EMVValidateTB1Byte( |
|---|
| 948 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 949 | unsigned char in_ucTB1Byte |
|---|
| 950 | ) |
|---|
| 951 | { |
|---|
| 952 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 953 | |
|---|
| 954 | BDBG_ENTER((SmartCardValidateTB1Byte)); |
|---|
| 955 | |
|---|
| 956 | /* Decode TB1 (programming voltage) */ |
|---|
| 957 | if (in_ucTB1Byte == 0x00) { |
|---|
| 958 | /* |
|---|
| 959 | BDBG_MSG(("VPP is not connected in the ICC\n")); |
|---|
| 960 | BDBG_MSG(("No programming current\n")); |
|---|
| 961 | */ |
|---|
| 962 | } |
|---|
| 963 | |
|---|
| 964 | else { |
|---|
| 965 | /* |
|---|
| 966 | According to EMV ATR spec, in response to a warm reset, |
|---|
| 967 | the terminal shall accept an ATR containing TB1 of any value |
|---|
| 968 | */ |
|---|
| 969 | if (in_channelHandle->resetType == BSCD_ResetType_eWarm) { |
|---|
| 970 | /* |
|---|
| 971 | BDBG_ERR(("VPP is not connected in the ICC\n")); |
|---|
| 972 | BDBG_ERR(("No programming current\n")); |
|---|
| 973 | */ |
|---|
| 974 | } |
|---|
| 975 | |
|---|
| 976 | else { |
|---|
| 977 | BDBG_ERR(("Non-Zero TB1 = %02x during cold reset. Not acceptable for EMV.\n",in_ucTB1Byte)); |
|---|
| 978 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 979 | } |
|---|
| 980 | } |
|---|
| 981 | |
|---|
| 982 | |
|---|
| 983 | BSCD_P_DONE_LABEL: |
|---|
| 984 | |
|---|
| 985 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTB1Byte); |
|---|
| 986 | return( errCode ); |
|---|
| 987 | |
|---|
| 988 | } |
|---|
| 989 | |
|---|
| 990 | |
|---|
| 991 | BERR_Code BSCD_Channel_P_EMVValidateTC1Byte( |
|---|
| 992 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 993 | unsigned char in_ucTC1Byte |
|---|
| 994 | ) |
|---|
| 995 | { |
|---|
| 996 | BDBG_MSG(("In SmartCardValidateTC1Byte\n")); |
|---|
| 997 | |
|---|
| 998 | /* Decode TC1 (guard time) */ |
|---|
| 999 | if ( (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e0) && |
|---|
| 1000 | (in_ucTC1Byte == 0xff)) { |
|---|
| 1001 | |
|---|
| 1002 | /* |
|---|
| 1003 | When in T = 0 mode and ucTC1Byte == 0xff, simply set |
|---|
| 1004 | additional guardtime to zero ETUs. This is to pass the test and it is different from EMV 96. |
|---|
| 1005 | */ |
|---|
| 1006 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue = 0; |
|---|
| 1007 | |
|---|
| 1008 | } |
|---|
| 1009 | else { |
|---|
| 1010 | /* |
|---|
| 1011 | use value of ucTC1Byte for additional guardtime, |
|---|
| 1012 | regardless of T = 0 or T = 1 mode |
|---|
| 1013 | */ |
|---|
| 1014 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue = in_ucTC1Byte; |
|---|
| 1015 | } |
|---|
| 1016 | |
|---|
| 1017 | in_channelHandle->currentChannelSettings.extraGuardTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 1018 | |
|---|
| 1019 | BREG_Write32( |
|---|
| 1020 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1021 | (in_channelHandle->ulRegStartAddr + BSCD_P_TGUARD), |
|---|
| 1022 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue); |
|---|
| 1023 | |
|---|
| 1024 | BDBG_MSG(("\nSmartCardValidateTC1Byte: ulGuardTime = 0x%x \n", |
|---|
| 1025 | in_channelHandle->currentChannelSettings.extraGuardTime.ulValue)); |
|---|
| 1026 | |
|---|
| 1027 | return BERR_SUCCESS; |
|---|
| 1028 | } |
|---|
| 1029 | |
|---|
| 1030 | |
|---|
| 1031 | |
|---|
| 1032 | BERR_Code BSCD_Channel_P_EMVValidateTD1Byte( |
|---|
| 1033 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1034 | unsigned char in_ucTD1Byte, |
|---|
| 1035 | bool *outp_bTCKRequired |
|---|
| 1036 | ) |
|---|
| 1037 | { |
|---|
| 1038 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1039 | |
|---|
| 1040 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTD1Byte)); |
|---|
| 1041 | |
|---|
| 1042 | if ((in_ucTD1Byte & 0x0f) > 0x01) { |
|---|
| 1043 | |
|---|
| 1044 | /* |
|---|
| 1045 | If the lower nibble of ucTD1Byte is not equal to either 0 |
|---|
| 1046 | or 1, then return fail, otherwise return success |
|---|
| 1047 | */ |
|---|
| 1048 | BDBG_ERR(("Erroneous TD1 l.s. nibble = %02x, should be either 0x00 or 0x01\n",in_ucTD1Byte)); |
|---|
| 1049 | |
|---|
| 1050 | *outp_bTCKRequired = true; |
|---|
| 1051 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1052 | } |
|---|
| 1053 | |
|---|
| 1054 | else if ((in_ucTD1Byte & 0x0f) == 0x01) { |
|---|
| 1055 | |
|---|
| 1056 | /* set protocol type to T = 1 */ |
|---|
| 1057 | in_channelHandle->currentChannelSettings.eProtocolType = BSCD_AsyncProtocolType_e1; |
|---|
| 1058 | |
|---|
| 1059 | *outp_bTCKRequired = true; |
|---|
| 1060 | } |
|---|
| 1061 | |
|---|
| 1062 | BSCD_P_DONE_LABEL: |
|---|
| 1063 | |
|---|
| 1064 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTD1Byte); |
|---|
| 1065 | return( errCode ); |
|---|
| 1066 | } |
|---|
| 1067 | |
|---|
| 1068 | BERR_Code BSCD_Channel_P_EMVValidateTA2Byte( |
|---|
| 1069 | unsigned char in_ucTA2Byte |
|---|
| 1070 | ) |
|---|
| 1071 | { |
|---|
| 1072 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1073 | |
|---|
| 1074 | BDBG_ENTER((SmartCardValidateTA2Byte)); |
|---|
| 1075 | |
|---|
| 1076 | if ((in_ucTA2Byte & 0x10) != 0) { |
|---|
| 1077 | BDBG_ERR(("Invalid TA2 = %02x \n",in_ucTA2Byte)); |
|---|
| 1078 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1079 | } |
|---|
| 1080 | |
|---|
| 1081 | BSCD_P_DONE_LABEL: |
|---|
| 1082 | |
|---|
| 1083 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA2Byte); |
|---|
| 1084 | return( errCode ); |
|---|
| 1085 | } |
|---|
| 1086 | |
|---|
| 1087 | BERR_Code BSCD_Channel_P_EMVValidateTB2Byte( |
|---|
| 1088 | unsigned char in_ucTB2Byte |
|---|
| 1089 | ) |
|---|
| 1090 | { |
|---|
| 1091 | BSTD_UNUSED(in_ucTB2Byte); |
|---|
| 1092 | BDBG_MSG(("In SmartCardValidateTB2Byte\n")); |
|---|
| 1093 | |
|---|
| 1094 | /* TB2 is not supported by EMV, therefore return failed */ |
|---|
| 1095 | BDBG_ERR(("TB2 is present, but not required for Europay standard. Invalid ATR\n")); |
|---|
| 1096 | |
|---|
| 1097 | return BSCD_STATUS_FAILED; |
|---|
| 1098 | } |
|---|
| 1099 | |
|---|
| 1100 | BERR_Code BSCD_Channel_P_EMVValidateTC2Byte( |
|---|
| 1101 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1102 | unsigned char in_ucTC2Byte |
|---|
| 1103 | ) |
|---|
| 1104 | { |
|---|
| 1105 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1106 | |
|---|
| 1107 | BDBG_ENTER((SmartCardValidateTC2Byte)); |
|---|
| 1108 | BDBG_MSG(("In BSCD_Channel_P_EMVValidateTC2Byte\n")); |
|---|
| 1109 | |
|---|
| 1110 | /* Decode TC2. NOTE: TC2 is specific to protocol type T = 0 */ |
|---|
| 1111 | if ((in_ucTC2Byte == 0x00) || (in_ucTC2Byte > 0x0A)) { |
|---|
| 1112 | |
|---|
| 1113 | /* Reject ATR if TC2 is equal to '0x00' or greater than '0x0A' */ |
|---|
| 1114 | BDBG_ERR(("Invalid TC2 = %02x \n",in_ucTC2Byte)); |
|---|
| 1115 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1116 | } |
|---|
| 1117 | |
|---|
| 1118 | else { |
|---|
| 1119 | /* Reset work waiting time, using valid TC2 Value */ |
|---|
| 1120 | /* Specify work wait time used for T = 0 protocol */ |
|---|
| 1121 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 1122 | BSCD_P_AdjustWWT(in_channelHandle, |
|---|
| 1123 | in_channelHandle->currentChannelSettings.ucFFactor, |
|---|
| 1124 | in_channelHandle->currentChannelSettings.ucDFactor, |
|---|
| 1125 | in_ucTC2Byte)); |
|---|
| 1126 | |
|---|
| 1127 | } |
|---|
| 1128 | |
|---|
| 1129 | |
|---|
| 1130 | BSCD_P_DONE_LABEL: |
|---|
| 1131 | |
|---|
| 1132 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTC2Byte); |
|---|
| 1133 | return( errCode ); |
|---|
| 1134 | } |
|---|
| 1135 | |
|---|
| 1136 | BERR_Code BSCD_Channel_P_EMVValidateTD2Byte( |
|---|
| 1137 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1138 | unsigned char in_ucTD2Byte, |
|---|
| 1139 | unsigned char in_ucTD1Byte, |
|---|
| 1140 | bool * outp_bTCKRequired |
|---|
| 1141 | ) |
|---|
| 1142 | { |
|---|
| 1143 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1144 | |
|---|
| 1145 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTD2Byte)); |
|---|
| 1146 | |
|---|
| 1147 | BSTD_UNUSED(in_channelHandle); |
|---|
| 1148 | if ((in_ucTD1Byte & 0x0F) == 0x00) { |
|---|
| 1149 | |
|---|
| 1150 | if (((in_ucTD2Byte & 0x0F) != 0x0E) && ((in_ucTD2Byte & 0x0F) != 0x01)) { |
|---|
| 1151 | /* |
|---|
| 1152 | If l.s. nibble of TD1 is '0', then l.s. nibble of TD2 |
|---|
| 1153 | must equal '0xE' or 0x01 |
|---|
| 1154 | */ |
|---|
| 1155 | BDBG_ERR(("Failing in SmartCardValidateTD2Byte - TD2 != 0x0E \n")); |
|---|
| 1156 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1157 | |
|---|
| 1158 | } |
|---|
| 1159 | |
|---|
| 1160 | else { |
|---|
| 1161 | *outp_bTCKRequired = true; |
|---|
| 1162 | goto BSCD_P_DONE_LABEL; |
|---|
| 1163 | } |
|---|
| 1164 | } |
|---|
| 1165 | |
|---|
| 1166 | else if ((in_ucTD1Byte & 0x0F) == 0x01) { |
|---|
| 1167 | |
|---|
| 1168 | if ((in_ucTD2Byte & 0x0F) != 0x01) { |
|---|
| 1169 | |
|---|
| 1170 | /* |
|---|
| 1171 | If l.s. nibble of TD1 is '1', then l.s. nibble of TD2 must |
|---|
| 1172 | equal '0x01' |
|---|
| 1173 | */ |
|---|
| 1174 | BDBG_MSG(("Failing in SmartCardValidateTD2Byte - TD2 != 0x01 \n")); |
|---|
| 1175 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1176 | } |
|---|
| 1177 | } |
|---|
| 1178 | |
|---|
| 1179 | BSCD_P_DONE_LABEL: |
|---|
| 1180 | |
|---|
| 1181 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTD2Byte); |
|---|
| 1182 | return( errCode ); |
|---|
| 1183 | } |
|---|
| 1184 | |
|---|
| 1185 | |
|---|
| 1186 | BERR_Code BSCD_Channel_P_EMVValidateTA3Byte( |
|---|
| 1187 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1188 | unsigned char in_ucTA3Byte |
|---|
| 1189 | ) |
|---|
| 1190 | { |
|---|
| 1191 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1192 | |
|---|
| 1193 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTA3Byte)); |
|---|
| 1194 | /* Decode TA3. */ |
|---|
| 1195 | if ((in_ucTA3Byte <= 0x0f) || (in_ucTA3Byte == 0xff)) { |
|---|
| 1196 | |
|---|
| 1197 | BDBG_ERR(("Invalid EMV TA3 = %02x \n",in_ucTA3Byte)); |
|---|
| 1198 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1199 | } |
|---|
| 1200 | |
|---|
| 1201 | else { |
|---|
| 1202 | in_channelHandle->currentChannelSettings.unCurrentIFSD = in_ucTA3Byte; |
|---|
| 1203 | } |
|---|
| 1204 | |
|---|
| 1205 | BSCD_P_DONE_LABEL: |
|---|
| 1206 | |
|---|
| 1207 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA3Byte); |
|---|
| 1208 | return( errCode ); |
|---|
| 1209 | |
|---|
| 1210 | } |
|---|
| 1211 | |
|---|
| 1212 | BERR_Code BSCD_Channel_P_EMVValidateTB3Byte( |
|---|
| 1213 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1214 | unsigned char in_ucTB3Byte, |
|---|
| 1215 | unsigned char in_ucFFactor, |
|---|
| 1216 | unsigned char in_ucDFactor |
|---|
| 1217 | ) |
|---|
| 1218 | { |
|---|
| 1219 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1220 | uint32_t ulGuardTime, ulGuardTimePlusOne, ulCWTValue, ulBlockWaitTime; |
|---|
| 1221 | unsigned char ucCWIVal, ucBWIVal; |
|---|
| 1222 | unsigned char ucBaudDiv, ucClkDiv; |
|---|
| 1223 | unsigned int unCWICheck; |
|---|
| 1224 | |
|---|
| 1225 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTB3Byte)); |
|---|
| 1226 | |
|---|
| 1227 | if (in_channelHandle->currentChannelSettings.eProtocolType == BSCD_AsyncProtocolType_e1) { |
|---|
| 1228 | |
|---|
| 1229 | /* Decode TB3. */ |
|---|
| 1230 | ucCWIVal = in_ucTB3Byte & 0x0f; |
|---|
| 1231 | ucBWIVal = (in_ucTB3Byte >> 4) & 0x0f; |
|---|
| 1232 | |
|---|
| 1233 | /* |
|---|
| 1234 | Obtain the power(2,CWI) factor from the value of |
|---|
| 1235 | CWI - see TB3 in EMV'96 spec for more |
|---|
| 1236 | */ |
|---|
| 1237 | if (ucCWIVal == 0x00) { |
|---|
| 1238 | unCWICheck = 1; |
|---|
| 1239 | } |
|---|
| 1240 | else { |
|---|
| 1241 | unCWICheck = 2<<(ucCWIVal-1); |
|---|
| 1242 | } |
|---|
| 1243 | |
|---|
| 1244 | /* Obtain guard time for comparison check below */ |
|---|
| 1245 | ulGuardTime = in_channelHandle->currentChannelSettings.extraGuardTime.ulValue ; |
|---|
| 1246 | |
|---|
| 1247 | /* |
|---|
| 1248 | Note: if ulGuardTime = 0xFF, then unGuardTimePlusOne = 0, |
|---|
| 1249 | according to EMV ATR rules P. I-28 |
|---|
| 1250 | */ |
|---|
| 1251 | if (ulGuardTime == 0xff) |
|---|
| 1252 | ulGuardTimePlusOne = 0; |
|---|
| 1253 | else |
|---|
| 1254 | ulGuardTimePlusOne = ulGuardTime + 1; |
|---|
| 1255 | |
|---|
| 1256 | |
|---|
| 1257 | /* |
|---|
| 1258 | Terminal shall reject ATR not containing TB3, or |
|---|
| 1259 | containing TB3 indicating BWI greater than 4 and/or |
|---|
| 1260 | CWI greater than 5, or power(2,CWI) < (N+1), where |
|---|
| 1261 | N is value of TC1 |
|---|
| 1262 | */ |
|---|
| 1263 | /*EMV2000*/ |
|---|
| 1264 | if ((ucCWIVal > 5) || (ucBWIVal > 4) || |
|---|
| 1265 | (unCWICheck <= ulGuardTimePlusOne)) { |
|---|
| 1266 | |
|---|
| 1267 | BDBG_MSG (("ucCWIVal = 0x%02x, ucBWIVal = 0x%02x, unCWICheck = %02d, guard_time = 0x%02x, ulGuardTimePlusOne=%ld\n", |
|---|
| 1268 | ucCWIVal, ucBWIVal, unCWICheck, ulGuardTime, ulGuardTimePlusOne)); |
|---|
| 1269 | BDBG_ERR(("Invalid TB3 = %02x \n",in_ucTB3Byte)); |
|---|
| 1270 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1271 | |
|---|
| 1272 | } |
|---|
| 1273 | |
|---|
| 1274 | else { |
|---|
| 1275 | |
|---|
| 1276 | |
|---|
| 1277 | /* Set CWT */ |
|---|
| 1278 | ulCWTValue = BREG_Read32( |
|---|
| 1279 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1280 | (in_channelHandle->ulRegStartAddr + BSCD_P_PROTO_CMD)); |
|---|
| 1281 | |
|---|
| 1282 | /* |
|---|
| 1283 | and with 0xf0 to remove the original 0x0f inserted |
|---|
| 1284 | into this register |
|---|
| 1285 | */ |
|---|
| 1286 | ulCWTValue &= 0xf0; |
|---|
| 1287 | ulCWTValue |= ucCWIVal; |
|---|
| 1288 | in_channelHandle->currentChannelSettings.ulCharacterWaitTimeInteger = ucCWIVal; |
|---|
| 1289 | |
|---|
| 1290 | |
|---|
| 1291 | #ifdef BSCD_EMV2000_CWT_PLUS_4 |
|---|
| 1292 | if ( (in_channelHandle->currentChannelSettings.scStandard != BSCD_Standard_eEMV2000) || |
|---|
| 1293 | (in_channelHandle->currentChannelSettings.eProtocolType != BSCD_AsyncProtocolType_e1)) { |
|---|
| 1294 | #endif |
|---|
| 1295 | BREG_Write32( |
|---|
| 1296 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1297 | (in_channelHandle->ulRegStartAddr + BSCD_P_PROTO_CMD), |
|---|
| 1298 | ulCWTValue); |
|---|
| 1299 | |
|---|
| 1300 | #ifdef BSCD_EMV2000_CWT_PLUS_4 |
|---|
| 1301 | } |
|---|
| 1302 | #endif |
|---|
| 1303 | |
|---|
| 1304 | BDBG_MSG(("ulCWTValue = 0x%x\n", ulCWTValue)); |
|---|
| 1305 | |
|---|
| 1306 | |
|---|
| 1307 | /* set BWT */ |
|---|
| 1308 | /* |
|---|
| 1309 | The block waiting time is encoded as described in ISO 7816-3, |
|---|
| 1310 | repeated here in the following equation: |
|---|
| 1311 | |
|---|
| 1312 | BWT = [11 + 2 bwi x 960 x 372 x D/F] etu |
|---|
| 1313 | |
|---|
| 1314 | e.g If bwi = 4 and F/D = 372 then BWT = 15,371 etu. |
|---|
| 1315 | The minimum and maximum BWT are ~186 and 15,728,651 etu. |
|---|
| 1316 | */ |
|---|
| 1317 | in_channelHandle->currentChannelSettings.unPrescale = |
|---|
| 1318 | BSCD_P_GetPrescale(in_channelHandle, in_ucDFactor, in_ucFFactor) * |
|---|
| 1319 | in_channelHandle->currentChannelSettings.ucExternalClockDivisor + |
|---|
| 1320 | (in_channelHandle->currentChannelSettings.ucExternalClockDivisor - 1); |
|---|
| 1321 | |
|---|
| 1322 | |
|---|
| 1323 | ucBaudDiv = BSCD_P_GetBaudDiv(in_channelHandle, in_ucDFactor, in_ucFFactor); |
|---|
| 1324 | ucClkDiv = BSCD_P_GetClkDiv(in_channelHandle, in_ucDFactor, in_ucFFactor); |
|---|
| 1325 | |
|---|
| 1326 | if (ucBWIVal == 0x00) { |
|---|
| 1327 | |
|---|
| 1328 | ulBlockWaitTime = 960 * 372 * ucClkDiv / |
|---|
| 1329 | (in_channelHandle->currentChannelSettings.unPrescale+1) / ucBaudDiv + 11; |
|---|
| 1330 | } |
|---|
| 1331 | |
|---|
| 1332 | else { |
|---|
| 1333 | |
|---|
| 1334 | ulBlockWaitTime = (2<<(ucBWIVal-1)) * 960 * 372 * |
|---|
| 1335 | ucClkDiv / (in_channelHandle->currentChannelSettings.unPrescale+1) / ucBaudDiv + 11; |
|---|
| 1336 | } |
|---|
| 1337 | |
|---|
| 1338 | BDBG_MSG (("In SmartCardValidateTB3Byte: unBlockWaitTime = %d, ulClkDiv = 0x%02x\n", |
|---|
| 1339 | ulBlockWaitTime, ucClkDiv)); |
|---|
| 1340 | |
|---|
| 1341 | BDBG_MSG (("In SmartCardValidateTB3Byte: ulPrescale = 0x%02x, ucBaudDiv = 0x%02x\n", |
|---|
| 1342 | in_channelHandle->currentChannelSettings.unPrescale, ucBaudDiv)); |
|---|
| 1343 | |
|---|
| 1344 | |
|---|
| 1345 | /* Change timer to equal calculated BWT */ |
|---|
| 1346 | if (in_channelHandle->currentChannelSettings.scStandard == BSCD_Standard_eEMV2000) |
|---|
| 1347 | in_channelHandle->currentChannelSettings.blockWaitTime.ulValue = ulBlockWaitTime + |
|---|
| 1348 | BSCD_P_GetISOBaudRateAdjustor(in_channelHandle->currentChannelSettings.ucDFactor) * |
|---|
| 1349 | BSCD_DEFAULT_EXTRA_BLOCK_WAITING_TIME_EMV2000; |
|---|
| 1350 | else |
|---|
| 1351 | in_channelHandle->currentChannelSettings.blockWaitTime.ulValue = ulBlockWaitTime ; |
|---|
| 1352 | in_channelHandle->currentChannelSettings.blockWaitTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 1353 | |
|---|
| 1354 | BDBG_MSG (("TB3, blockWaitTime = %ld\n", |
|---|
| 1355 | in_channelHandle->currentChannelSettings.blockWaitTime.ulValue)); |
|---|
| 1356 | |
|---|
| 1357 | /* Need this for MetroWerks */ |
|---|
| 1358 | /* |
|---|
| 1359 | timer.eTimerType = BSCD_TimerType_eWaitTimer; |
|---|
| 1360 | timer.timerMode.eWaitTimerMode = BSCD_WaitTimerMode_eBlockWaitTime; |
|---|
| 1361 | |
|---|
| 1362 | timeValue.ulValue = in_channelHandle->currentChannelSettings.blockWaitTime.ulValue ; |
|---|
| 1363 | |
|---|
| 1364 | BSCD_P_CHECK_ERR_CODE_FUNC(errCode, |
|---|
| 1365 | BSCD_Channel_ConfigTimer(in_channelHandle, &timer, &timeValue)); |
|---|
| 1366 | */ |
|---|
| 1367 | } |
|---|
| 1368 | } /* eProtocolType == BSCD_AsyncProtocolType_e1 */ |
|---|
| 1369 | |
|---|
| 1370 | BSCD_P_DONE_LABEL: |
|---|
| 1371 | |
|---|
| 1372 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTB3Byte); |
|---|
| 1373 | return( errCode ); |
|---|
| 1374 | } |
|---|
| 1375 | |
|---|
| 1376 | BERR_Code BSCD_Channel_P_EMVValidateTC3Byte( |
|---|
| 1377 | unsigned char in_ucTC3Byte |
|---|
| 1378 | ) |
|---|
| 1379 | { |
|---|
| 1380 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1381 | |
|---|
| 1382 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTC3Byte)); |
|---|
| 1383 | BDBG_MSG(("In BSCD_Channel_P_EMVValidateTC3Byte = 0x%02x\n", in_ucTC3Byte)); |
|---|
| 1384 | |
|---|
| 1385 | /* Terminal shall reject ATR containing non-zero TC3 Byte */ |
|---|
| 1386 | if (in_ucTC3Byte != 0) { |
|---|
| 1387 | BDBG_ERR(("Failing in SmartCardValidateTC3Byte \n")); |
|---|
| 1388 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1389 | } |
|---|
| 1390 | |
|---|
| 1391 | BSCD_P_DONE_LABEL: |
|---|
| 1392 | |
|---|
| 1393 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTC3Byte); |
|---|
| 1394 | return( errCode ); |
|---|
| 1395 | |
|---|
| 1396 | } |
|---|
| 1397 | |
|---|
| 1398 | BERR_Code BSCD_Channel_P_EMVValidateTCKByte( |
|---|
| 1399 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1400 | unsigned char *inp_ucATR, |
|---|
| 1401 | unsigned int in_unATRLength |
|---|
| 1402 | ) |
|---|
| 1403 | { |
|---|
| 1404 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1405 | |
|---|
| 1406 | unsigned char ucTCKCompare = 0; |
|---|
| 1407 | unsigned int i; |
|---|
| 1408 | |
|---|
| 1409 | BDBG_ENTER((BSCD_Channel_P_EMVValidateTCKByte)); |
|---|
| 1410 | BSTD_UNUSED(in_channelHandle); |
|---|
| 1411 | |
|---|
| 1412 | /* Start from T0 to TCK. Including historical bytes if they exist */ |
|---|
| 1413 | for (i=1; i<=in_unATRLength; i++) { |
|---|
| 1414 | ucTCKCompare = ucTCKCompare ^ inp_ucATR[i]; |
|---|
| 1415 | BDBG_MSG(("In SmartCardValidateTCKByte inp_ucATR[%d] = %02x\n", i, inp_ucATR[i])); |
|---|
| 1416 | } |
|---|
| 1417 | |
|---|
| 1418 | if (ucTCKCompare != 0) { |
|---|
| 1419 | BDBG_ERR(("Invalid TCK. \n")); |
|---|
| 1420 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_DEACTIVATE, true); |
|---|
| 1421 | } |
|---|
| 1422 | |
|---|
| 1423 | /* TCK validated successfully */ |
|---|
| 1424 | BSCD_P_DONE_LABEL: |
|---|
| 1425 | |
|---|
| 1426 | BDBG_LEAVE(BSCD_Channel_P_EMVValidateTCKByte); |
|---|
| 1427 | return( errCode ); |
|---|
| 1428 | } |
|---|
| 1429 | |
|---|
| 1430 | BERR_Code BSCD_Channel_P_EMVATRByteRead( |
|---|
| 1431 | BSCD_ChannelHandle in_channelHandle, |
|---|
| 1432 | unsigned char *inoutp_ucData, |
|---|
| 1433 | unsigned long in_ulMaxAtrByteTimeInETU, |
|---|
| 1434 | long in_lMaxTotalAtrByteTimeInETU, |
|---|
| 1435 | unsigned long *inoutp_ultotalAtrByteTimeInETU |
|---|
| 1436 | ) |
|---|
| 1437 | { |
|---|
| 1438 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 1439 | uint32_t ulTimerCntVal1, ulTimerCntVal2, ulTimerCntVal; |
|---|
| 1440 | uint32_t ulStatus; |
|---|
| 1441 | BSCD_Timer timer = {BSCD_TimerType_eGPTimer, {BSCD_GPTimerMode_eIMMEDIATE}, false, false}; |
|---|
| 1442 | /* BSCD_TimerValue timeValue= {BSCD_MAX_ETU_PER_ATR_BYTE, BSCD_TimerUnit_eETU}; */ |
|---|
| 1443 | |
|---|
| 1444 | BSCD_Timer wwtTimer = {BSCD_TimerType_eWaitTimer, {BSCD_GPTimerMode_eIMMEDIATE}, false, false}; |
|---|
| 1445 | |
|---|
| 1446 | BDBG_ENTER(BSCD_Channel_P_EMVATRByteRead); |
|---|
| 1447 | |
|---|
| 1448 | BSTD_UNUSED(in_ulMaxAtrByteTimeInETU); |
|---|
| 1449 | |
|---|
| 1450 | BKNI_EnterCriticalSection(); |
|---|
| 1451 | ulStatus = in_channelHandle->ulStatus2 = BREG_Read32( |
|---|
| 1452 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1453 | (in_channelHandle->ulRegStartAddr + BSCD_P_STATUS_2)); |
|---|
| 1454 | BDBG_MSG(("Status2 = 0x%x\n", ulStatus)); |
|---|
| 1455 | BKNI_LeaveCriticalSection(); |
|---|
| 1456 | |
|---|
| 1457 | if ((ulStatus & BCHP_SCA_SC_STATUS_2_rempty_MASK) == BCHP_SCA_SC_STATUS_2_rempty_MASK) { |
|---|
| 1458 | |
|---|
| 1459 | /* Do not have any byte in SC_RECEIVE */ |
|---|
| 1460 | |
|---|
| 1461 | if ( (errCode = BSCD_Channel_P_WaitForRcv(in_channelHandle)) != BERR_SUCCESS) { |
|---|
| 1462 | |
|---|
| 1463 | /* disable the timer, always return the previous error */ |
|---|
| 1464 | |
|---|
| 1465 | /* Disable timer, which was enable upon receiving atr_intr */ |
|---|
| 1466 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &timer); |
|---|
| 1467 | |
|---|
| 1468 | /* disable WWT. This was enabled in activating time */ |
|---|
| 1469 | wwtTimer.timerMode.eWaitTimerMode = BSCD_WaitTimerMode_eWorkWaitTime; |
|---|
| 1470 | BSCD_Channel_EnableDisableTimer_isr(in_channelHandle, &wwtTimer); |
|---|
| 1471 | |
|---|
| 1472 | /* Read timer counter and accumulate it to *inoutp_ultotalAtrByteTimeInETU */ |
|---|
| 1473 | ulTimerCntVal2 = BREG_Read32( |
|---|
| 1474 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1475 | (in_channelHandle->ulRegStartAddr + BSCD_P_TIMER_CNT_2)); |
|---|
| 1476 | |
|---|
| 1477 | ulTimerCntVal1= BREG_Read32( |
|---|
| 1478 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1479 | (in_channelHandle->ulRegStartAddr + BSCD_P_TIMER_CNT_1)); |
|---|
| 1480 | |
|---|
| 1481 | ulTimerCntVal = (((unsigned int) ulTimerCntVal2) << 8) | ulTimerCntVal1; |
|---|
| 1482 | |
|---|
| 1483 | *inoutp_ultotalAtrByteTimeInETU += ulTimerCntVal; |
|---|
| 1484 | |
|---|
| 1485 | if (*inoutp_ultotalAtrByteTimeInETU > (unsigned long) in_lMaxTotalAtrByteTimeInETU) { |
|---|
| 1486 | BDBG_MSG(("SmartCardATRByteRead: inoutp_ultotalAtrByteTimeInETU = %lu , in_lMaxTotalAtrByteTimeInETU = %d\n", |
|---|
| 1487 | *inoutp_ultotalAtrByteTimeInETU, in_lMaxTotalAtrByteTimeInETU)); |
|---|
| 1488 | BSCD_P_CHECK_ERR_CODE_CONDITION(errCode, BSCD_STATUS_FAILED, true); |
|---|
| 1489 | } |
|---|
| 1490 | |
|---|
| 1491 | BDBG_MSG(("After WaitForRcv in EMVATRByteRead errCode = 0x%x\n", errCode)); |
|---|
| 1492 | return errCode; |
|---|
| 1493 | } |
|---|
| 1494 | |
|---|
| 1495 | } |
|---|
| 1496 | |
|---|
| 1497 | else { |
|---|
| 1498 | BKNI_EnterCriticalSection(); |
|---|
| 1499 | in_channelHandle->ulIntrStatus2 &= ~BCHP_SCA_SC_INTR_STAT_2_rcv_intr_MASK; |
|---|
| 1500 | BKNI_LeaveCriticalSection(); |
|---|
| 1501 | BDBG_MSG(("Cancel out RCV_INTR, pSc_intrStatus2 = 0x%x\n", |
|---|
| 1502 | in_channelHandle->ulIntrStatus2)); |
|---|
| 1503 | } |
|---|
| 1504 | |
|---|
| 1505 | *inoutp_ucData = (unsigned char) BREG_Read32( |
|---|
| 1506 | in_channelHandle->moduleHandle->regHandle, |
|---|
| 1507 | (in_channelHandle->ulRegStartAddr + BSCD_P_RECEIVE)); |
|---|
| 1508 | |
|---|
| 1509 | BDBG_MSG(("atr = 0x%x\n", *inoutp_ucData)); |
|---|
| 1510 | |
|---|
| 1511 | BSCD_P_DONE_LABEL: |
|---|
| 1512 | |
|---|
| 1513 | BDBG_LEAVE(BSCD_Channel_P_EMVATRByteRead); |
|---|
| 1514 | BDBG_MSG(("Leave EMVATRByteRead errCode = 0x%x\n", errCode)); |
|---|
| 1515 | return( errCode ); |
|---|
| 1516 | } |
|---|
| 1517 | |
|---|