source: svn/trunk/newcon3bcm2_21bu/nexus/modules/smartcard/7552/src/nexus_smartcard.c

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

first commit

  • Property svn:executable set to *
File size: 34.8 KB
Line 
1/***************************************************************************
2 *     (c)2007-2011 Broadcom Corporation
3 *
4 *  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 *  and may only be used, duplicated, modified or distributed pursuant to the terms and
6 *  conditions of a separate, written license agreement executed between you and Broadcom
7 *  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 *  no license (express or implied), right to use, or waiver of any kind with respect to the
9 *  Software, and Broadcom expressly reserves all rights in and to the Software and all
10 *  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 *  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 *  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 *  Except as expressly set forth in the Authorized License,
15 *
16 *  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 *  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 *  and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 *  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 *  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 *  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 *  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 *  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 *  USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 *  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 *  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 *  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 *  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 *  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 *  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 *  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 *  ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: nexus_smartcard.c $
39 * $brcm_Revision: 44 $
40 * $brcm_Date: 12/1/11 4:43p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/smartcard/7425/src/nexus_smartcard.c $
47 *
48 * 44   12/1/11 4:43p jtna
49 * SW7425-1708: add comment about app having to call
50 *  NEXUS_Smartcard_SetSettings() after resume
51 *
52 * 43   11/7/11 12:25p vishk
53 * SW7405-5152: Nexus smartcard module error when ATR bytes actually read
54 *  is less than what is expected
55 *
56 * 42   8/3/11 11:09a gmohile
57 * SW7125-1014 : Add module to active priority scheduler
58 *
59 * 41   7/21/11 4:14p gmohile
60 * SW7125-1014 : Rework power management
61 *
62 * SW7125-1014/1   7/20/11 4:37p gmohile
63 * SW7125-1014 : Rework power management
64 *
65 * 40   5/26/11 3:53p vishk
66 * SW7346-228: Add support for the new attribute BSCD_ResetWaitCycles in
67 *  BSCD_ChannelSettings to NEXUS
68 *
69 * 39   5/26/11 3:52p vishk
70 * SW7346-228: Add support for the new attribute BSCD_ResetWaitCycles in
71 *  BSCD_ChannelSettings to NEXUS
72 *
73 * 38   4/28/11 8:15a vishk
74 * SW7405-5152: Nexus smartcard module error when ATR bytes actually read
75 *  is less than what is expected Bug fix pertaining to the logic when
76 *  bytes expected is equall to bytes read.
77 *
78 * 37   4/21/11 5:01p VISHK
79 * SW7405-5152: Nexus smartcard module error when ATR bytes actually read
80 *  is less than what is expected.
81 *
82 * 36   4/21/11 3:50p VISHK
83 * SW7405-5152: Nexus smartcard module error when ATR bytes actually read
84 *  is less than what is expected.
85 *
86 * 35   4/20/11 6:15p jtna
87 * SW7425-365: fix build warnings for 2.6.37 kernel
88 *
89 * 34   4/13/11 11:55a VISHK
90 * SW7346-138: NEXUS Smartcard settings need to be able to set the
91 *  BSCD_ChannelSettings.ATRRecvTimeInteger parameter Fix compile errors.
92 *
93 * 33   4/13/11 10:21a VISHK
94 * SW7346-138: NEXUS Smartcard settings need to be able to set the
95 *  BSCD_ChannelSettings.ATRRecvTimeInteger parameter Set the default
96 *  parameters.
97 *
98 * 32   4/11/11 4:54p vishk
99 * SW7346-138: NEXUS Smartcard settings need to be able to set the
100 *  BSCD_ChannelSettings.ATRRecvTimeInteger parameter
101 *
102 * 31   4/8/11 12:39p erickson
103 * SW7405-5210: add NEXUS_SmartcardStatus.iccClockFrequency
104 *
105 * 30   3/3/11 12:38p VISHK
106 * SW7408-210 : Add standby support
107 *
108 * 29   3/1/11 5:38p gmohile
109 * SW7408-210 : Add standby support
110 *
111 * 28   2/25/11 2:39p vishk
112 * SW7405-5152: Nexus smartcard module error when ATR bytes actually read
113 *  is less than what is expected.
114 *
115 * 27   2/7/11 4:28p VISHK
116 * SW7346-25: Allow CLK Freq configuration in Nexus.  Initialize and set
117 *  source clock frequency per smartcard channel. The frequency can be
118 *  changed dynamically hence its also applied in
119 *  NEXUS_Smartcard_SetSettings().
120 *
121 * 26   2/7/11 9:52a erickson
122 * SW7400-2841: fix vcc default, fix bounds check in NEXUS_Smartcard_Open,
123 *  add memset to GetStatus to future-proof
124 *
125 * 25   12/8/10 7:40a VISHK
126 * SW7342-321: Allow the function NEXUS_Smartcard_ResetCard to be called
127 *  without any data having to be read.
128 *
129 * 24   8/24/10 3:41p VISHK
130 * SW7125-598:  Need to add the IFSI param interface in
131 *  NEXUS_Smartcard_SetSettings
132 *
133 * 23   8/16/10 4:41p VISHK
134 * SW7405-4023: SMARTCARD: Support card deactivation
135 *
136 * 22   8/10/10 6:22p VISHK
137 * SW7335-811: NEXUS_Smartcard_PowerIcc does not account for TDA8024
138 *  presence.  To Toggle power up and down as the coupling chip TDA8024 is
139 *  active LOW.
140 *
141 * 21   8/3/10 10:51a VISHK
142 * SW7125-478: NEXUS_Smartcard_SetParamsFromAtr() is not completed.
143 *  Currently the ATR(answer to reset) is passed through to the
144 *  application. Its the resposibility of the application to decode the
145 *  atr.  But, once decoded, the application can use
146 *  NEXUS_Smartcard_SetSettings() to set the desired parameters. So,
147 *  deleting the api NEXUS_Smartcard_SetParamsFromAtr() as it is
148 *  redundant. Please refer to the smartcard.c and smartcard_t1.c in
149 *  nexus/examples/io for further details as to how to decode the ATR.
150 *
151 * 20   5/29/10 11:07a VISHK
152 * SW7325-753: Smartcard: Irdeto Smartcard settings is not set correctly
153 *
154 * 19   2/16/10 10:33a VISHK
155 * SW7400-2689: NEXUS smartcard module needs to use the
156 *  NEXUS_SmartcardSettings to open the smartcard channel.
157 *
158 * 18   2/16/10 10:32a VISHK
159 * SW7400-2689: NEXUS smartcard module needs to use the
160 *  NEXUS_SmartcardSettings to open the smartcard channel.
161 *
162 * 17   2/11/10 12:35p VISHK
163 * SW7400-2689: NEXUS smartcard module needs to use the
164 *  NEXUS_SmartcardSettings to open the smartcard channel.
165 *
166 * 16   2/8/10 4:32p VISHK
167 * SW7400-2610: The NEXU Smartcard API needs to add support for two new
168 *  smartcard parameters setPinmuxCb and setVccCb;
169 *
170 * 15   1/26/10 1:59p VISHK
171 * SW7400-2551: The NEXUS Smartcard module needs to add support for power
172 *  up/down of the smartcard inteface.
173 *
174 * 14   1/26/10 11:17a VISHK
175 * SW7400-2610: The NEXU Smartcard API needs to add support for two new
176 *  smartcard parameters setPinmuxCb and setVccCb;
177 *
178 * 13   10/28/09 4:09p vishk
179 * SW7400-2551: The NEXUS Smartcard module needs to add support for power
180 *  up/down of the smartcard inteface.
181 *
182 * 12   9/30/09 3:47p vishk
183 * SW7400-2551: The NEXUS Smartcard module needs to add support for power
184 *  up/down of the smartcard inteface.
185 *
186 * 11   7/20/09 5:55p vishk
187 * PR 54381: Nexus smartcard module setting not configurable
188 *
189 * 10   5/22/09 5:08p vishk
190 * PR 54381: Nexus smartcard module setting not configurable
191 *
192 * 9   5/1/09 5:33p vishk
193 * PR 54381: Nexus smartcard module setting not configurable
194 *
195 * 9   5/1/09 5:27p vishk
196 * PR 54381: Nexus smartcard module setting not configurable
197 *
198 * 8   4/21/09 11:42a vishk
199 * PR 54381: Nexus smartcard module setting not configurable
200 *
201 * 7   4/20/09 3:18p vishk
202 * PR 54381: Nexus smartcard module setting not configurable
203 *
204 * 6   1/26/09 12:06p erickson
205 * PR51468: global variable naming convention
206 *
207 * 5   1/26/09 11:30a erickson
208 * PR51468: global variable naming convention
209 *
210 * 4   9/3/08 10:06a vishk
211 * PR 45615: ISO smartcard channel settings not correct and not
212 *  configurable.
213 * PR 29851: Smartcard functions need to allow more parameter changes
214 *
215 * 3   8/19/08 3:18p vishk
216 * PR 45615: ISO smartcard channel settings not correct and not
217 *  configurable.
218 * PR 29851: Smartcard functions need to allow more parameter changes
219 *
220 * 2   8/19/08 1:59p vishk
221 * PR 45615: ISO smartcard channel settings not correct and not
222 *  configurable.
223 * PR 29851: Smartcard functions need to allow more parameter changes
224 *
225 * 1   5/19/08 12:05p vishk
226 * PR 40034: Develop Nexus Smartcard Interface/Module.
227 *
228 **************************************************************************/
229#include "nexus_smartcard_module.h"
230#include "bscd.h"
231#include "bscd_datatypes.h"
232#include "priv/nexus_core.h"
233#include "nexus_platform_features.h"
234
235BDBG_MODULE(nexus_smartcard);
236
237NEXUS_ModuleHandle g_NEXUS_smartcardModule;
238
239struct {
240    NEXUS_SmartcardModuleSettings settings;
241    BSCD_Handle scd;
242} g_NEXUS_smartcard;
243
244/****************************************
245* Module functions
246***************/
247
248void NEXUS_SmartcardModule_GetDefaultSettings(NEXUS_SmartcardModuleSettings *pSettings)
249{
250    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
251}
252
253NEXUS_ModuleHandle NEXUS_SmartcardModule_Init(const NEXUS_SmartcardModuleSettings *pSettings)
254{
255    BSCD_Settings scdSettings;
256    NEXUS_Error errCode;
257    NEXUS_ModuleSettings moduleSettings;
258
259    BDBG_ASSERT(!g_NEXUS_smartcardModule);
260    NEXUS_Module_GetDefaultSettings(&moduleSettings);
261    moduleSettings.priority = NEXUS_ModulePriority_eLowActiveStandby;
262    g_NEXUS_smartcardModule = NEXUS_Module_Create("smartcard", &moduleSettings);
263    if(!g_NEXUS_smartcardModule) {
264    return NULL;
265    }
266
267    if (pSettings)
268    {
269        g_NEXUS_smartcard.settings = *pSettings;
270    }
271    else
272    {
273        NEXUS_SmartcardModule_GetDefaultSettings(&g_NEXUS_smartcard.settings);
274    }
275
276    BSCD_GetDefaultSettings(&scdSettings, g_pCoreHandles->chp);
277    scdSettings.moduleClkFreq.FreqSrc = (BSCD_ClockFreqSrc) g_NEXUS_smartcard.settings.clockSource;
278    scdSettings.moduleClkFreq.ulClkFreq = g_NEXUS_smartcard.settings.clockFrequency;
279    scdSettings.moduleClkFreq.bIsUsingOsc = g_NEXUS_smartcard.settings.externalOscillatior;
280    scdSettings.moduleClkFreq.bIsRoutedInternal = g_NEXUS_smartcard.settings.routedInternal;
281    errCode = BSCD_Open(&g_NEXUS_smartcard.scd, g_pCoreHandles->reg, g_pCoreHandles->chp, g_pCoreHandles->bint, &scdSettings);
282    if (errCode)
283    {
284        NEXUS_Module_Destroy(g_NEXUS_smartcardModule);
285        g_NEXUS_smartcardModule = NULL;
286
287        BERR_TRACE(NEXUS_UNKNOWN);
288        return NULL;
289    }
290
291    return g_NEXUS_smartcardModule;
292}
293
294void NEXUS_SmartcardModule_Uninit()
295{
296    BSCD_Close(g_NEXUS_smartcard.scd);
297    NEXUS_Module_Destroy(g_NEXUS_smartcardModule);
298    g_NEXUS_smartcardModule = NULL;
299}
300
301/****************************************
302* API functions
303***************/
304
305BDBG_OBJECT_ID(NEXUS_Smartcard);
306
307typedef struct NEXUS_Smartcard {
308    BDBG_OBJECT(NEXUS_Smartcard)
309    bool opened;
310    BSCD_ChannelHandle channelHandle; /* scd channel */
311    BSCD_ChannelSettings channelSettings;
312    NEXUS_SmartcardSettings settings;
313    NEXUS_SmartcardState state;
314    NEXUS_IsrCallbackHandle insertCardCallback, removeCardCallback;
315} NEXUS_Smartcard;
316
317static NEXUS_Smartcard g_NEXUS_smartcards[BSCD_MAX_SUPPOTED_CHANNELS];
318
319void NEXUS_Smartcard_GetDefaultSettings(NEXUS_SmartcardSettings *pSettings)
320{
321    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
322
323    pSettings->standard = NEXUS_SmartcardStandard_eNds;
324    pSettings->protocol = NEXUS_SmartcardProtocol_eT0;
325    pSettings->fFactor = 1;
326    pSettings->dFactor = 1;
327    pSettings->extClockDivisor = 1;
328    pSettings->txRetries = 4;
329    pSettings->rxRetries = 4;
330    pSettings->workWaitTime.value = 9600;
331    pSettings->blockWaitTime.value = 971;
332    pSettings->extraGuardTime.value= 2;
333    pSettings->blockGuardTime.value = 22;
334    pSettings->timeOut.value= 5000;
335    pSettings->timeOut.unit= NEXUS_TimerUnit_eMilliSec;
336    pSettings->scPresDbInfo.dbWidth = 7;
337    pSettings->scPresDbInfo.scPresMode = NEXUS_ScPresMode_eMask;
338    pSettings->isPresHigh = true;
339    pSettings->setPinmux = true;
340    pSettings->setVcc = true;
341    pSettings->vcc = NEXUS_SmartcardVcc_e5V;
342    pSettings->sourceClockFreq = 27000000;
343    pSettings->atrReceiveTime.value = 40000;
344    pSettings->atrReceiveTime.unit = NEXUS_TimerUnit_eClk;
345    pSettings->resetCycles = 42000;
346}
347
348void NEXUS_Smartcard_GetSettings(NEXUS_SmartcardHandle smartcard, NEXUS_SmartcardSettings *pSettings)
349{
350    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
351    *pSettings = smartcard->settings;
352}
353
354NEXUS_Error NEXUS_Smartcard_SetSettings(NEXUS_SmartcardHandle smartcard, const NEXUS_SmartcardSettings *pSettings)
355{
356    NEXUS_Error errCode;
357    BSCD_ChannelSettings *pChSettings;
358
359    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
360
361    if ( pSettings == NULL )
362    {
363        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
364    }
365    pChSettings = &smartcard->channelSettings;
366
367    errCode = BSCD_Channel_GetParameters(smartcard->channelHandle, pChSettings);
368    if ( errCode ) {
369        return BERR_TRACE(NEXUS_UNKNOWN);
370    }
371
372    if (pSettings->standard == NEXUS_SmartcardStandard_eNds || pSettings->standard == NEXUS_SmartcardStandard_eIso || pSettings->standard == NEXUS_SmartcardStandard_eIrdeto) {
373        BDBG_CASSERT(NEXUS_SmartcardStandard_eNdsNoFlowControl == (NEXUS_SmartcardStandard)BSCD_Standard_eNDS_NO_FLOWCRTL);
374        pChSettings->scStandard = pSettings->standard;
375    } else {
376        BDBG_ERR(("The requested standard is not supported at this time"));
377        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
378    }
379
380    /* This is hard-coding due to PI requirements.
381            This way the PI picks up the right values based on the F and D factors. */
382
383    pChSettings->ucEtuClkDiv = 0;
384    pChSettings->ucScClkDiv = 0;
385    pChSettings->unPrescale = 0;
386    pChSettings->ucBaudDiv = 0;
387
388
389    BDBG_CASSERT(NEXUS_SmartcardProtocol_eT14 == (NEXUS_SmartcardProtocol)BSCD_AsyncProtocolType_e14_IRDETO);
390    pChSettings->eProtocolType = pSettings->protocol;
391
392    pChSettings->ucFFactor = pSettings->fFactor;
393    pChSettings->ucDFactor = pSettings->dFactor;
394    pChSettings->ucExternalClockDivisor = pSettings->extClockDivisor;
395    pChSettings->ucTxRetries = pSettings->txRetries;
396    pChSettings->ucRxRetries = pSettings->rxRetries;
397    pChSettings->ucBaudDiv = pSettings->baudDiv;
398    pChSettings->unCurrentIFSD = pSettings->currentIFSD;
399
400    BDBG_CASSERT(NEXUS_TimerUnit_eMilliSec == (NEXUS_TimerUnit)BSCD_TimerUnit_eMilliSec);
401    pChSettings->workWaitTime.ulValue = pSettings->workWaitTime.value;
402    pChSettings->workWaitTime.unit = pSettings->workWaitTime.unit;
403    pChSettings->blockWaitTime.ulValue = pSettings->blockWaitTime.value;
404    pChSettings->blockWaitTime.unit = pSettings->blockWaitTime.unit;
405    pChSettings->extraGuardTime.ulValue = pSettings->extraGuardTime.value;
406    pChSettings->extraGuardTime.unit = pSettings->extraGuardTime.unit;
407    pChSettings->blockGuardTime.ulValue = pSettings->blockGuardTime.value;
408    pChSettings->blockGuardTime.unit = pSettings->blockGuardTime.unit;
409    pChSettings->ulCharacterWaitTimeInteger = pSettings->characterWaitTime;
410
411    BDBG_CASSERT(NEXUS_EdcEncode_eCrc == (NEXUS_EdcEncode)BSCD_EDCEncode_eCRC);
412    pChSettings->edcSetting.edcEncode = pSettings->edcSetting.edcEncode;
413    pChSettings->edcSetting.bIsEnabled = pSettings->edcSetting.isEnabled;
414    pChSettings->timeOut.ulValue = pSettings->timeOut.value;
415    pChSettings->timeOut.unit = pSettings->timeOut.unit;
416    pChSettings->bAutoDeactiveReq = pSettings->autoDeactiveReq;
417    pChSettings->bNullFilter = pSettings->nullFilter;
418
419    BDBG_CASSERT(NEXUS_ScPresMode_eMask == (NEXUS_ScPresMode)BSCD_ScPresMode_eMask);
420    pChSettings->scPresDbInfo.scPresMode = pSettings->scPresDbInfo.scPresMode;
421    pChSettings->scPresDbInfo.bIsEnabled = pSettings->scPresDbInfo.isEnabled;
422    pChSettings->scPresDbInfo.ucDbWidth = pSettings->scPresDbInfo.dbWidth;
423
424    BDBG_CASSERT(NEXUS_ResetCardAction_eReceiveAndDecode == (NEXUS_ResetCardAction)BSCD_ResetCardAction_eReceiveAndDecode);
425    pChSettings->resetCardAction = pSettings->resetCardAction;
426    pChSettings->blockWaitTimeExt.ulValue = pSettings->blockWaitTimeExt.value;
427    pChSettings->blockWaitTimeExt.unit = pSettings->blockWaitTimeExt.unit;
428    pChSettings->bIsPresHigh = pSettings->isPresHigh;
429    pChSettings->setPinmux = pSettings->setPinmux;
430    pChSettings->setVcc = pSettings->setVcc;
431    pChSettings->bConnectDirectly = pSettings->connectDirectly;
432    pChSettings->srcClkFreqInHz = pSettings->sourceClockFreq;
433    pChSettings->ATRRecvTimeInteger.ulValue = pSettings->atrReceiveTime.value;
434    pChSettings->ATRRecvTimeInteger.unit = pSettings->atrReceiveTime.unit;
435    switch (pSettings->resetCycles)
436    {
437        case 42000:
438            pChSettings->eResetCycles = BSCD_MAX_RESET_IN_CLK_CYCLES;
439            break;
440        case 60000:
441            pChSettings->eResetCycles = BSCD_TDA803X_MAX_RESET_IN_CLK_CYCLES;
442            break;
443        default:
444            pChSettings->eResetCycles = BSCD_MAX_RESET_IN_CLK_CYCLES;
445    }
446
447    NEXUS_IsrCallback_Set(smartcard->insertCardCallback, &pSettings->insertCard);
448    NEXUS_IsrCallback_Set(smartcard->removeCardCallback, &pSettings->removeCard);
449
450    errCode = BSCD_Channel_SetParameters(smartcard->channelHandle, pChSettings);
451    if ( errCode ) {
452        return BERR_TRACE(NEXUS_UNKNOWN);
453    }
454
455    BSCD_Channel_EnableInterrupts(smartcard->channelHandle);
456
457    smartcard->settings = *pSettings;
458
459    return NEXUS_SUCCESS;
460}
461
462static void NEXUS_Smartcard_P_CardInserted_isr(BSCD_ChannelHandle channelHandle, void * pData )
463{
464    int index;
465
466    /* There is no way of setting pData to the smartcard handle, so we must look it up. */
467    BSTD_UNUSED(pData);
468    BDBG_MSG(("Card insertion detected."));
469    for (index=0; index < BSCD_MAX_SUPPOTED_CHANNELS; index++) {
470        if (g_NEXUS_smartcards[index].channelHandle == channelHandle) {
471            if ( g_NEXUS_smartcards[index].settings.insertCard.callback) {
472                NEXUS_Module_IsrCallback_Fire_isr(g_NEXUS_smartcardModule, g_NEXUS_smartcards[index].insertCardCallback);
473            }
474        }
475    }
476}
477
478static void NEXUS_Smartcard_P_CardRemoved_isr(BSCD_ChannelHandle channelHandle, void * pData )
479{
480    int index;
481
482    /* There is no way of setting pData to the smartcard handle, so we must look it up. */
483    BSTD_UNUSED(pData);
484    BDBG_MSG(("Card removal detected"));
485    for (index=0; index < BSCD_MAX_SUPPOTED_CHANNELS; index++) {
486        if (g_NEXUS_smartcards[index].channelHandle == channelHandle) {
487            if ( g_NEXUS_smartcards[index].settings.removeCard.callback) {
488                NEXUS_Module_IsrCallback_Fire_isr(g_NEXUS_smartcardModule, g_NEXUS_smartcards[index].removeCardCallback);
489            }
490        }
491    }
492}
493
494NEXUS_Error NEXUS_Smartcard_P_Open(NEXUS_SmartcardHandle smartcard, unsigned index, const NEXUS_SmartcardSettings *pSettings)
495{
496    NEXUS_Error errCode;
497
498    errCode = BSCD_GetChannelDefaultSettings(g_NEXUS_smartcard.scd, index, &smartcard->channelSettings);
499    if ( errCode )
500    {
501    errCode = BERR_TRACE(errCode);
502    goto error;
503    }
504
505    smartcard->channelSettings.ucEtuClkDiv = 0;
506    smartcard->channelSettings.ucScClkDiv = 0;
507    smartcard->channelSettings.unPrescale = 0;
508    smartcard->channelSettings.ucBaudDiv = 0;
509    smartcard->channelSettings.setVcc = pSettings->setVcc;
510    smartcard->channelSettings.vcc = pSettings->vcc;
511    smartcard->channelSettings.setPinmux = pSettings->setPinmux;
512    smartcard->channelSettings.eProtocolType = pSettings->protocol;
513    smartcard->channelSettings.scStandard = pSettings->standard;
514    smartcard->channelSettings.ucFFactor = pSettings->fFactor;
515    smartcard->channelSettings.ucDFactor = pSettings->dFactor;
516    smartcard->channelSettings.ucExternalClockDivisor = pSettings->extClockDivisor;
517    smartcard->channelSettings.ucTxRetries = pSettings->txRetries;
518    smartcard->channelSettings.ucRxRetries = pSettings->rxRetries;
519    smartcard->channelSettings.ucBaudDiv = pSettings->baudDiv;
520    smartcard->channelSettings.resetCardAction = pSettings->resetCardAction;
521    smartcard->channelSettings.unCurrentIFSD = pSettings->currentIFSD;
522
523    smartcard->channelSettings.ulCharacterWaitTimeInteger = pSettings->characterWaitTime;
524    smartcard->channelSettings.bAutoDeactiveReq = pSettings->autoDeactiveReq;
525    smartcard->channelSettings.bNullFilter = pSettings->nullFilter;
526    smartcard->channelSettings.bIsPresHigh = pSettings->isPresHigh;
527    smartcard->channelSettings.bConnectDirectly = pSettings->connectDirectly;
528
529    NEXUS_IsrCallback_Set(smartcard->insertCardCallback, &pSettings->insertCard);
530    NEXUS_IsrCallback_Set(smartcard->removeCardCallback, &pSettings->removeCard);
531
532    smartcard->channelSettings.workWaitTime.ulValue = pSettings->workWaitTime.value;
533    smartcard->channelSettings.workWaitTime.unit = pSettings->workWaitTime.unit;
534    smartcard->channelSettings.blockWaitTime.ulValue = pSettings->blockWaitTime.value;
535    smartcard->channelSettings.blockWaitTime.unit = pSettings->blockWaitTime.unit;
536    smartcard->channelSettings.extraGuardTime.ulValue = pSettings->extraGuardTime.value;
537    smartcard->channelSettings.extraGuardTime.unit = pSettings->extraGuardTime.unit;
538    smartcard->channelSettings.blockGuardTime.ulValue = pSettings->blockGuardTime.value;
539    smartcard->channelSettings.blockGuardTime.unit = pSettings->blockGuardTime.unit;
540    smartcard->channelSettings.edcSetting.edcEncode = pSettings->edcSetting.edcEncode;
541    smartcard->channelSettings.edcSetting.bIsEnabled = pSettings->edcSetting.isEnabled;
542    smartcard->channelSettings.timeOut.ulValue = pSettings->timeOut.value;
543    smartcard->channelSettings.timeOut.unit = pSettings->timeOut.unit;
544    smartcard->channelSettings.scPresDbInfo.scPresMode = pSettings->scPresDbInfo.scPresMode;
545    smartcard->channelSettings.scPresDbInfo.bIsEnabled = pSettings->scPresDbInfo.isEnabled;
546    smartcard->channelSettings.scPresDbInfo.ucDbWidth = pSettings->scPresDbInfo.dbWidth;
547    smartcard->channelSettings.blockWaitTimeExt.ulValue = pSettings->blockWaitTimeExt.value;
548    smartcard->channelSettings.blockWaitTimeExt.unit = pSettings->blockWaitTimeExt.unit;
549    smartcard->channelSettings.srcClkFreqInHz = pSettings->sourceClockFreq;
550    smartcard->channelSettings.ATRRecvTimeInteger.ulValue = pSettings->atrReceiveTime.value;
551    smartcard->channelSettings.ATRRecvTimeInteger.unit = pSettings->atrReceiveTime.unit;
552    switch (pSettings->resetCycles)
553    {
554        case 42000:
555            smartcard->channelSettings.eResetCycles = BSCD_MAX_RESET_IN_CLK_CYCLES;
556            break;
557        case 60000:
558            smartcard->channelSettings.eResetCycles = BSCD_TDA803X_MAX_RESET_IN_CLK_CYCLES;
559            break;
560        default:
561            smartcard->channelSettings.eResetCycles = BSCD_MAX_RESET_IN_CLK_CYCLES;
562    }
563       
564
565    smartcard->settings = *pSettings;
566
567    errCode = BSCD_Channel_Open(g_NEXUS_smartcard.scd, &smartcard->channelHandle, index, &smartcard->channelSettings);
568    if ( errCode ) {
569    BERR_TRACE(NEXUS_UNKNOWN);
570    goto error;
571    }
572
573    BKNI_EnterCriticalSection();
574    errCode = BSCD_Channel_EnableIntrCallback_isr(smartcard->channelHandle,BSCD_IntType_eCardInsertInt,NEXUS_Smartcard_P_CardInserted_isr);
575    BKNI_LeaveCriticalSection();
576    if ( errCode ) {
577    BERR_TRACE(NEXUS_UNKNOWN);
578    goto error;
579    }
580    BKNI_EnterCriticalSection();
581    errCode = BSCD_Channel_EnableIntrCallback_isr(smartcard->channelHandle,BSCD_IntType_eCardRemoveInt,NEXUS_Smartcard_P_CardRemoved_isr);
582    BKNI_LeaveCriticalSection();
583    if ( errCode ) {
584    BERR_TRACE(NEXUS_UNKNOWN);
585    goto error;
586    }
587
588error:
589    return errCode;
590
591}
592
593NEXUS_SmartcardHandle NEXUS_Smartcard_Open(unsigned index, const NEXUS_SmartcardSettings *pSettings)
594{
595    NEXUS_Error errCode;
596    unsigned char totalChannels;
597    NEXUS_SmartcardHandle smartcard;
598
599    if ( pSettings == NULL )
600    {
601        BERR_TRACE(NEXUS_INVALID_PARAMETER);
602        return NULL;
603    }
604    if (index >= BSCD_MAX_SUPPOTED_CHANNELS) {
605        BERR_TRACE(NEXUS_INVALID_PARAMETER);
606        return NULL;
607    }
608
609    smartcard = &g_NEXUS_smartcards[index];
610
611    if ( smartcard->opened == true )
612    {
613        BDBG_ERR(("Smartcard %d is already open", index));
614        errCode = BERR_TRACE(NEXUS_NOT_SUPPORTED);
615        return NULL;
616    }
617
618    BSCD_GetTotalChannels(g_NEXUS_smartcard.scd, &totalChannels);
619    if ( index >= totalChannels)
620    {
621        BDBG_ERR(("unable to open Smartcard[%d]", index));
622        errCode = BERR_TRACE(NEXUS_INVALID_PARAMETER);
623        return NULL;
624    }
625
626    if (pSettings->standard == NEXUS_SmartcardStandard_eNds || pSettings->standard == NEXUS_SmartcardStandard_eIso || pSettings->standard == NEXUS_SmartcardStandard_eIrdeto) {
627
628        BKNI_Memset(smartcard, 0, sizeof(*smartcard));
629        BDBG_OBJECT_SET(smartcard, NEXUS_Smartcard);
630        smartcard->opened = true;
631        smartcard->insertCardCallback = NEXUS_IsrCallback_Create(smartcard, NULL);
632        smartcard->removeCardCallback = NEXUS_IsrCallback_Create(smartcard, NULL);
633
634        smartcard->state = NEXUS_SmartcardState_eUnknown;
635
636    errCode = NEXUS_Smartcard_P_Open(smartcard, index, pSettings);
637    if ( errCode )
638        {
639            errCode = BERR_TRACE(errCode);
640            goto error;
641        }
642    } else {
643        BDBG_ERR(("The requested standard is not supported at this time"));
644        BERR_TRACE(NEXUS_INVALID_PARAMETER);
645    }
646
647    return smartcard;
648
649error:
650    NEXUS_Smartcard_Close(smartcard);
651    return NULL;
652}
653
654void NEXUS_Smartcard_P_Close(NEXUS_SmartcardHandle smartcard)
655{
656    if (smartcard->channelHandle)
657    {
658        BKNI_EnterCriticalSection();
659        BSCD_Channel_DisableIntrCallback_isr(smartcard->channelHandle,BSCD_IntType_eCardInsertInt);
660        BKNI_LeaveCriticalSection();
661
662        BKNI_EnterCriticalSection();
663        BSCD_Channel_DisableIntrCallback_isr(smartcard->channelHandle,BSCD_IntType_eCardRemoveInt);
664        BKNI_LeaveCriticalSection();
665        if(BSCD_Channel_Close(smartcard->channelHandle))
666        {
667            BERR_TRACE(NEXUS_UNKNOWN);
668        }
669    }
670}
671
672void NEXUS_Smartcard_Close(NEXUS_SmartcardHandle smartcard)
673{
674    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
675
676    NEXUS_Smartcard_P_Close(smartcard);
677
678    smartcard->state = NEXUS_SmartcardState_eUnknown;
679    NEXUS_IsrCallback_Destroy(smartcard->insertCardCallback);
680    NEXUS_IsrCallback_Destroy(smartcard->removeCardCallback);
681
682    BDBG_OBJECT_UNSET(smartcard, NEXUS_Smartcard);
683
684    BKNI_Memset(smartcard, 0, sizeof(*smartcard));
685}
686
687NEXUS_Error NEXUS_Smartcard_Reset(NEXUS_SmartcardHandle smartcard, bool warmReset)
688{
689    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
690
691    smartcard->state = warmReset ? NEXUS_SmartcardState_eWarmResetting : NEXUS_SmartcardState_eColdResetting;
692    if (BSCD_Channel_ResetIFD(smartcard->channelHandle, warmReset ? BSCD_ResetType_eWarm : BSCD_ResetType_eCold)) {
693        smartcard->state = NEXUS_SmartcardState_eResetDone;
694        return BERR_TRACE(NEXUS_UNKNOWN);
695    }
696    smartcard->state = NEXUS_SmartcardState_eResetDone;
697
698    return NEXUS_SUCCESS;
699}
700
701
702NEXUS_Error NEXUS_Smartcard_Read(NEXUS_SmartcardHandle smartcard, void *pData,  size_t numBytes, size_t *pBytesRead)
703{
704    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
705
706    smartcard->state = NEXUS_SmartcardState_eReceiving;
707    if (BSCD_Channel_Receive(smartcard->channelHandle, pData, (unsigned long *) pBytesRead, numBytes)) {
708        smartcard->state = NEXUS_SmartcardState_eReady;
709        return BERR_TRACE(NEXUS_UNKNOWN);
710    }
711
712    smartcard->state = NEXUS_SmartcardState_eReady;
713    if (*pBytesRead <= 0) {
714        return BERR_TRACE(NEXUS_UNKNOWN);
715    }
716
717    return NEXUS_SUCCESS;
718}
719
720NEXUS_Error NEXUS_Smartcard_Write(NEXUS_SmartcardHandle smartcard, const void *pData, size_t numBytes, size_t *pBytesWritten)
721{
722    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
723
724    smartcard->state = NEXUS_SmartcardState_eTransmitting;
725
726    if (BSCD_Channel_Transmit(smartcard->channelHandle, (uint8_t *) pData, numBytes)) {
727        *pBytesWritten = 0;
728        smartcard->state = NEXUS_SmartcardState_eTransmitted;
729        return BERR_TRACE(NEXUS_UNKNOWN);
730    }
731    else {
732        *pBytesWritten = numBytes;
733        smartcard->state = NEXUS_SmartcardState_eTransmitted;
734        return NEXUS_SUCCESS;
735    }
736}
737
738NEXUS_Error NEXUS_Smartcard_GetStatus(NEXUS_SmartcardHandle smartcard, NEXUS_SmartcardStatus *pStatus)
739{
740    BSCD_Status  internal_status;
741    BSCD_ChannelSettings internal_settings;
742    BERR_Code rc;
743
744    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
745    BDBG_ASSERT(NULL != pStatus);
746    BKNI_Memset(pStatus, 0, sizeof(*pStatus));
747
748    rc = BSCD_Channel_GetStatus(smartcard->channelHandle, &internal_status);
749    if (rc) return BERR_TRACE(rc);
750
751    pStatus->err = NEXUS_SmartcardError_eNoError;
752    pStatus->cardPresent = internal_status.bCardPresent;
753    pStatus->state = smartcard->state;
754
755    /* some SCD settings are actually read-only status */
756    rc = BSCD_Channel_GetParameters(smartcard->channelHandle, &internal_settings);
757    if (rc) return BERR_TRACE(rc);
758
759    pStatus->iccClockFrequency = internal_settings.currentICCClkFreq;
760
761    return NEXUS_SUCCESS;
762}
763
764NEXUS_Error NEXUS_Smartcard_DetectCard(NEXUS_SmartcardHandle smartcard)
765{
766    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
767
768    if (BSCD_Channel_DetectCard(smartcard->channelHandle, BSCD_CardPresent_eInserted)) {
769        return BERR_TRACE(NEXUS_UNKNOWN);
770    }
771    return NEXUS_SUCCESS;
772}
773
774NEXUS_Error NEXUS_Smartcard_ResetCard(NEXUS_SmartcardHandle smartcard, void *pData, size_t numBytes, size_t *pBytesRead)
775{
776    NEXUS_Error errCode;
777    bool inverseConvention;
778    bool tckPresesnt = false;
779    uint8_t size = 0, n=0;
780    unsigned char k=0;
781    char y=0;
782    char * pAtr;
783    char * pAtrTemp;
784    unsigned long readCount=0, errCount=0;
785
786    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
787    smartcard->state = NEXUS_SmartcardState_eUnknown;
788
789    if (BSCD_Channel_ResetCard(smartcard->channelHandle, BSCD_ResetCardAction_eNoAction)) {
790        return BERR_TRACE(NEXUS_UNKNOWN);
791    }
792
793    if(numBytes == 0){
794        return NEXUS_SUCCESS;
795    }
796
797     if (pData) {
798        BSCD_Channel_Receive(smartcard->channelHandle, pData, &readCount, numBytes);
799
800        *pBytesRead = readCount;
801        pAtr = (char *)pData;
802        pAtrTemp = (char *)pData;
803
804        if(readCount < 2){
805            BDBG_ERR(("Minimum ATR size is two bytes. Data read (%d bytes) is less than minimum ATR size of two bytes.", readCount));       
806            return BERR_TRACE(NEXUS_UNKNOWN);
807        }
808       
809        if(*pAtr == 0x3f) inverseConvention=true;
810        else inverseConvention=false;
811        size ++;
812        pAtr ++;
813
814        k = (*pAtr) & 0x0f;
815        size ++;
816
817        if(readCount == 2){
818            BDBG_WRN(("The requested ATR size = %d bytes, received ATR size = %d bytes and decoded ATR size = %d bytes.", numBytes, *pBytesRead, size));
819            return NEXUS_SUCCESS;
820        }
821
822
823        while ((y = ((*pAtr) & 0xf0))) {
824            if((*pAtr) & 0x10) n++;
825            if((*pAtr) & 0x20) n++;
826            if((*pAtr) & 0x40) n++;
827            if((*pAtr) & 0x80) n++;
828            if(((*pAtr) & 0x0f) && (size != 2)) tckPresesnt = true; /* TCK*/
829
830            size += n;
831
832            if((size > *pBytesRead) && (numBytes > *pBytesRead)) { /*because TS is also accounted for in pBytesRead*/
833                readCount = 0;
834                errCode = BSCD_Channel_Receive(smartcard->channelHandle, (void *)(pAtrTemp + *pBytesRead), &readCount, (numBytes - *pBytesRead));
835                if(errCode != BSCD_STATUS_READ_SUCCESS) break;
836                *pBytesRead += readCount;
837                if(!readCount) {
838                    errCount++;
839                    /* Trying forty times(Max ATR size is 32 bytes) to get the complete ATR. If not, error out. */
840                    if (errCount > 40){
841                        BDBG_WRN(("The requested ATR of size = %d bytes could not be received, received ATR size = %d bytes and decoded ATR size = %d bytes.", numBytes, *pBytesRead, size));
842                        return BERR_TRACE(NEXUS_UNKNOWN);
843                    }
844                    size -= n;                 
845                    continue;
846                }
847            }
848            else if(numBytes <= *pBytesRead){
849                pAtr += n;
850                break;
851            }
852            pAtr += n;
853            n=0;
854        }
855
856        if(((*pAtr) & 0x0f) || tckPresesnt) size++;
857
858        size += k;
859
860        if ((*pBytesRead == numBytes) && (*pBytesRead == size)) {
861            return NEXUS_SUCCESS;
862        }
863
864        if (*pBytesRead <= 0) {
865            return BERR_TRACE(NEXUS_UNKNOWN);
866        }
867        else {
868            BDBG_WRN(("The requested ATR size = %d bytes, received ATR size = %d bytes and decoded ATR size = %d bytes.", numBytes, *pBytesRead, size));
869            return NEXUS_SUCCESS;
870        }
871    } else {
872        BDBG_ERR(("Null Pointer passed for pData."));
873        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
874    }
875    return NEXUS_SUCCESS;
876}
877
878NEXUS_Error NEXUS_Smartcard_PowerIcc (NEXUS_SmartcardHandle smartcard, NEXUS_SmartcardPowerIcc iccAction)
879{
880    NEXUS_Error errCode = NEXUS_SUCCESS;
881    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
882
883    if (!smartcard->settings.connectDirectly) {
884        iccAction = (iccAction+1)%NEXUS_SmartcardPowerIcc_eMax; /*Toggle power up and down as the coupling chip TDA8024 is active LOW. */
885    }
886
887    if (iccAction) {
888        errCode = BSCD_Channel_PowerICC(smartcard->channelHandle, BSCD_PowerICC_ePowerUp);
889
890    }
891    else {
892        errCode = BSCD_Channel_PowerICC(smartcard->channelHandle, BSCD_PowerICC_ePowerDown);
893    }
894
895    smartcard->state = NEXUS_SmartcardState_eUnknown;
896    return errCode;
897}
898
899NEXUS_Error NEXUS_Smartcard_Deactivate (NEXUS_SmartcardHandle smartcard)
900{
901    BDBG_OBJECT_ASSERT(smartcard, NEXUS_Smartcard);
902
903    if (BSCD_Channel_Deactivate(smartcard->channelHandle)){
904        return BERR_TRACE(NEXUS_UNKNOWN);
905    }
906
907    return NEXUS_SUCCESS;
908}
909
910NEXUS_Error NEXUS_SmartcardModule_Standby_priv(bool enabled, const NEXUS_StandbySettings *pSettings)
911{
912#if NEXUS_POWER_MANAGEMENT
913    NEXUS_Error errCode = NEXUS_SUCCESS;
914    unsigned i;
915    BSTD_UNUSED(pSettings);
916
917    for (i=0; i<sizeof(g_NEXUS_smartcards)/sizeof(g_NEXUS_smartcards[0]); i++) {
918        NEXUS_SmartcardHandle smartcard = &g_NEXUS_smartcards[i];
919        if (!smartcard) { continue; }
920        if (!smartcard->opened) { continue; }
921
922        if (enabled) {
923            NEXUS_Smartcard_P_Close(smartcard);
924        } 
925        else {
926            errCode = NEXUS_Smartcard_P_Open(smartcard, i, &smartcard->settings);
927            if (errCode) { BERR_TRACE(NEXUS_UNKNOWN); return errCode; }
928            /* after resume, the app must call NEXUS_Smartcard_SetSettings(), just like
929               it must do after NEXUS_Smartcard_Open(). the smartcard API is weird like that */
930        }
931    }
932
933    return errCode;
934#else
935    BSTD_UNUSED(enabled);
936    BSTD_UNUSED(pSettings);
937    return NEXUS_SUCCESS;
938#endif
939}
Note: See TracBrowser for help on using the repository browser.