source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/scd/7552/bscd_emvpriv.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 45.7 KB
Line 
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
85BDBG_MODULE(BSCD);
86
87BERR_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        }
172BSCD_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
180BERR_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
276BERR_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       
857BSCD_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
873BERR_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
896BERR_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
905BERR_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       
940BSCD_P_DONE_LABEL:
941       
942        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA1Byte);
943        return( errCode );
944       
945}
946
947BERR_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       
983BSCD_P_DONE_LABEL:
984       
985        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTB1Byte);
986        return( errCode );
987       
988}
989
990
991BERR_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
1032BERR_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
1062BSCD_P_DONE_LABEL:
1063       
1064        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTD1Byte);
1065        return( errCode );
1066}
1067
1068BERR_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
1081BSCD_P_DONE_LABEL:
1082       
1083        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA2Byte);
1084        return( errCode );
1085}
1086
1087BERR_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
1100BERR_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
1130BSCD_P_DONE_LABEL:
1131       
1132        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTC2Byte);
1133        return( errCode );
1134}
1135
1136BERR_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
1179BSCD_P_DONE_LABEL:
1180       
1181        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTD2Byte);
1182        return( errCode );
1183}
1184
1185
1186BERR_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       
1205BSCD_P_DONE_LABEL:
1206       
1207        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTA3Byte);
1208        return( errCode );
1209       
1210}
1211
1212BERR_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       
1370BSCD_P_DONE_LABEL:
1371       
1372        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTB3Byte);
1373        return( errCode );
1374}
1375
1376BERR_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
1391BSCD_P_DONE_LABEL:
1392       
1393        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTC3Byte);
1394        return( errCode );
1395
1396}
1397
1398BERR_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 */
1424BSCD_P_DONE_LABEL:
1425       
1426        BDBG_LEAVE(BSCD_Channel_P_EMVValidateTCKByte);
1427        return( errCode );
1428}
1429
1430BERR_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
1511BSCD_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
Note: See TracBrowser for help on using the repository browser.