| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2009-2010, 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: $ |
|---|
| 11 | * $brcm_Revision: $ |
|---|
| 12 | * $brcm_Date: $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: $ |
|---|
| 19 | * |
|---|
| 20 | ***************************************************************************/ |
|---|
| 21 | #include "bsettop_smartcard.h" |
|---|
| 22 | #include "bstd.h" |
|---|
| 23 | #include "bscd.h" |
|---|
| 24 | #include "gist.h" |
|---|
| 25 | |
|---|
| 26 | BDBG_MODULE(smartcard); |
|---|
| 27 | |
|---|
| 28 | bresult bscd_settop_err(const char* func,int line,char *err_str,bresult err); |
|---|
| 29 | #define BSETTOP_ERROR(x) bscd_settop_err(__FUNCTION__,__LINE__,#x,x) |
|---|
| 30 | #define B_ID_IS_INDEX(x) (x == 0) |
|---|
| 31 | |
|---|
| 32 | /* |
|---|
| 33 | * error debugging function |
|---|
| 34 | */ |
|---|
| 35 | bresult bscd_settop_err(const char* func,int line,char *err_str,bresult err) |
|---|
| 36 | { |
|---|
| 37 | BDBG_ERR(("%s:%d - %s\n",func,line,err_str)); |
|---|
| 38 | return err; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | static b_task_t bsmartcard_task_h; |
|---|
| 42 | typedef struct bsmartcard_event_t |
|---|
| 43 | { |
|---|
| 44 | b_queue_t queue; |
|---|
| 45 | b_event_t events[4]; |
|---|
| 46 | }bsmartcard_event_t; |
|---|
| 47 | static bsmartcard_event_t s_bsmartcard_event; |
|---|
| 48 | |
|---|
| 49 | struct bsmartcard |
|---|
| 50 | { |
|---|
| 51 | BSCD_ChannelHandle channelHandle; /* scd channel */ |
|---|
| 52 | BSCD_ChannelSettings channelSettings; |
|---|
| 53 | bsmartcard_settings_t settings; |
|---|
| 54 | bsmartcard_state state; |
|---|
| 55 | unsigned int *p_stack; |
|---|
| 56 | } ; |
|---|
| 57 | |
|---|
| 58 | struct scd_module |
|---|
| 59 | { |
|---|
| 60 | BSCD_Handle moduleHandle; |
|---|
| 61 | BSCD_Settings moduleSettings; |
|---|
| 62 | struct bsmartcard cliChannel[BSCD_MAX_SUPPOTED_CHANNELS]; |
|---|
| 63 | bool card_inserted[BSCD_MAX_SUPPOTED_CHANNELS]; |
|---|
| 64 | bool card_removed[BSCD_MAX_SUPPOTED_CHANNELS]; |
|---|
| 65 | bool done; |
|---|
| 66 | } g_smartcard; |
|---|
| 67 | |
|---|
| 68 | |
|---|
| 69 | static bresult bsmartcard_p_set_settings( |
|---|
| 70 | BSCD_ChannelSettings *inoutp_sSettings, |
|---|
| 71 | bsmartcard_standard standard, |
|---|
| 72 | bsmartcard_protocol protocol |
|---|
| 73 | ); |
|---|
| 74 | |
|---|
| 75 | static void bsmartcard_p_card_inserted( BSCD_ChannelHandle in_channelHandle, void * inp_data ) { |
|---|
| 76 | int i; |
|---|
| 77 | |
|---|
| 78 | /* Sadly, there does not currently appear to be a means of setting inp_data to the specific bsmartcard. */ |
|---|
| 79 | BSTD_UNUSED(inp_data); |
|---|
| 80 | BDBG_MSG(("Card insertion detected.")); |
|---|
| 81 | for (i=0; i < BSCD_MAX_SUPPOTED_CHANNELS; i++) |
|---|
| 82 | { |
|---|
| 83 | if (g_smartcard.cliChannel[i].channelHandle == in_channelHandle) |
|---|
| 84 | { |
|---|
| 85 | g_smartcard.card_inserted[i] = 1; |
|---|
| 86 | } |
|---|
| 87 | } |
|---|
| 88 | bos_post_event(s_bsmartcard_event.queue,(b_event_t*)(s_bsmartcard_event.events)); |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | static void bsmartcard_p_card_removed( BSCD_ChannelHandle in_channelHandle, void * inp_data ) { |
|---|
| 92 | int i; |
|---|
| 93 | |
|---|
| 94 | /* Sadly, there does not currently appear to be a means of setting inp_data to the specific bsmartcard. */ |
|---|
| 95 | BSTD_UNUSED(inp_data); |
|---|
| 96 | BDBG_MSG(("Card removal detected")); |
|---|
| 97 | for (i=0; i < BSCD_MAX_SUPPOTED_CHANNELS; i++) |
|---|
| 98 | { |
|---|
| 99 | if (g_smartcard.cliChannel[i].channelHandle == in_channelHandle) |
|---|
| 100 | { |
|---|
| 101 | g_smartcard.card_removed[i] = 1; |
|---|
| 102 | } |
|---|
| 103 | } |
|---|
| 104 | bos_post_event(s_bsmartcard_event.queue,(b_event_t*)(s_bsmartcard_event.events)); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | bresult |
|---|
| 108 | bsmartcard_init(void) |
|---|
| 109 | { |
|---|
| 110 | BERR_Code rc; |
|---|
| 111 | |
|---|
| 112 | rc = BSCD_GetDefaultSettings(&g_smartcard.moduleSettings, GetCHP()); |
|---|
| 113 | if (rc!=BERR_SUCCESS) |
|---|
| 114 | { |
|---|
| 115 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | g_smartcard.done = false; |
|---|
| 119 | g_smartcard.moduleSettings.moduleClkFreq.FreqSrc = BSCD_ClockFreqSrc_eInternalClock; |
|---|
| 120 | g_smartcard.moduleSettings.moduleClkFreq.ulClkFreq = 27000000; |
|---|
| 121 | g_smartcard.moduleSettings.ucMaxChannels = BSCD_MAX_SUPPOTED_CHANNELS; |
|---|
| 122 | |
|---|
| 123 | g_smartcard.card_inserted[0] = 0; |
|---|
| 124 | g_smartcard.card_inserted[1] = 0; |
|---|
| 125 | g_smartcard.card_removed[0] = 0; |
|---|
| 126 | g_smartcard.card_removed[1] = 0; |
|---|
| 127 | |
|---|
| 128 | rc = BSCD_Open(&g_smartcard.moduleHandle, GetREG(), GetCHP(), |
|---|
| 129 | GetINT(), &g_smartcard.moduleSettings); |
|---|
| 130 | if (rc!=BERR_SUCCESS) |
|---|
| 131 | { |
|---|
| 132 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | bos_create_queue(&s_bsmartcard_event.queue, s_bsmartcard_event.events, 4); |
|---|
| 136 | |
|---|
| 137 | return b_ok; |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | |
|---|
| 141 | void |
|---|
| 142 | bsmartcard_shutdown(void) |
|---|
| 143 | { |
|---|
| 144 | BSCD_Close(g_smartcard.moduleHandle); |
|---|
| 145 | return; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | void bsmartcard_settings_init(bsmartcard_settings_t *settings) |
|---|
| 149 | { |
|---|
| 150 | BDBG_ASSERT(settings); |
|---|
| 151 | |
|---|
| 152 | BKNI_Memset(settings,0,sizeof(*settings)); |
|---|
| 153 | /* these match the old hard-coded values */ |
|---|
| 154 | settings->protocol = bsmartcard_protocol_t0; |
|---|
| 155 | settings->standard = bsmartcard_standard_nds; |
|---|
| 156 | settings->callback_context = NULL; |
|---|
| 157 | settings->card_insertion = NULL; |
|---|
| 158 | settings->card_removal = NULL; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | static void bsmardcard_task(void *data) |
|---|
| 162 | { |
|---|
| 163 | int i; |
|---|
| 164 | while (!g_smartcard.done) |
|---|
| 165 | { |
|---|
| 166 | bos_pend_event(s_bsmartcard_event.queue, 0xFF); |
|---|
| 167 | for (i=0; i < BSCD_MAX_SUPPOTED_CHANNELS; i++) |
|---|
| 168 | { |
|---|
| 169 | if (g_smartcard.card_inserted[i]) |
|---|
| 170 | { |
|---|
| 171 | if (g_smartcard.cliChannel[i].settings.card_insertion) |
|---|
| 172 | { |
|---|
| 173 | g_smartcard.cliChannel[i].settings.card_insertion(g_smartcard.cliChannel[i].settings.callback_context); |
|---|
| 174 | } |
|---|
| 175 | g_smartcard.card_inserted[i] = 0; |
|---|
| 176 | } |
|---|
| 177 | if (g_smartcard.card_removed[i]) |
|---|
| 178 | { |
|---|
| 179 | if (g_smartcard.cliChannel[i].settings.card_removal) |
|---|
| 180 | { |
|---|
| 181 | g_smartcard.cliChannel[i].settings.card_removal(g_smartcard.cliChannel[i].settings.callback_context); |
|---|
| 182 | } |
|---|
| 183 | g_smartcard.card_removed[i] = 0; |
|---|
| 184 | } |
|---|
| 185 | } |
|---|
| 186 | } |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | bsmartcard_t bsmartcard_open(bobject_t smartcard_id, bsmartcard_t * smartcard, const bsmartcard_settings_t *settings) |
|---|
| 190 | { |
|---|
| 191 | BERR_Code rc; |
|---|
| 192 | unsigned int index; |
|---|
| 193 | b_task_params params; |
|---|
| 194 | b_task_t task_h; |
|---|
| 195 | |
|---|
| 196 | BDBG_ASSERT(settings); |
|---|
| 197 | |
|---|
| 198 | if (B_ID_IS_INDEX(smartcard_id)) |
|---|
| 199 | { |
|---|
| 200 | index = B_ID_GET_INDEX(smartcard_id); |
|---|
| 201 | } |
|---|
| 202 | else |
|---|
| 203 | { |
|---|
| 204 | if (smartcard_id==0) |
|---|
| 205 | { |
|---|
| 206 | BSETTOP_ERROR(berr_invalid_parameter); |
|---|
| 207 | goto error; |
|---|
| 208 | } |
|---|
| 209 | BSETTOP_ERROR(berr_not_available); |
|---|
| 210 | goto error; |
|---|
| 211 | } |
|---|
| 212 | if (index >= BSCD_MAX_SUPPOTED_CHANNELS) |
|---|
| 213 | { |
|---|
| 214 | BSETTOP_ERROR(berr_invalid_parameter); |
|---|
| 215 | goto error; |
|---|
| 216 | } |
|---|
| 217 | g_smartcard.cliChannel[index].p_stack = BKNI_Malloc(256*4); |
|---|
| 218 | if (!(g_smartcard.cliChannel[index].p_stack)) |
|---|
| 219 | { |
|---|
| 220 | BSETTOP_ERROR(berr_out_of_memory); |
|---|
| 221 | goto error; |
|---|
| 222 | } |
|---|
| 223 | |
|---|
| 224 | g_smartcard.cliChannel[index].state = bsmartcard_state_unknown; |
|---|
| 225 | g_smartcard.cliChannel[index].settings = *settings; |
|---|
| 226 | |
|---|
| 227 | rc = BSCD_GetChannelDefaultSettings(g_smartcard.moduleHandle, index, |
|---|
| 228 | &g_smartcard.cliChannel[index].channelSettings); |
|---|
| 229 | if (rc!=BERR_SUCCESS) |
|---|
| 230 | { |
|---|
| 231 | BSETTOP_ERROR(berr_external_error); |
|---|
| 232 | goto error; |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | if (settings->standard == bsmartcard_standard_nds || settings->standard == bsmartcard_standard_iso) |
|---|
| 236 | { |
|---|
| 237 | if (bsmartcard_p_set_settings(&g_smartcard.cliChannel[index].channelSettings, settings->standard, settings->protocol) != b_ok) |
|---|
| 238 | { |
|---|
| 239 | BSETTOP_ERROR(berr_external_error); |
|---|
| 240 | goto error; |
|---|
| 241 | } |
|---|
| 242 | } |
|---|
| 243 | else |
|---|
| 244 | { |
|---|
| 245 | BDBG_ERR(("The requested standard is not supported at this time")); |
|---|
| 246 | BSETTOP_ERROR(berr_not_available); |
|---|
| 247 | } |
|---|
| 248 | |
|---|
| 249 | rc = BSCD_Channel_Open(g_smartcard.moduleHandle, &g_smartcard.cliChannel[index].channelHandle, |
|---|
| 250 | index, &g_smartcard.cliChannel[index].channelSettings); |
|---|
| 251 | if (rc!=BERR_SUCCESS) |
|---|
| 252 | { |
|---|
| 253 | BSETTOP_ERROR(berr_external_error); |
|---|
| 254 | goto error; |
|---|
| 255 | } |
|---|
| 256 | |
|---|
| 257 | BSCD_Channel_EnableIntrCallback_isr(g_smartcard.cliChannel[index].channelHandle,BSCD_IntType_eCardInsertInt,bsmartcard_p_card_inserted); |
|---|
| 258 | BSCD_Channel_EnableIntrCallback_isr(g_smartcard.cliChannel[index].channelHandle,BSCD_IntType_eCardRemoveInt,bsmartcard_p_card_removed); |
|---|
| 259 | |
|---|
| 260 | *smartcard = &g_smartcard.cliChannel[index]; |
|---|
| 261 | params.name="smartcard_task"; |
|---|
| 262 | params.priority = 8; |
|---|
| 263 | params.stack_size = 256; |
|---|
| 264 | params.stack = g_smartcard.cliChannel[index].p_stack; |
|---|
| 265 | bos_start_task(&task_h,¶ms, bsmardcard_task, &task_h); |
|---|
| 266 | if (!task_h) |
|---|
| 267 | { |
|---|
| 268 | BDBG_ERR(("task_h create failed\n")); |
|---|
| 269 | } |
|---|
| 270 | bsmartcard_task_h = task_h; |
|---|
| 271 | |
|---|
| 272 | return *smartcard; |
|---|
| 273 | |
|---|
| 274 | error: |
|---|
| 275 | *smartcard = NULL; |
|---|
| 276 | return *smartcard; |
|---|
| 277 | } |
|---|
| 278 | |
|---|
| 279 | void bsmartcard_close(bsmartcard_t smartcard) |
|---|
| 280 | { |
|---|
| 281 | BDBG_ASSERT(smartcard); |
|---|
| 282 | |
|---|
| 283 | smartcard->state = bsmartcard_state_unknown; |
|---|
| 284 | if (BSCD_Channel_Close(smartcard->channelHandle) != b_ok) |
|---|
| 285 | BSETTOP_ERROR(berr_external_error); |
|---|
| 286 | bos_stop_task(bsmartcard_task_h); |
|---|
| 287 | bos_delete_queue(&s_bsmartcard_event.queue); |
|---|
| 288 | if (smartcard->p_stack) |
|---|
| 289 | { |
|---|
| 290 | BKNI_Free(smartcard->p_stack); |
|---|
| 291 | smartcard->p_stack = NULL; |
|---|
| 292 | } |
|---|
| 293 | |
|---|
| 294 | } |
|---|
| 295 | |
|---|
| 296 | bresult bsmartcard_reset(bsmartcard_t smartcard, bool warm_reset) |
|---|
| 297 | { |
|---|
| 298 | BDBG_ASSERT(smartcard); |
|---|
| 299 | |
|---|
| 300 | smartcard->state = warm_reset ? bsmartcard_state_warm_resetting : bsmartcard_state_cold_resetting; |
|---|
| 301 | if (BSCD_Channel_ResetIFD(smartcard->channelHandle, warm_reset ? BSCD_ResetType_eWarm : BSCD_ResetType_eCold)) |
|---|
| 302 | { |
|---|
| 303 | smartcard->state = bsmartcard_state_reset_done; |
|---|
| 304 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 305 | } |
|---|
| 306 | smartcard->state = bsmartcard_state_reset_done; |
|---|
| 307 | return b_ok; |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | bresult bsmartcard_read(bsmartcard_t smartcard, void *data, |
|---|
| 312 | size_t length, size_t *length_read) |
|---|
| 313 | { |
|---|
| 314 | BDBG_ASSERT(smartcard); |
|---|
| 315 | |
|---|
| 316 | smartcard->state = bsmartcard_state_receiving; |
|---|
| 317 | if (BSCD_Channel_Receive(smartcard->channelHandle, |
|---|
| 318 | data, (unsigned long *) length_read, length) != b_ok) |
|---|
| 319 | { |
|---|
| 320 | smartcard->state = bsmartcard_state_ready; |
|---|
| 321 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 322 | } |
|---|
| 323 | |
|---|
| 324 | smartcard->state = bsmartcard_state_ready; |
|---|
| 325 | if (*length_read <= 0) |
|---|
| 326 | { |
|---|
| 327 | return BSETTOP_ERROR(berr_external_error);; |
|---|
| 328 | } |
|---|
| 329 | |
|---|
| 330 | return b_ok; |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | bresult bsmartcard_write(bsmartcard_t smartcard, const void *data, |
|---|
| 334 | size_t length, size_t *length_written) |
|---|
| 335 | { |
|---|
| 336 | BDBG_ASSERT(smartcard); |
|---|
| 337 | |
|---|
| 338 | smartcard->state = bsmartcard_state_transmitting; |
|---|
| 339 | |
|---|
| 340 | if (BSCD_Channel_Transmit( smartcard->channelHandle, (uint8_t *) data, length) != b_ok) |
|---|
| 341 | { |
|---|
| 342 | *length_written = 0; |
|---|
| 343 | smartcard->state = bsmartcard_state_transmitted; |
|---|
| 344 | return BSETTOP_ERROR(berr_external_error);; |
|---|
| 345 | } |
|---|
| 346 | else |
|---|
| 347 | { |
|---|
| 348 | *length_written = length; |
|---|
| 349 | smartcard->state = bsmartcard_state_transmitted; |
|---|
| 350 | return b_ok; |
|---|
| 351 | } |
|---|
| 352 | } |
|---|
| 353 | |
|---|
| 354 | bresult bsmartcard_get_status(bsmartcard_t smartcard, bsmartcard_status *status) |
|---|
| 355 | { |
|---|
| 356 | |
|---|
| 357 | BSCD_Status internal_status; |
|---|
| 358 | |
|---|
| 359 | BDBG_ASSERT(smartcard); |
|---|
| 360 | |
|---|
| 361 | if (BSCD_Channel_GetStatus(smartcard->channelHandle, &internal_status) != b_ok) |
|---|
| 362 | { |
|---|
| 363 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 364 | } |
|---|
| 365 | status->err = bsmartcard_no_error; |
|---|
| 366 | status->card_present = internal_status.bCardPresent; |
|---|
| 367 | status->state = smartcard->state; |
|---|
| 368 | return b_ok; |
|---|
| 369 | } |
|---|
| 370 | |
|---|
| 371 | bresult bsmartcard_detect_card(bsmartcard_t smartcard) |
|---|
| 372 | { |
|---|
| 373 | BDBG_ASSERT(smartcard); |
|---|
| 374 | |
|---|
| 375 | if (BSCD_Channel_DetectCard(smartcard->channelHandle, BSCD_CardPresent_eInserted) != b_ok) |
|---|
| 376 | { |
|---|
| 377 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 378 | } |
|---|
| 379 | return b_ok; |
|---|
| 380 | } |
|---|
| 381 | |
|---|
| 382 | bresult bsmartcard_reset_card(bsmartcard_t smartcard, |
|---|
| 383 | void *data, size_t length, size_t *length_read) |
|---|
| 384 | { |
|---|
| 385 | BDBG_ASSERT(smartcard); |
|---|
| 386 | |
|---|
| 387 | smartcard->state = bsmartcard_state_unknown; |
|---|
| 388 | |
|---|
| 389 | if (BSCD_Channel_ResetCard(smartcard->channelHandle, BSCD_ResetCardAction_eNoAction) != b_ok) |
|---|
| 390 | { |
|---|
| 391 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 392 | } |
|---|
| 393 | |
|---|
| 394 | if (data) |
|---|
| 395 | { |
|---|
| 396 | if (BSCD_Channel_Receive(smartcard->channelHandle, |
|---|
| 397 | data, (unsigned long *) length_read, length) != b_ok) |
|---|
| 398 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 399 | |
|---|
| 400 | if (*length_read > length) |
|---|
| 401 | { |
|---|
| 402 | return BSETTOP_ERROR(berr_invalid_parameter); |
|---|
| 403 | } |
|---|
| 404 | if (*length_read <= 0) |
|---|
| 405 | { |
|---|
| 406 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 407 | } |
|---|
| 408 | else |
|---|
| 409 | { |
|---|
| 410 | smartcard->state = bsmartcard_state_reset_done; |
|---|
| 411 | /* interpret ATR data and set the settings */ |
|---|
| 412 | smartcard->channelSettings.extraGuardTime.ulValue = ((unsigned long *) data )[4]; |
|---|
| 413 | return b_ok; |
|---|
| 414 | } |
|---|
| 415 | } |
|---|
| 416 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 417 | } |
|---|
| 418 | |
|---|
| 419 | bresult bsmartcard_set_params_from_atr ( |
|---|
| 420 | bsmartcard_t smartcard |
|---|
| 421 | ) |
|---|
| 422 | { |
|---|
| 423 | BDBG_ASSERT(smartcard); |
|---|
| 424 | |
|---|
| 425 | smartcard->state = bsmartcard_state_receive_decode_atr; |
|---|
| 426 | if (BSCD_Channel_SetParameters(smartcard->channelHandle, |
|---|
| 427 | &(smartcard->channelSettings)) != b_ok) |
|---|
| 428 | { |
|---|
| 429 | smartcard->state = bsmartcard_state_unknown; |
|---|
| 430 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 431 | } |
|---|
| 432 | |
|---|
| 433 | if (BSCD_Channel_EnableInterrupts(smartcard->channelHandle) != b_ok) |
|---|
| 434 | { |
|---|
| 435 | smartcard->state = bsmartcard_state_unknown; |
|---|
| 436 | return BSETTOP_ERROR(berr_external_error); |
|---|
| 437 | } |
|---|
| 438 | |
|---|
| 439 | smartcard->state = bsmartcard_state_ready; |
|---|
| 440 | return b_ok; |
|---|
| 441 | } |
|---|
| 442 | |
|---|
| 443 | static bresult bsmartcard_p_set_settings( |
|---|
| 444 | BSCD_ChannelSettings *inoutp_sSettings, |
|---|
| 445 | bsmartcard_standard standard, |
|---|
| 446 | bsmartcard_protocol protocol |
|---|
| 447 | ) |
|---|
| 448 | { |
|---|
| 449 | /* Smart Card Standard */ |
|---|
| 450 | switch (standard) |
|---|
| 451 | { |
|---|
| 452 | case bsmartcard_standard_nds: |
|---|
| 453 | inoutp_sSettings->scStandard = BSCD_Standard_eNDS; |
|---|
| 454 | break; |
|---|
| 455 | case bsmartcard_standard_iso: |
|---|
| 456 | inoutp_sSettings->scStandard = BSCD_Standard_eISO; |
|---|
| 457 | break; |
|---|
| 458 | default: |
|---|
| 459 | inoutp_sSettings->scStandard = BSCD_Standard_eUnknown; |
|---|
| 460 | break; |
|---|
| 461 | } |
|---|
| 462 | |
|---|
| 463 | /* Asynchronous Protocol Types. */ |
|---|
| 464 | switch (protocol) |
|---|
| 465 | { |
|---|
| 466 | case bsmartcard_protocol_t1: |
|---|
| 467 | inoutp_sSettings->eProtocolType = BSCD_AsyncProtocolType_e1; |
|---|
| 468 | break; |
|---|
| 469 | case bsmartcard_protocol_t14: |
|---|
| 470 | inoutp_sSettings->eProtocolType = BSCD_AsyncProtocolType_e14_IRDETO; |
|---|
| 471 | break; |
|---|
| 472 | case bsmartcard_protocol_t0: |
|---|
| 473 | default: |
|---|
| 474 | inoutp_sSettings->eProtocolType = BSCD_AsyncProtocolType_e0; |
|---|
| 475 | break; |
|---|
| 476 | } |
|---|
| 477 | |
|---|
| 478 | /* Set F, Clock Rate Conversion Factor */ |
|---|
| 479 | inoutp_sSettings->ucFFactor = 1; |
|---|
| 480 | |
|---|
| 481 | /* Set D, Baud Rate Adjustor */ |
|---|
| 482 | inoutp_sSettings->ucDFactor = 1; |
|---|
| 483 | |
|---|
| 484 | /* Set ETU Clock Divider */ |
|---|
| 485 | inoutp_sSettings->ucEtuClkDiv = 6; |
|---|
| 486 | |
|---|
| 487 | /* Set SC Clock Divider */ |
|---|
| 488 | inoutp_sSettings->ucScClkDiv = 1; |
|---|
| 489 | |
|---|
| 490 | /* Set external Clock Divisor. For TDA only 1, 2,4,8 are valid value. */ |
|---|
| 491 | inoutp_sSettings->ucExternalClockDivisor = 1; |
|---|
| 492 | |
|---|
| 493 | /* Set Prescale */ |
|---|
| 494 | inoutp_sSettings->unPrescale = 0x0B; |
|---|
| 495 | |
|---|
| 496 | /* Set baud divisor */ |
|---|
| 497 | inoutp_sSettings->ucBaudDiv = 0x1F; |
|---|
| 498 | |
|---|
| 499 | /* Set ICC CLK Freq */ |
|---|
| 500 | |
|---|
| 501 | |
|---|
| 502 | /* If the final ISO baudrate is not equal to the final BRCM baudrate, there is a potential mismatch */ |
|---|
| 503 | |
|---|
| 504 | |
|---|
| 505 | /* Set maximum IFSD */ |
|---|
| 506 | |
|---|
| 507 | /* Set current IFSD */ |
|---|
| 508 | inoutp_sSettings->unCurrentIFSD = BSCD_MAX_TX_SIZE; |
|---|
| 509 | |
|---|
| 510 | /* Set Number of transmit parity retries */ |
|---|
| 511 | inoutp_sSettings->ucTxRetries = 4; |
|---|
| 512 | |
|---|
| 513 | /* Set Number of receive parity retries */ |
|---|
| 514 | inoutp_sSettings->ucRxRetries = 4; |
|---|
| 515 | |
|---|
| 516 | /* Set work waiting time */ |
|---|
| 517 | inoutp_sSettings->workWaitTime.ulValue = BSCD_DEFAULT_WORK_WAITING_TIME ; |
|---|
| 518 | inoutp_sSettings->workWaitTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 519 | |
|---|
| 520 | /* Set block Wait time */ |
|---|
| 521 | inoutp_sSettings->blockWaitTime.ulValue = BSCD_DEFAULT_BLOCK_WAITING_TIME ; |
|---|
| 522 | inoutp_sSettings->blockWaitTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 523 | |
|---|
| 524 | /* Set Extra Guard Time */ |
|---|
| 525 | inoutp_sSettings->extraGuardTime.ulValue = BSCD_DEFAULT_EXTRA_GUARD_TIME ; |
|---|
| 526 | inoutp_sSettings->extraGuardTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 527 | |
|---|
| 528 | /* Set block Guard time */ |
|---|
| 529 | inoutp_sSettings->blockGuardTime.ulValue = BSCD_DEFAULT_BLOCK_GUARD_TIME ; |
|---|
| 530 | inoutp_sSettings->blockGuardTime.unit = BSCD_TimerUnit_eETU; |
|---|
| 531 | |
|---|
| 532 | /* Set character Wait time Integer */ |
|---|
| 533 | inoutp_sSettings->ulCharacterWaitTimeInteger = BSCD_DEFAULT_CHARACTER_WAIT_TIME_INTEGER ; |
|---|
| 534 | |
|---|
| 535 | /* Set EDC encoding */ |
|---|
| 536 | inoutp_sSettings->edcSetting.bIsEnabled = false; |
|---|
| 537 | |
|---|
| 538 | /* Set transaction time out */ |
|---|
| 539 | inoutp_sSettings->timeOut.ulValue = BSCD_DEFAULT_TIME_OUT ; |
|---|
| 540 | inoutp_sSettings->timeOut.unit = BSCD_TimerUnit_eMilliSec; |
|---|
| 541 | |
|---|
| 542 | /* auto deactivation sequence */ |
|---|
| 543 | inoutp_sSettings->bAutoDeactiveReq = false; |
|---|
| 544 | |
|---|
| 545 | /* nullFilter */ |
|---|
| 546 | inoutp_sSettings->bNullFilter = false; |
|---|
| 547 | |
|---|
| 548 | /* debounce info */ |
|---|
| 549 | inoutp_sSettings->scPresDbInfo.bIsEnabled = false; /* Use TDA chip */ |
|---|
| 550 | inoutp_sSettings->scPresDbInfo.ucDbWidth = BSCD_DEFAULT_DB_WIDTH; |
|---|
| 551 | inoutp_sSettings->scPresDbInfo.scPresMode = BSCD_ScPresMode_eMask; |
|---|
| 552 | |
|---|
| 553 | /* Specify if we want the driver to read, decode and program registers */ |
|---|
| 554 | inoutp_sSettings->resetCardAction = BSCD_ResetCardAction_eNoAction; |
|---|
| 555 | |
|---|
| 556 | return b_ok ; |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | #ifdef CONFIG_SMARTCARD_TEST |
|---|
| 560 | #include "ministd.h" |
|---|
| 561 | void bsettop_smartcard_test(void) |
|---|
| 562 | { |
|---|
| 563 | int cnt = 0; |
|---|
| 564 | bsmartcard_settings_t settings; |
|---|
| 565 | bsmartcard_t smartcard; |
|---|
| 566 | |
|---|
| 567 | bsmartcard_init(); |
|---|
| 568 | bsmartcard_settings_init(&settings); |
|---|
| 569 | smartcard = bsmartcard_open(0,&smartcard,&settings); |
|---|
| 570 | bsmartcard_reset(smartcard,false); |
|---|
| 571 | |
|---|
| 572 | while (cnt++ < 120) |
|---|
| 573 | { |
|---|
| 574 | printf("Check for smartcard...\n"); |
|---|
| 575 | if (bsmartcard_detect_card(smartcard) == b_ok) |
|---|
| 576 | { |
|---|
| 577 | #define MAX_ATR_LEN 256 |
|---|
| 578 | size_t atr_len = MAX_ATR_LEN; |
|---|
| 579 | static char *atr_buffer[MAX_ATR_LEN+1]; |
|---|
| 580 | printf("Smartcard detected\n"); |
|---|
| 581 | |
|---|
| 582 | /* Must reset interface again and detect card again */ |
|---|
| 583 | printf("Reset smartcard interface... \n"); |
|---|
| 584 | bsmartcard_reset(smartcard,false); |
|---|
| 585 | if (bsmartcard_detect_card(smartcard) != b_ok) |
|---|
| 586 | { |
|---|
| 587 | printf("Reset smartcard interface failed... \n"); |
|---|
| 588 | continue; |
|---|
| 589 | } |
|---|
| 590 | |
|---|
| 591 | printf("Smartcard reset card\n"); |
|---|
| 592 | if (bsmartcard_reset_card(smartcard,atr_buffer,atr_len,&atr_len) != b_ok) |
|---|
| 593 | { |
|---|
| 594 | printf("Smartcard reset card failed\n"); |
|---|
| 595 | continue; |
|---|
| 596 | } |
|---|
| 597 | |
|---|
| 598 | if (atr_len > 0) |
|---|
| 599 | { |
|---|
| 600 | atr_buffer[atr_len] = 0; |
|---|
| 601 | printf("Smartcard reset card ATR %d bytes = %s\n",atr_len,atr_buffer); |
|---|
| 602 | if (bsmartcard_set_params_from_atr(smartcard) != b_ok) |
|---|
| 603 | { |
|---|
| 604 | printf("Smartcard bsmartcard_set_params_from_atr failed\n"); |
|---|
| 605 | continue; |
|---|
| 606 | } |
|---|
| 607 | break; |
|---|
| 608 | } |
|---|
| 609 | else |
|---|
| 610 | { |
|---|
| 611 | printf("Smartcard reset card failed. ATR length = 0\n"); |
|---|
| 612 | } |
|---|
| 613 | } |
|---|
| 614 | else |
|---|
| 615 | printf("No smartcard detected\n"); |
|---|
| 616 | |
|---|
| 617 | bos_sleep(1000); |
|---|
| 618 | } |
|---|
| 619 | bsmartcard_close(smartcard); |
|---|
| 620 | bsmartcard_shutdown(); |
|---|
| 621 | } |
|---|
| 622 | |
|---|
| 623 | #endif /* CONFIG_SMARTCARD_TEST */ |
|---|