1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <errno.h> 18 #include <pthread.h> 19 #include <semaphore.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <math.h> 23 #include <sys/queue.h> 24 #include <hardware/hardware.h> 25 #include <hardware/nfc.h> 26 #include <cutils/properties.h> 27 28 #include "com_android_nfc.h" 29 30 #define ERROR_BUFFER_TOO_SMALL -12 31 #define ERROR_INSUFFICIENT_RESOURCES -9 32 33 extern uint32_t libnfc_llc_error_count; 34 35 static phLibNfc_sConfig_t gDrvCfg; 36 void *gHWRef; 37 static phNfc_sData_t gInputParam; 38 static phNfc_sData_t gOutputParam; 39 40 uint8_t device_connected_flag; 41 static bool driverConfigured = FALSE; 42 43 static phLibNfc_Handle hLlcpHandle; 44 static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED; 45 static phLibNfc_Llcp_eLinkStatus_t g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault; 46 47 static jmethodID cached_NfcManager_notifyNdefMessageListeners; 48 static jmethodID cached_NfcManager_notifyTransactionListeners; 49 static jmethodID cached_NfcManager_notifyLlcpLinkActivation; 50 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated; 51 static jmethodID cached_NfcManager_notifyTargetDeselected; 52 53 static jmethodID cached_NfcManager_notifySeFieldActivated; 54 static jmethodID cached_NfcManager_notifySeFieldDeactivated; 55 56 static jmethodID cached_NfcManager_notifySeApduReceived; 57 static jmethodID cached_NfcManager_notifySeMifareAccess; 58 static jmethodID cached_NfcManager_notifySeEmvCardRemoval; 59 60 namespace android { 61 62 phLibNfc_Handle storedHandle = 0; 63 64 struct nfc_jni_native_data *exported_nat = NULL; 65 66 /* Internal functions declaration */ 67 static void *nfc_jni_client_thread(void *arg); 68 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status); 69 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status); 70 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status); 71 static void nfc_jni_se_set_mode_callback(void *context, 72 phLibNfc_Handle handle, NFCSTATUS status); 73 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status); 74 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume); 75 static void nfc_jni_Discovery_notification_callback(void *pContext, 76 phLibNfc_RemoteDevList_t *psRemoteDevList, 77 uint8_t uNofRemoteDev, NFCSTATUS status); 78 static void nfc_jni_transaction_callback(void *context, 79 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle, 80 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status); 81 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock); 82 83 /* 84 * Deferred callback called when client thread must be exited 85 */ 86 static void client_kill_deferred_call(void* arg) 87 { 88 struct nfc_jni_native_data *nat = (struct nfc_jni_native_data *)arg; 89 90 nat->running = FALSE; 91 } 92 93 static void kill_client(nfc_jni_native_data *nat) 94 { 95 phDal4Nfc_Message_Wrapper_t wrapper; 96 phLibNfc_DeferredCall_t *pMsg; 97 98 usleep(50000); 99 100 ALOGD("Terminating client thread..."); 101 102 pMsg = (phLibNfc_DeferredCall_t*)malloc(sizeof(phLibNfc_DeferredCall_t)); 103 pMsg->pCallback = client_kill_deferred_call; 104 pMsg->pParameter = (void*)nat; 105 106 wrapper.msg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; 107 wrapper.msg.pMsgData = pMsg; 108 wrapper.msg.Size = sizeof(phLibNfc_DeferredCall_t); 109 110 phDal4Nfc_msgsnd(gDrvCfg.nClientId, (struct msgbuf *)&wrapper, sizeof(phLibNfc_Message_t), 0); 111 } 112 113 static void nfc_jni_ioctl_callback(void *pContext, phNfc_sData_t *pOutput, NFCSTATUS status) { 114 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 115 LOG_CALLBACK("nfc_jni_ioctl_callback", status); 116 117 /* Report the callback status and wake up the caller */ 118 pCallbackData->status = status; 119 sem_post(&pCallbackData->sem); 120 } 121 122 static void nfc_jni_deinit_download_callback(void *pContext, NFCSTATUS status) 123 { 124 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 125 LOG_CALLBACK("nfc_jni_deinit_download_callback", status); 126 127 /* Report the callback status and wake up the caller */ 128 pCallbackData->status = status; 129 sem_post(&pCallbackData->sem); 130 } 131 132 static int nfc_jni_download_locked(struct nfc_jni_native_data *nat, uint8_t update) 133 { 134 uint8_t OutputBuffer[1]; 135 uint8_t InputBuffer[1]; 136 struct timespec ts; 137 NFCSTATUS status = NFCSTATUS_FAILED; 138 phLibNfc_StackCapabilities_t caps; 139 struct nfc_jni_callback_data cb_data; 140 bool result; 141 142 /* Create the local semaphore */ 143 if (!nfc_cb_data_init(&cb_data, NULL)) 144 { 145 goto clean_and_return; 146 } 147 148 if(update) 149 { 150 //deinit 151 TRACE("phLibNfc_Mgt_DeInitialize() (download)"); 152 REENTRANCE_LOCK(); 153 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_download_callback, (void *)&cb_data); 154 REENTRANCE_UNLOCK(); 155 if (status != NFCSTATUS_PENDING) 156 { 157 ALOGE("phLibNfc_Mgt_DeInitialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 158 } 159 160 clock_gettime(CLOCK_REALTIME, &ts); 161 ts.tv_sec += 5; 162 163 /* Wait for callback response */ 164 if(sem_timedwait(&cb_data.sem, &ts)) 165 { 166 ALOGW("Deinitialization timed out (download)"); 167 } 168 169 if(cb_data.status != NFCSTATUS_SUCCESS) 170 { 171 ALOGW("Deinitialization FAILED (download)"); 172 } 173 TRACE("Deinitialization SUCCESS (download)"); 174 } 175 176 result = performDownload(nat, false); 177 178 if (!result) { 179 status = NFCSTATUS_FAILED; 180 goto clean_and_return; 181 } 182 183 TRACE("phLibNfc_Mgt_Initialize()"); 184 REENTRANCE_LOCK(); 185 status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data); 186 REENTRANCE_UNLOCK(); 187 if(status != NFCSTATUS_PENDING) 188 { 189 ALOGE("phLibNfc_Mgt_Initialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 190 goto clean_and_return; 191 } 192 TRACE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 193 194 if(sem_wait(&cb_data.sem)) 195 { 196 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 197 status = NFCSTATUS_FAILED; 198 goto clean_and_return; 199 } 200 201 /* Initialization Status */ 202 if(cb_data.status != NFCSTATUS_SUCCESS) 203 { 204 status = cb_data.status; 205 goto clean_and_return; 206 } 207 208 /* ====== CAPABILITIES ======= */ 209 REENTRANCE_LOCK(); 210 status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat); 211 REENTRANCE_UNLOCK(); 212 if (status != NFCSTATUS_SUCCESS) 213 { 214 ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 215 } 216 else 217 { 218 ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d", 219 caps.psDevCapabilities.hal_version, 220 caps.psDevCapabilities.fw_version, 221 caps.psDevCapabilities.hw_version, 222 caps.psDevCapabilities.model_id, 223 caps.psDevCapabilities.hci_version, 224 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1], 225 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2], 226 caps.psDevCapabilities.firmware_update_info); 227 } 228 229 /*Download is successful*/ 230 status = NFCSTATUS_SUCCESS; 231 232 clean_and_return: 233 nfc_cb_data_deinit(&cb_data); 234 return status; 235 } 236 237 static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat) 238 { 239 char value[PROPERTY_VALUE_MAX]; 240 int result = FALSE; 241 NFCSTATUS status; 242 243 /* ====== CONFIGURE DRIVER ======= */ 244 /* Configure hardware link */ 245 gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600); 246 247 TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x)", gDrvCfg.nClientId); 248 REENTRANCE_LOCK(); 249 status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef); 250 REENTRANCE_UNLOCK(); 251 if(status == NFCSTATUS_ALREADY_INITIALISED) { 252 ALOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 253 } 254 else if(status != NFCSTATUS_SUCCESS) 255 { 256 ALOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 257 goto clean_and_return; 258 } 259 TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 260 261 if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0) 262 { 263 ALOGE("pthread_create failed"); 264 goto clean_and_return; 265 } 266 267 driverConfigured = TRUE; 268 269 clean_and_return: 270 return result; 271 } 272 273 static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat) 274 { 275 int result = FALSE; 276 NFCSTATUS status; 277 278 /* Unconfigure driver */ 279 TRACE("phLibNfc_Mgt_UnConfigureDriver()"); 280 REENTRANCE_LOCK(); 281 status = phLibNfc_Mgt_UnConfigureDriver(gHWRef); 282 REENTRANCE_UNLOCK(); 283 if(status != NFCSTATUS_SUCCESS) 284 { 285 ALOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status)); 286 } 287 else 288 { 289 ALOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 290 result = TRUE; 291 } 292 293 driverConfigured = FALSE; 294 295 return result; 296 } 297 298 /* Initialization function */ 299 static int nfc_jni_initialize(struct nfc_jni_native_data *nat) { 300 struct timespec ts; 301 uint8_t resp[16]; 302 NFCSTATUS status; 303 phLibNfc_StackCapabilities_t caps; 304 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; 305 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0; 306 phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo; 307 struct nfc_jni_callback_data cb_data; 308 uint8_t firmware_status; 309 uint8_t update = TRUE; 310 int result = JNI_FALSE; 311 const hw_module_t* hw_module; 312 nfc_pn544_device_t* pn544_dev = NULL; 313 int ret = 0; 314 ALOGD("Start Initialization\n"); 315 316 /* Create the local semaphore */ 317 if (!nfc_cb_data_init(&cb_data, NULL)) 318 { 319 goto clean_and_return; 320 } 321 /* Get EEPROM values and device port from product-specific settings */ 322 ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module); 323 if (ret) { 324 ALOGE("hw_get_module() failed."); 325 goto clean_and_return; 326 } 327 ret = nfc_pn544_open(hw_module, &pn544_dev); 328 if (ret) { 329 ALOGE("Could not open pn544 hw_module."); 330 goto clean_and_return; 331 } 332 if (pn544_dev->num_eeprom_settings == 0 || pn544_dev->eeprom_settings == NULL) { 333 ALOGE("Could not load EEPROM settings"); 334 goto clean_and_return; 335 } 336 337 /* Reset device connected handle */ 338 device_connected_flag = 0; 339 340 /* Reset stored handle */ 341 storedHandle = 0; 342 343 /* Initialize Driver */ 344 if(!driverConfigured) 345 { 346 nfc_jni_configure_driver(nat); 347 } 348 349 /* ====== INITIALIZE ======= */ 350 351 TRACE("phLibNfc_Mgt_Initialize()"); 352 REENTRANCE_LOCK(); 353 status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data); 354 REENTRANCE_UNLOCK(); 355 if(status != NFCSTATUS_PENDING) 356 { 357 ALOGE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 358 update = FALSE; 359 goto force_download; 360 } 361 TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 362 363 /* Wait for callback response */ 364 if(sem_wait(&cb_data.sem)) 365 { 366 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 367 goto clean_and_return; 368 } 369 370 /* Initialization Status */ 371 if(cb_data.status != NFCSTATUS_SUCCESS) 372 { 373 update = FALSE; 374 goto force_download; 375 } 376 377 /* ====== CAPABILITIES ======= */ 378 379 REENTRANCE_LOCK(); 380 status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat); 381 REENTRANCE_UNLOCK(); 382 if (status != NFCSTATUS_SUCCESS) 383 { 384 ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 385 } 386 else 387 { 388 ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d", 389 caps.psDevCapabilities.hal_version, 390 caps.psDevCapabilities.fw_version, 391 caps.psDevCapabilities.hw_version, 392 caps.psDevCapabilities.model_id, 393 caps.psDevCapabilities.hci_version, 394 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1], 395 caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2], 396 caps.psDevCapabilities.firmware_update_info); 397 } 398 399 /* ====== FIRMWARE VERSION ======= */ 400 if(caps.psDevCapabilities.firmware_update_info) 401 { 402 force_download: 403 for (i=0; i<3; i++) 404 { 405 TRACE("Firmware version not UpToDate"); 406 status = nfc_jni_download_locked(nat, update); 407 if(status == NFCSTATUS_SUCCESS) 408 { 409 ALOGI("Firmware update SUCCESS"); 410 break; 411 } 412 ALOGW("Firmware update FAILED"); 413 update = FALSE; 414 } 415 if(i>=3) 416 { 417 ALOGE("Unable to update firmware, giving up"); 418 goto clean_and_return; 419 } 420 } 421 else 422 { 423 TRACE("Firmware version UpToDate"); 424 } 425 /* ====== EEPROM SETTINGS ======= */ 426 427 // Update EEPROM settings 428 TRACE("****** START EEPROM SETTINGS UPDATE ******"); 429 for (i = 0; i < pn544_dev->num_eeprom_settings; i++) 430 { 431 char eeprom_property[PROPERTY_KEY_MAX]; 432 char eeprom_value[PROPERTY_VALUE_MAX]; 433 uint8_t* eeprom_base = &(pn544_dev->eeprom_settings[i*4]); 434 TRACE("> EEPROM SETTING: %d", i); 435 436 // Check for override of this EEPROM value in properties 437 snprintf(eeprom_property, sizeof(eeprom_property), "debug.nfc.eeprom.%02X%02X", 438 eeprom_base[1], eeprom_base[2]); 439 TRACE(">> Checking property: %s", eeprom_property); 440 if (property_get(eeprom_property, eeprom_value, "") == 2) { 441 int eeprom_value_num = (int)strtol(eeprom_value, (char**)NULL, 16); 442 ALOGD(">> Override EEPROM addr 0x%02X%02X with value %02X", 443 eeprom_base[1], eeprom_base[2], eeprom_value_num); 444 eeprom_base[3] = eeprom_value_num; 445 } 446 447 TRACE(">> Addr: 0x%02X%02X set to: 0x%02X", eeprom_base[1], eeprom_base[2], 448 eeprom_base[3]); 449 gInputParam.buffer = eeprom_base; 450 gInputParam.length = 0x04; 451 gOutputParam.buffer = resp; 452 453 REENTRANCE_LOCK(); 454 status = phLibNfc_Mgt_IoCtl(gHWRef, NFC_MEM_WRITE, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); 455 REENTRANCE_UNLOCK(); 456 if (status != NFCSTATUS_PENDING) { 457 ALOGE("phLibNfc_Mgt_IoCtl() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 458 goto clean_and_return; 459 } 460 /* Wait for callback response */ 461 if(sem_wait(&cb_data.sem)) 462 { 463 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 464 goto clean_and_return; 465 } 466 467 /* Initialization Status */ 468 if (cb_data.status != NFCSTATUS_SUCCESS) 469 { 470 goto clean_and_return; 471 } 472 } 473 TRACE("****** ALL EEPROM SETTINGS UPDATED ******"); 474 475 /* ====== SECURE ELEMENTS ======= */ 476 477 REENTRANCE_LOCK(); 478 ALOGD("phLibNfc_SE_GetSecureElementList()"); 479 status = phLibNfc_SE_GetSecureElementList(SE_List, &No_SE); 480 REENTRANCE_UNLOCK(); 481 if (status != NFCSTATUS_SUCCESS) 482 { 483 ALOGD("phLibNfc_SE_GetSecureElementList(): Error"); 484 goto clean_and_return; 485 } 486 487 ALOGD("\n> Number of Secure Element(s) : %d\n", No_SE); 488 /* Display Secure Element information */ 489 for (i = 0; i < No_SE; i++) 490 { 491 if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { 492 ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected, handle=%p", (void*)SE_List[i].hSecureElement); 493 } else if (SE_List[i].eSE_Type == phLibNfc_SE_Type_UICC) { 494 ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected, handle=%p", (void*)SE_List[i].hSecureElement); 495 } 496 497 /* Set SE mode - Off */ 498 REENTRANCE_LOCK(); 499 status = phLibNfc_SE_SetMode(SE_List[i].hSecureElement, 500 phLibNfc_SE_ActModeOff, nfc_jni_se_set_mode_callback, 501 (void *)&cb_data); 502 REENTRANCE_UNLOCK(); 503 if (status != NFCSTATUS_PENDING) 504 { 505 ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, 506 nfc_jni_get_status_name(status)); 507 goto clean_and_return; 508 } 509 ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, 510 nfc_jni_get_status_name(status)); 511 512 /* Wait for callback response */ 513 if(sem_wait(&cb_data.sem)) 514 { 515 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 516 goto clean_and_return; 517 } 518 } 519 520 /* ====== LLCP ======= */ 521 522 /* LLCP Params */ 523 TRACE("****** NFC Config Mode NFCIP1 - LLCP ******"); 524 LlcpConfigInfo.miu = nat->miu; 525 LlcpConfigInfo.lto = nat->lto; 526 LlcpConfigInfo.wks = nat->wks; 527 LlcpConfigInfo.option = nat->opt; 528 529 REENTRANCE_LOCK(); 530 status = phLibNfc_Mgt_SetLlcp_ConfigParams(&LlcpConfigInfo, 531 nfc_jni_llcpcfg_callback, 532 (void *)&cb_data); 533 REENTRANCE_UNLOCK(); 534 if(status != NFCSTATUS_PENDING) 535 { 536 ALOGE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status, 537 nfc_jni_get_status_name(status)); 538 goto clean_and_return; 539 } 540 TRACE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status, 541 nfc_jni_get_status_name(status)); 542 543 /* Wait for callback response */ 544 if(sem_wait(&cb_data.sem)) 545 { 546 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 547 goto clean_and_return; 548 } 549 550 /* ===== DISCOVERY ==== */ 551 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator 552 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target 553 nat->discovery_cfg.Duration = 300000; /* in ms */ 554 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; 555 556 /* Register for the card emulation mode */ 557 REENTRANCE_LOCK(); 558 ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); 559 REENTRANCE_UNLOCK(); 560 if(ret != NFCSTATUS_SUCCESS) 561 { 562 ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret); 563 goto clean_and_return; 564 } 565 TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret); 566 567 568 /* ====== END ======= */ 569 570 ALOGI("NFC Initialized"); 571 572 result = TRUE; 573 574 clean_and_return: 575 if (result != TRUE) 576 { 577 if(nat) 578 { 579 kill_client(nat); 580 } 581 } 582 if (pn544_dev != NULL) { 583 nfc_pn544_close(pn544_dev); 584 } 585 nfc_cb_data_deinit(&cb_data); 586 587 return result; 588 } 589 590 static int is_user_build() { 591 char value[PROPERTY_VALUE_MAX]; 592 property_get("ro.build.type", value, ""); 593 return !strncmp("user", value, PROPERTY_VALUE_MAX); 594 } 595 596 /* 597 * Last-chance fallback when there is no clean way to recover 598 * Performs a software reset 599 */ 600 void emergency_recovery(struct nfc_jni_native_data *nat) { 601 if (!is_user_build()) { 602 ALOGE("emergency_recovery: force restart of NFC service"); 603 } else { 604 // dont recover immediately, so we can debug 605 unsigned int t; 606 for (t=1; t < 1000000; t <<= 1) { 607 ALOGE("emergency_recovery: NFC stack dead-locked"); 608 sleep(t); 609 } 610 } 611 phLibNfc_Mgt_Recovery(); 612 abort(); // force a noisy crash 613 } 614 615 void nfc_jni_reset_timeout_values() 616 { 617 REENTRANCE_LOCK(); 618 phLibNfc_SetIsoXchgTimeout(NXP_ISO_XCHG_TIMEOUT); 619 phLibNfc_SetHciTimeout(NXP_NFC_HCI_TIMEOUT); 620 phLibNfc_SetFelicaTimeout(NXP_FELICA_XCHG_TIMEOUT); 621 phLibNfc_SetMifareRawTimeout(NXP_MIFARE_XCHG_TIMEOUT); 622 REENTRANCE_UNLOCK(); 623 } 624 625 /* 626 * Restart the polling loop when unable to perform disconnect 627 */ 628 void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat) 629 { 630 nfc_jni_start_discovery_locked(nat, true); 631 } 632 633 /* 634 * Utility to recover UID from target infos 635 */ 636 static phNfc_sData_t get_target_uid(phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) 637 { 638 phNfc_sData_t uid; 639 640 switch(psRemoteDevInfo->RemDevType) 641 { 642 case phNfc_eISO14443_A_PICC: 643 case phNfc_eISO14443_4A_PICC: 644 case phNfc_eISO14443_3A_PICC: 645 case phNfc_eMifare_PICC: 646 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid; 647 uid.length = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength; 648 break; 649 case phNfc_eISO14443_B_PICC: 650 case phNfc_eISO14443_4B_PICC: 651 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi; 652 uid.length = sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi); 653 break; 654 case phNfc_eFelica_PICC: 655 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm; 656 uid.length = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength; 657 break; 658 case phNfc_eJewel_PICC: 659 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid; 660 uid.length = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength; 661 break; 662 case phNfc_eISO15693_PICC: 663 uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid; 664 uid.length = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength; 665 break; 666 case phNfc_eNfcIP1_Target: 667 case phNfc_eNfcIP1_Initiator: 668 uid.buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID; 669 uid.length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID_Length; 670 break; 671 default: 672 uid.buffer = NULL; 673 uid.length = 0; 674 break; 675 } 676 677 return uid; 678 } 679 680 /* 681 * NFC stack message processing 682 */ 683 static void *nfc_jni_client_thread(void *arg) 684 { 685 struct nfc_jni_native_data *nat; 686 JNIEnv *e; 687 JavaVMAttachArgs thread_args; 688 phDal4Nfc_Message_Wrapper_t wrapper; 689 690 nat = (struct nfc_jni_native_data *)arg; 691 692 thread_args.name = "NFC Message Loop"; 693 thread_args.version = nat->env_version; 694 thread_args.group = NULL; 695 696 nat->vm->AttachCurrentThread(&e, &thread_args); 697 pthread_setname_np(pthread_self(), "message"); 698 699 TRACE("NFC client started"); 700 nat->running = TRUE; 701 while(nat->running == TRUE) 702 { 703 /* Fetch next message from the NFC stack message queue */ 704 if(phDal4Nfc_msgrcv(gDrvCfg.nClientId, (void *)&wrapper, 705 sizeof(phLibNfc_Message_t), 0, 0) == -1) 706 { 707 ALOGE("NFC client received bad message"); 708 continue; 709 } 710 711 switch(wrapper.msg.eMsgType) 712 { 713 case PH_LIBNFC_DEFERREDCALL_MSG: 714 { 715 phLibNfc_DeferredCall_t *msg = 716 (phLibNfc_DeferredCall_t *)(wrapper.msg.pMsgData); 717 718 REENTRANCE_LOCK(); 719 msg->pCallback(msg->pParameter); 720 REENTRANCE_UNLOCK(); 721 722 break; 723 } 724 } 725 } 726 TRACE("NFC client stopped"); 727 728 nat->vm->DetachCurrentThread(); 729 730 return NULL; 731 } 732 733 extern uint8_t nfc_jni_is_ndef; 734 extern uint8_t *nfc_jni_ndef_buf; 735 extern uint32_t nfc_jni_ndef_buf_len; 736 737 static phLibNfc_sNfcIPCfg_t nfc_jni_nfcip1_cfg = 738 { 739 3, 740 { 0x46, 0x66, 0x6D } 741 }; 742 743 /* 744 * Callbacks 745 */ 746 747 /* P2P - LLCP callbacks */ 748 static void nfc_jni_llcp_linkStatus_callback(void *pContext, 749 phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus) 750 { 751 phFriNfc_Llcp_sLinkParameters_t sLinkParams; 752 JNIEnv *e; 753 NFCSTATUS status; 754 755 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 756 757 struct nfc_jni_native_data *nat = (nfc_jni_native_data *)pContextData->pContext; 758 759 nfc_jni_listen_data_t * pListenData = NULL; 760 nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor(); 761 762 TRACE("Callback: nfc_jni_llcp_linkStatus_callback()"); 763 764 nat->vm->GetEnv( (void **)&e, nat->env_version); 765 766 /* Update link status */ 767 g_eLinkStatus = eLinkStatus; 768 769 if(eLinkStatus == phFriNfc_LlcpMac_eLinkActivated) 770 { 771 REENTRANCE_LOCK(); 772 status = phLibNfc_Llcp_GetRemoteInfo(hLlcpHandle, &sLinkParams); 773 REENTRANCE_UNLOCK(); 774 if(status != NFCSTATUS_SUCCESS) 775 { 776 ALOGW("GetRemote Info failded - Status = %02x",status); 777 } 778 else 779 { 780 ALOGI("LLCP Link activated (LTO=%d, MIU=%d, OPTION=0x%02x, WKS=0x%02x)",sLinkParams.lto, 781 sLinkParams.miu, 782 sLinkParams.option, 783 sLinkParams.wks); 784 device_connected_flag = 1; 785 } 786 } 787 else if(eLinkStatus == phFriNfc_LlcpMac_eLinkDeactivated) 788 { 789 ALOGI("LLCP Link deactivated"); 790 free(pContextData); 791 /* Reset device connected flag */ 792 device_connected_flag = 0; 793 794 /* Reset incoming socket list */ 795 while (!LIST_EMPTY(&pMonitor->incoming_socket_head)) 796 { 797 pListenData = LIST_FIRST(&pMonitor->incoming_socket_head); 798 LIST_REMOVE(pListenData, entries); 799 free(pListenData); 800 } 801 802 /* Notify manager that the LLCP is lost or deactivated */ 803 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkDeactivated, nat->tag); 804 if(e->ExceptionCheck()) 805 { 806 ALOGE("Exception occured"); 807 kill_client(nat); 808 } 809 } 810 } 811 812 static void nfc_jni_checkLlcp_callback(void *context, 813 NFCSTATUS status) 814 { 815 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)context; 816 817 LOG_CALLBACK("nfc_jni_checkLlcp_callback", status); 818 819 pContextData->status = status; 820 sem_post(&pContextData->sem); 821 } 822 823 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status) 824 { 825 struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; 826 LOG_CALLBACK("nfc_jni_llcpcfg_callback", status); 827 828 /* Report the callback status and wake up the caller */ 829 pCallbackData->status = status; 830 sem_post(&pCallbackData->sem); 831 } 832 833 static void nfc_jni_llcp_transport_listen_socket_callback(void *pContext, 834 phLibNfc_Handle hIncomingSocket) 835 { 836 phLibNfc_Handle hServiceSocket = (phLibNfc_Handle)pContext; 837 nfc_jni_listen_data_t * pListenData = NULL; 838 nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor(); 839 840 TRACE("nfc_jni_llcp_transport_listen_socket_callback socket handle = %p", (void*)hIncomingSocket); 841 842 pthread_mutex_lock(&pMonitor->incoming_socket_mutex); 843 844 /* Store the connection request */ 845 pListenData = (nfc_jni_listen_data_t*)malloc(sizeof(nfc_jni_listen_data_t)); 846 if (pListenData == NULL) 847 { 848 ALOGE("Failed to create structure to handle incoming LLCP connection request"); 849 goto clean_and_return; 850 } 851 pListenData->pServerSocket = hServiceSocket; 852 pListenData->pIncomingSocket = hIncomingSocket; 853 LIST_INSERT_HEAD(&pMonitor->incoming_socket_head, pListenData, entries); 854 855 /* Signal pending accept operations that the list is updated */ 856 pthread_cond_broadcast(&pMonitor->incoming_socket_cond); 857 858 clean_and_return: 859 pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); 860 } 861 862 void nfc_jni_llcp_transport_socket_err_callback(void* pContext, 863 uint8_t nErrCode) 864 { 865 PHNFC_UNUSED_VARIABLE(pContext); 866 867 TRACE("Callback: nfc_jni_llcp_transport_socket_err_callback()"); 868 869 if(nErrCode == PHFRINFC_LLCP_ERR_FRAME_REJECTED) 870 { 871 ALOGW("Frame Rejected - Disconnected"); 872 } 873 else if(nErrCode == PHFRINFC_LLCP_ERR_DISCONNECTED) 874 { 875 ALOGD("Socket Disconnected"); 876 } 877 } 878 879 880 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status) 881 { 882 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 883 884 LOG_CALLBACK("nfc_jni_discover_callback", status); 885 886 pContextData->status = status; 887 sem_post(&pContextData->sem); 888 } 889 890 static uint8_t find_preferred_target(phLibNfc_RemoteDevList_t *psRemoteDevList, 891 uint8_t uNoOfRemoteDev) 892 { 893 // Always prefer p2p targets over other targets. Otherwise, select the first target 894 // reported. 895 uint8_t preferred_index = 0; 896 for (uint8_t i = 0; i < uNoOfRemoteDev; i++) { 897 if((psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 898 || (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Target)) { 899 preferred_index = i; 900 } 901 } 902 return preferred_index; 903 } 904 905 static void nfc_jni_Discovery_notification_callback(void *pContext, 906 phLibNfc_RemoteDevList_t *psRemoteDevList, 907 uint8_t uNofRemoteDev, NFCSTATUS status) 908 { 909 JNIEnv *e; 910 NFCSTATUS ret; 911 jclass tag_cls = NULL; 912 jobject target_array; 913 jobject tag; 914 jmethodID ctor; 915 jfieldID f; 916 const char * typeName; 917 jbyteArray tagUid; 918 jbyteArray generalBytes = NULL; 919 struct nfc_jni_native_data *nat; 920 struct timespec ts; 921 phNfc_sData_t data; 922 int i; 923 int target_index = 0; // Target that will be reported (if multiple can be >0) 924 925 nat = (struct nfc_jni_native_data *)pContext; 926 927 nat->vm->GetEnv( (void **)&e, nat->env_version); 928 929 if(status == NFCSTATUS_DESELECTED) 930 { 931 LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status); 932 933 /* Notify manager that a target was deselected */ 934 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected); 935 if(e->ExceptionCheck()) 936 { 937 ALOGE("Exception occured"); 938 kill_client(nat); 939 } 940 } 941 else 942 { 943 LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status); 944 TRACE("Discovered %d tags", uNofRemoteDev); 945 946 target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev); 947 948 /* Reset device connected flag */ 949 device_connected_flag = 1; 950 phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo; 951 phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev; 952 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 953 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) 954 { 955 956 tag_cls = e->GetObjectClass(nat->cached_P2pDevice); 957 if(e->ExceptionCheck()) 958 { 959 ALOGE("Get Object Class Error"); 960 kill_client(nat); 961 return; 962 } 963 964 /* New target instance */ 965 ctor = e->GetMethodID(tag_cls, "<init>", "()V"); 966 tag = e->NewObject(tag_cls, ctor); 967 968 /* Set P2P Target mode */ 969 f = e->GetFieldID(tag_cls, "mMode", "I"); 970 971 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 972 { 973 ALOGD("Discovered P2P Initiator"); 974 e->SetIntField(tag, f, (jint)MODE_P2P_INITIATOR); 975 } 976 else 977 { 978 ALOGD("Discovered P2P Target"); 979 e->SetIntField(tag, f, (jint)MODE_P2P_TARGET); 980 } 981 982 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 983 { 984 /* Set General Bytes */ 985 f = e->GetFieldID(tag_cls, "mGeneralBytes", "[B"); 986 987 TRACE("General Bytes length ="); 988 for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++) 989 { 990 ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]); 991 } 992 993 generalBytes = e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length); 994 995 e->SetByteArrayRegion(generalBytes, 0, 996 remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length, 997 (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo); 998 999 e->SetObjectField(tag, f, generalBytes); 1000 } 1001 1002 /* Set tag handle */ 1003 f = e->GetFieldID(tag_cls, "mHandle", "I"); 1004 e->SetIntField(tag, f,(jint)remDevHandle); 1005 TRACE("Target handle = 0x%08x",remDevHandle); 1006 } 1007 else 1008 { 1009 tag_cls = e->GetObjectClass(nat->cached_NfcTag); 1010 if(e->ExceptionCheck()) 1011 { 1012 kill_client(nat); 1013 return; 1014 } 1015 1016 /* New tag instance */ 1017 ctor = e->GetMethodID(tag_cls, "<init>", "()V"); 1018 tag = e->NewObject(tag_cls, ctor); 1019 1020 bool multi_protocol = false; 1021 1022 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 1023 { 1024 TRACE("Multiple Protocol TAG detected\n"); 1025 multi_protocol = true; 1026 } 1027 1028 /* Set tag UID */ 1029 f = e->GetFieldID(tag_cls, "mUid", "[B"); 1030 data = get_target_uid(remDevInfo); 1031 tagUid = e->NewByteArray(data.length); 1032 if(data.length > 0) 1033 { 1034 e->SetByteArrayRegion(tagUid, 0, data.length, (jbyte *)data.buffer); 1035 } 1036 e->SetObjectField(tag, f, tagUid); 1037 1038 /* Generate technology list */ 1039 jintArray techList; 1040 jintArray handleList; 1041 jintArray typeList; 1042 nfc_jni_get_technology_tree(e, psRemoteDevList, 1043 multi_protocol ? uNofRemoteDev : 1, 1044 &techList, &handleList, &typeList); 1045 1046 /* Push the technology list into the java object */ 1047 f = e->GetFieldID(tag_cls, "mTechList", "[I"); 1048 e->SetObjectField(tag, f, techList); 1049 1050 f = e->GetFieldID(tag_cls, "mTechHandles", "[I"); 1051 e->SetObjectField(tag, f, handleList); 1052 1053 f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I"); 1054 e->SetObjectField(tag, f, typeList); 1055 1056 f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I"); 1057 e->SetIntField(tag, f,(jint)-1); 1058 1059 f = e->GetFieldID(tag_cls, "mConnectedHandle", "I"); 1060 e->SetIntField(tag, f,(jint)-1); 1061 } 1062 1063 storedHandle = remDevHandle; 1064 if (nat->tag != NULL) { 1065 e->DeleteGlobalRef(nat->tag); 1066 } 1067 nat->tag = e->NewGlobalRef(tag); 1068 1069 /* Notify the service */ 1070 TRACE("Notify Nfc Service"); 1071 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 1072 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) 1073 { 1074 /* Store the hanlde of the P2P device */ 1075 hLlcpHandle = remDevHandle; 1076 1077 /* Notify manager that new a P2P device was found */ 1078 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag); 1079 if(e->ExceptionCheck()) 1080 { 1081 ALOGE("Exception occured"); 1082 kill_client(nat); 1083 } 1084 } 1085 else 1086 { 1087 /* Notify manager that new a tag was found */ 1088 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag); 1089 if(e->ExceptionCheck()) 1090 { 1091 ALOGE("Exception occured"); 1092 kill_client(nat); 1093 } 1094 } 1095 e->DeleteLocalRef(tag); 1096 } 1097 } 1098 1099 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status) 1100 { 1101 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1102 1103 LOG_CALLBACK("nfc_jni_init_callback", status); 1104 1105 pContextData->status = status; 1106 sem_post(&pContextData->sem); 1107 } 1108 1109 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status) 1110 { 1111 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1112 1113 LOG_CALLBACK("nfc_jni_deinit_callback", status); 1114 1115 pContextData->status = status; 1116 sem_post(&pContextData->sem); 1117 } 1118 1119 /* Set Secure Element mode callback*/ 1120 static void nfc_jni_smartMX_setModeCb (void* pContext, 1121 phLibNfc_Handle hSecureElement, 1122 NFCSTATUS status) 1123 { 1124 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1125 1126 LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status); 1127 1128 pContextData->status = status; 1129 sem_post(&pContextData->sem); 1130 } 1131 1132 /* Card Emulation callback */ 1133 static void nfc_jni_transaction_callback(void *context, 1134 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle, 1135 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status) 1136 { 1137 JNIEnv *e; 1138 jobject tmp_array = NULL; 1139 jobject mifare_block = NULL; 1140 struct nfc_jni_native_data *nat; 1141 phNfc_sData_t *aid; 1142 phNfc_sData_t *mifare_command; 1143 struct nfc_jni_callback_data *pCallbackData; 1144 int i=0; 1145 1146 LOG_CALLBACK("nfc_jni_transaction_callback", status); 1147 1148 nat = (struct nfc_jni_native_data *)context; 1149 1150 nat->vm->GetEnv( (void **)&e, nat->env_version); 1151 1152 if(status == NFCSTATUS_SUCCESS) 1153 { 1154 switch(evt_type) 1155 { 1156 case phLibNfc_eSE_EvtStartTransaction: 1157 { 1158 TRACE("> SE EVT_START_TRANSACTION"); 1159 if(evt_info->UiccEvtInfo.aid.length <= AID_MAXLEN) 1160 { 1161 aid = &(evt_info->UiccEvtInfo.aid); 1162 1163 ALOGD("> AID DETECTED"); 1164 1165 if(aid != NULL) 1166 { 1167 if (TRACE_ENABLED == 1) { 1168 char aid_str[AID_MAXLEN * 2 + 1]; 1169 aid_str[0] = '\0'; 1170 for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) { 1171 snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]); 1172 } 1173 ALOGD("> AID: %s", aid_str); 1174 } 1175 tmp_array = e->NewByteArray(aid->length); 1176 if (tmp_array == NULL) 1177 { 1178 goto error; 1179 } 1180 1181 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer); 1182 if(e->ExceptionCheck()) 1183 { 1184 goto error; 1185 } 1186 } 1187 else 1188 { 1189 goto error; 1190 } 1191 1192 TRACE("Notify Nfc Service"); 1193 /* Notify manager that a new event occurred on a SE */ 1194 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array); 1195 if(e->ExceptionCheck()) 1196 { 1197 goto error; 1198 } 1199 } 1200 else 1201 { 1202 ALOGD("> NO AID DETECTED"); 1203 } 1204 }break; 1205 1206 case phLibNfc_eSE_EvtApduReceived: 1207 { 1208 phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid); 1209 TRACE("> SE EVT_APDU_RECEIVED"); 1210 1211 if (apdu != NULL) { 1212 TRACE(" APDU length=%d", apdu->length); 1213 tmp_array = e->NewByteArray(apdu->length); 1214 if (tmp_array == NULL) { 1215 goto error; 1216 } 1217 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer); 1218 if (e->ExceptionCheck()) { 1219 goto error; 1220 } 1221 } else { 1222 TRACE(" APDU EMPTY"); 1223 } 1224 1225 TRACE("Notify Nfc Service"); 1226 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array); 1227 }break; 1228 1229 case phLibNfc_eSE_EvtCardRemoval: 1230 { 1231 TRACE("> SE EVT_EMV_CARD_REMOVAL"); 1232 TRACE("Notify Nfc Service"); 1233 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval); 1234 }break; 1235 1236 case phLibNfc_eSE_EvtMifareAccess: 1237 { 1238 TRACE("> SE EVT_MIFARE_ACCESS"); 1239 mifare_command = &(evt_info->UiccEvtInfo.aid); 1240 TRACE("> MIFARE Block: %d",mifare_command->buffer[1]); 1241 tmp_array = e->NewByteArray(2); 1242 if (tmp_array == NULL) 1243 { 1244 goto error; 1245 } 1246 1247 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer); 1248 if(e->ExceptionCheck()) 1249 { 1250 goto error; 1251 } 1252 TRACE("Notify Nfc Service"); 1253 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block); 1254 }break; 1255 1256 case phLibNfc_eSE_EvtFieldOn: 1257 { 1258 TRACE("> SE EVT_FIELD_ON"); 1259 TRACE("Notify Nfc Service"); 1260 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated); 1261 }break; 1262 1263 case phLibNfc_eSE_EvtFieldOff: 1264 { 1265 TRACE("> SE EVT_FIELD_OFF"); 1266 TRACE("Notify Nfc Service"); 1267 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated); 1268 }break; 1269 1270 default: 1271 { 1272 TRACE("Unknown SE event"); 1273 }break; 1274 } 1275 } 1276 else 1277 { 1278 ALOGE("SE transaction notification error"); 1279 goto error; 1280 } 1281 1282 /* Function finished, now clean and return */ 1283 goto clean_and_return; 1284 1285 error: 1286 /* In case of error, just discard the notification */ 1287 ALOGE("Failed to send SE transaction notification"); 1288 e->ExceptionClear(); 1289 1290 clean_and_return: 1291 if(tmp_array != NULL) 1292 { 1293 e->DeleteLocalRef(tmp_array); 1294 } 1295 } 1296 1297 static void nfc_jni_se_set_mode_callback(void *pContext, 1298 phLibNfc_Handle handle, NFCSTATUS status) 1299 { 1300 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1301 1302 LOG_CALLBACK("nfc_jni_se_set_mode_callback", status); 1303 1304 pContextData->status = status; 1305 sem_post(&pContextData->sem); 1306 } 1307 1308 /* 1309 * NFCManager methods 1310 */ 1311 1312 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume) 1313 { 1314 NFCSTATUS ret; 1315 struct nfc_jni_callback_data cb_data; 1316 1317 /* Create the local semaphore */ 1318 if (!nfc_cb_data_init(&cb_data, NULL)) 1319 { 1320 goto clean_and_return; 1321 } 1322 /* Reset the PN544 ISO XCHG / sw watchdog timeouts */ 1323 nfc_jni_reset_timeout_values(); 1324 1325 /* Reload the p2p modes */ 1326 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator 1327 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target 1328 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; 1329 1330 /* Reset device connected flag */ 1331 device_connected_flag = 0; 1332 1333 /* Start Polling loop */ 1334 TRACE("****** Start NFC Discovery ******"); 1335 REENTRANCE_LOCK(); 1336 ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG, 1337 nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1338 REENTRANCE_UNLOCK(); 1339 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1340 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1341 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1342 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1343 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1344 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1345 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1346 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1347 nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret); 1348 1349 if(ret != NFCSTATUS_PENDING) 1350 { 1351 emergency_recovery(nat); 1352 goto clean_and_return; 1353 } 1354 1355 /* Wait for callback response */ 1356 if(sem_wait(&cb_data.sem)) 1357 { 1358 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1359 goto clean_and_return; 1360 } 1361 1362 clean_and_return: 1363 nfc_cb_data_deinit(&cb_data); 1364 } 1365 1366 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) 1367 { 1368 phLibNfc_sADD_Cfg_t discovery_cfg; 1369 NFCSTATUS ret; 1370 struct nfc_jni_callback_data cb_data; 1371 1372 /* Create the local semaphore */ 1373 if (!nfc_cb_data_init(&cb_data, NULL)) 1374 { 1375 goto clean_and_return; 1376 } 1377 1378 discovery_cfg.PollDevInfo.PollEnabled = 0; 1379 discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode; 1380 discovery_cfg.NfcIP_Target_Mode = 0; 1381 discovery_cfg.NfcIP_Tgt_Disable = TRUE; 1382 1383 /* Start Polling loop */ 1384 TRACE("****** Stop NFC Discovery ******"); 1385 REENTRANCE_LOCK(); 1386 ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1387 REENTRANCE_UNLOCK(); 1388 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1389 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1390 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1391 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1392 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1393 discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1394 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1395 discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1396 discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret); 1397 1398 if(ret != NFCSTATUS_PENDING) 1399 { 1400 emergency_recovery(nat); 1401 } 1402 1403 /* Wait for callback response */ 1404 if(sem_wait(&cb_data.sem)) 1405 { 1406 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1407 goto clean_and_return; 1408 } 1409 1410 clean_and_return: 1411 nfc_cb_data_deinit(&cb_data); 1412 } 1413 1414 1415 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) 1416 { 1417 struct nfc_jni_native_data *nat; 1418 1419 CONCURRENCY_LOCK(); 1420 1421 /* Retrieve native structure address */ 1422 nat = nfc_jni_get_nat(e, o); 1423 1424 nfc_jni_stop_discovery_locked(nat); 1425 1426 CONCURRENCY_UNLOCK(); 1427 1428 } 1429 1430 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) { 1431 NFCSTATUS ret; 1432 struct nfc_jni_native_data *nat; 1433 1434 CONCURRENCY_LOCK(); 1435 1436 nat = nfc_jni_get_nat(e, o); 1437 1438 /* Register callback for remote device notifications. 1439 * Must re-register every time we turn on discovery, since other operations 1440 * (such as opening the Secure Element) can change the remote device 1441 * notification callback*/ 1442 REENTRANCE_LOCK(); 1443 ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat); 1444 REENTRANCE_UNLOCK(); 1445 if(ret != NFCSTATUS_SUCCESS) 1446 { 1447 ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret); 1448 goto clean_and_return; 1449 } 1450 TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n", 1451 nat->registry_info.Jewel==TRUE?"J":"", 1452 nat->registry_info.MifareUL==TRUE?"UL":"", 1453 nat->registry_info.MifareStd==TRUE?"Mi":"", 1454 nat->registry_info.Felica==TRUE?"F":"", 1455 nat->registry_info.ISO14443_4A==TRUE?"4A":"", 1456 nat->registry_info.ISO14443_4B==TRUE?"4B":"", 1457 nat->registry_info.NFC==TRUE?"P2P":"", 1458 nat->registry_info.ISO15693==TRUE?"R":"", ret); 1459 1460 nfc_jni_start_discovery_locked(nat, false); 1461 clean_and_return: 1462 CONCURRENCY_UNLOCK(); 1463 } 1464 1465 static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) { 1466 CONCURRENCY_LOCK(); 1467 nfc_jni_reset_timeout_values(); 1468 CONCURRENCY_UNLOCK(); 1469 } 1470 1471 static void setFelicaTimeout(jint timeout) { 1472 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms. 1473 // It can be set to 0 to disable the timeout altogether, in which case we 1474 // use the sw watchdog as a fallback. 1475 if (timeout <= 255) { 1476 phLibNfc_SetFelicaTimeout(timeout); 1477 } else { 1478 // Disable hw timeout, use sw watchdog for timeout 1479 phLibNfc_SetFelicaTimeout(0); 1480 phLibNfc_SetHciTimeout(timeout); 1481 } 1482 1483 } 1484 // Calculates ceiling log2 of value 1485 static unsigned int log2(int value) { 1486 unsigned int ret = 0; 1487 bool isPowerOf2 = ((value & (value - 1)) == 0); 1488 while ( (value >> ret) > 1 ) ret++; 1489 if (!isPowerOf2) ret++; 1490 return ret; 1491 } 1492 1493 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X 1494 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X 1495 // 1496 // We keep the constant part of the formula in a static; note the factor 1497 // 1000 off, which is due to the fact that the formula calculates seconds, 1498 // but this method gets milliseconds as an argument. 1499 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0; 1500 1501 static int calcTimeout(int timeout_in_ms) { 1502 // timeout = (256 * 16 / 13560000) * 2 ^ X 1503 // First find the first X for which timeout > requested timeout 1504 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor))); 1505 } 1506 1507 static void setIsoDepTimeout(jint timeout) { 1508 if (timeout <= 4900) { 1509 int value = calcTimeout(timeout); 1510 // Then re-compute the actual timeout based on X 1511 double actual_timeout = nxp_nfc_timeout_factor * (1 << value); 1512 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate, 1513 // but it will take some time to get back through the sw layers. 1514 // 500 ms should be enough). 1515 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500)); 1516 value |= 0x10; // bit 4 to enable timeout 1517 phLibNfc_SetIsoXchgTimeout(value); 1518 } 1519 else { 1520 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout 1521 // must be disabled completely, to prevent the PN544 from aborting 1522 // the transaction. We reuse the HCI sw watchdog to catch the timeout 1523 // in that case. 1524 phLibNfc_SetIsoXchgTimeout(0x00); 1525 phLibNfc_SetHciTimeout(timeout); 1526 } 1527 } 1528 1529 static void setNfcATimeout(jint timeout) { 1530 if (timeout <= 4900) { 1531 int value = calcTimeout(timeout); 1532 phLibNfc_SetMifareRawTimeout(value); 1533 } 1534 else { 1535 // Disable mifare raw timeout, use HCI sw watchdog instead 1536 phLibNfc_SetMifareRawTimeout(0x00); 1537 phLibNfc_SetHciTimeout(timeout); 1538 } 1539 } 1540 1541 static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o, 1542 jint tech, jint timeout) { 1543 bool success = false; 1544 CONCURRENCY_LOCK(); 1545 if (timeout <= 0) { 1546 ALOGE("Timeout must be positive."); 1547 return false; 1548 } else { 1549 switch (tech) { 1550 case TARGET_TYPE_MIFARE_CLASSIC: 1551 case TARGET_TYPE_MIFARE_UL: 1552 // Intentional fall-through, Mifare UL, Classic 1553 // transceive just uses raw 3A frames 1554 case TARGET_TYPE_ISO14443_3A: 1555 setNfcATimeout(timeout); 1556 success = true; 1557 break; 1558 case TARGET_TYPE_ISO14443_4: 1559 setIsoDepTimeout(timeout); 1560 success = true; 1561 break; 1562 case TARGET_TYPE_FELICA: 1563 setFelicaTimeout(timeout); 1564 success = true; 1565 break; 1566 default: 1567 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech); 1568 success = false; 1569 } 1570 } 1571 CONCURRENCY_UNLOCK(); 1572 return success; 1573 } 1574 1575 static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o, 1576 jint tech) { 1577 int timeout = -1; 1578 CONCURRENCY_LOCK(); 1579 switch (tech) { 1580 case TARGET_TYPE_MIFARE_CLASSIC: 1581 case TARGET_TYPE_MIFARE_UL: 1582 // Intentional fall-through, Mifare UL, Classic 1583 // transceive just uses raw 3A frames 1584 case TARGET_TYPE_ISO14443_3A: 1585 timeout = phLibNfc_GetMifareRawTimeout(); 1586 if (timeout == 0) { 1587 timeout = phLibNfc_GetHciTimeout(); 1588 } else { 1589 // Timeout returned from libnfc needs conversion to ms 1590 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1591 } 1592 break; 1593 case TARGET_TYPE_ISO14443_4: 1594 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only 1595 if (timeout == 0) { 1596 timeout = phLibNfc_GetHciTimeout(); 1597 } else { 1598 // Timeout returned from libnfc needs conversion to ms 1599 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1600 } 1601 break; 1602 case TARGET_TYPE_FELICA: 1603 timeout = phLibNfc_GetFelicaTimeout(); 1604 if (timeout == 0) { 1605 timeout = phLibNfc_GetHciTimeout(); 1606 } else { 1607 // Felica timeout already in ms 1608 } 1609 break; 1610 default: 1611 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech); 1612 break; 1613 } 1614 CONCURRENCY_UNLOCK(); 1615 return timeout; 1616 } 1617 1618 1619 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o) 1620 { 1621 NFCSTATUS status; 1622 struct nfc_jni_native_data *nat = NULL; 1623 jclass cls; 1624 jobject obj; 1625 jfieldID f; 1626 1627 TRACE("****** Init Native Structure ******"); 1628 1629 /* Initialize native structure */ 1630 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); 1631 if(nat == NULL) 1632 { 1633 ALOGD("malloc of nfc_jni_native_data failed"); 1634 return FALSE; 1635 } 1636 memset(nat, 0, sizeof(*nat)); 1637 e->GetJavaVM(&(nat->vm)); 1638 nat->env_version = e->GetVersion(); 1639 nat->manager = e->NewGlobalRef(o); 1640 1641 cls = e->GetObjectClass(o); 1642 f = e->GetFieldID(cls, "mNative", "I"); 1643 e->SetIntField(o, f, (jint)nat); 1644 1645 /* Initialize native cached references */ 1646 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, 1647 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); 1648 1649 cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls, 1650 "notifyTransactionListeners", "([B)V"); 1651 1652 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, 1653 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1654 1655 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls, 1656 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1657 1658 cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls, 1659 "notifyTargetDeselected","()V"); 1660 1661 cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls, 1662 "notifySeFieldActivated", "()V"); 1663 1664 cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls, 1665 "notifySeFieldDeactivated", "()V"); 1666 1667 cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls, 1668 "notifySeApduReceived", "([B)V"); 1669 1670 cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls, 1671 "notifySeMifareAccess", "([B)V"); 1672 1673 cached_NfcManager_notifySeEmvCardRemoval = e->GetMethodID(cls, 1674 "notifySeEmvCardRemoval", "()V"); 1675 1676 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1) 1677 { 1678 ALOGD("Native Structure initialization failed"); 1679 return FALSE; 1680 } 1681 1682 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) 1683 { 1684 ALOGD("Native Structure initialization failed"); 1685 return FALSE; 1686 } 1687 TRACE("****** Init Native Structure OK ******"); 1688 return TRUE; 1689 1690 } 1691 1692 /* Init/Deinit method */ 1693 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) 1694 { 1695 struct nfc_jni_native_data *nat = NULL; 1696 int init_result = JNI_FALSE; 1697 #ifdef TNFC_EMULATOR_ONLY 1698 char value[PROPERTY_VALUE_MAX]; 1699 #endif 1700 jboolean result; 1701 1702 CONCURRENCY_LOCK(); 1703 1704 #ifdef TNFC_EMULATOR_ONLY 1705 if (!property_get("ro.kernel.qemu", value, 0)) 1706 { 1707 ALOGE("NFC Initialization failed: not running in an emulator\n"); 1708 goto clean_and_return; 1709 } 1710 #endif 1711 1712 /* Retrieve native structure address */ 1713 nat = nfc_jni_get_nat(e, o); 1714 1715 nat->seId = SMX_SECURE_ELEMENT_ID; 1716 1717 nat->lto = 150; // LLCP_LTO 1718 nat->miu = 128; // LLCP_MIU 1719 // WKS indicates well-known services; 1 << sap for each supported SAP. 1720 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4) 1721 nat->wks = 0x13; // LLCP_WKS 1722 nat->opt = 0; // LLCP_OPT 1723 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1724 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1725 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE; 1726 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE; 1727 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE; 1728 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE; 1729 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE; 1730 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE; 1731 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1732 1733 nat->registry_info.MifareUL = TRUE; 1734 nat->registry_info.MifareStd = TRUE; 1735 nat->registry_info.ISO14443_4A = TRUE; 1736 nat->registry_info.ISO14443_4B = TRUE; 1737 nat->registry_info.Jewel = TRUE; 1738 nat->registry_info.Felica = TRUE; 1739 nat->registry_info.NFC = TRUE; 1740 nat->registry_info.ISO15693 = TRUE; 1741 1742 exported_nat = nat; 1743 1744 /* Perform the initialization */ 1745 init_result = nfc_jni_initialize(nat); 1746 1747 clean_and_return: 1748 CONCURRENCY_UNLOCK(); 1749 1750 /* Convert the result and return */ 1751 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE; 1752 } 1753 1754 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o) 1755 { 1756 struct timespec ts; 1757 NFCSTATUS status; 1758 int result = JNI_FALSE; 1759 struct nfc_jni_native_data *nat; 1760 int bStackReset = FALSE; 1761 struct nfc_jni_callback_data cb_data; 1762 1763 CONCURRENCY_LOCK(); 1764 1765 /* Retrieve native structure address */ 1766 nat = nfc_jni_get_nat(e, o); 1767 1768 /* Clear previous configuration */ 1769 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t)); 1770 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t)); 1771 1772 /* Create the local semaphore */ 1773 if (nfc_cb_data_init(&cb_data, NULL)) 1774 { 1775 TRACE("phLibNfc_Mgt_DeInitialize()"); 1776 REENTRANCE_LOCK(); 1777 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data); 1778 REENTRANCE_UNLOCK(); 1779 if (status == NFCSTATUS_PENDING) 1780 { 1781 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1782 1783 clock_gettime(CLOCK_REALTIME, &ts); 1784 ts.tv_sec += 5; 1785 1786 /* Wait for callback response */ 1787 if(sem_timedwait(&cb_data.sem, &ts) == -1) 1788 { 1789 ALOGW("Operation timed out"); 1790 bStackReset = TRUE; 1791 } 1792 1793 if(cb_data.status != NFCSTATUS_SUCCESS) 1794 { 1795 ALOGE("Failed to deinit the stack"); 1796 bStackReset = TRUE; 1797 } 1798 } 1799 else 1800 { 1801 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1802 bStackReset = TRUE; 1803 } 1804 nfc_cb_data_deinit(&cb_data); 1805 } 1806 else 1807 { 1808 ALOGE("Failed to create semaphore (errno=0x%08x)", errno); 1809 bStackReset = TRUE; 1810 } 1811 1812 kill_client(nat); 1813 1814 if(bStackReset == TRUE) 1815 { 1816 /* Complete deinit. failed, try hard restart of NFC */ 1817 ALOGW("Reseting stack..."); 1818 emergency_recovery(nat); 1819 } 1820 1821 result = nfc_jni_unconfigure_driver(nat); 1822 1823 TRACE("NFC Deinitialized"); 1824 1825 CONCURRENCY_UNLOCK(); 1826 1827 return TRUE; 1828 } 1829 1830 /* Secure Element methods */ 1831 static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) { 1832 NFCSTATUS ret; 1833 jintArray list= NULL; 1834 phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE]; 1835 uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE; 1836 1837 TRACE("****** Get Secure Element List ******"); 1838 1839 TRACE("phLibNfc_SE_GetSecureElementList()"); 1840 REENTRANCE_LOCK(); 1841 ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count); 1842 REENTRANCE_UNLOCK(); 1843 if (ret != NFCSTATUS_SUCCESS) { 1844 ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, 1845 nfc_jni_get_status_name(ret)); 1846 return list; 1847 } 1848 TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, 1849 nfc_jni_get_status_name(ret)); 1850 1851 TRACE("Nb SE: %d", se_count); 1852 list =e->NewIntArray(se_count); 1853 for (i = 0; i < se_count; i++) { 1854 if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { 1855 ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected"); 1856 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); 1857 } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) { 1858 ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected"); 1859 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); 1860 } 1861 e->SetIntArrayRegion(list, i, 1, (jint*)&se_list[i].hSecureElement); 1862 } 1863 1864 e->DeleteLocalRef(list); 1865 1866 return list; 1867 } 1868 1869 static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) { 1870 NFCSTATUS ret; 1871 struct nfc_jni_native_data *nat; 1872 struct nfc_jni_callback_data cb_data; 1873 1874 CONCURRENCY_LOCK(); 1875 1876 /* Retrieve native structure address */ 1877 nat = nfc_jni_get_nat(e, o); 1878 1879 /* Create the local semaphore */ 1880 if (!nfc_cb_data_init(&cb_data, NULL)) { 1881 goto clean_and_return; 1882 } 1883 1884 TRACE("****** Select Secure Element ******"); 1885 1886 TRACE("phLibNfc_SE_SetMode()"); 1887 /* Set SE mode - Virtual */ 1888 REENTRANCE_LOCK(); 1889 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback, 1890 (void *)&cb_data); 1891 REENTRANCE_UNLOCK(); 1892 if (ret != NFCSTATUS_PENDING) { 1893 ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1894 goto clean_and_return; 1895 } 1896 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1897 1898 /* Wait for callback response */ 1899 if (sem_wait(&cb_data.sem)) { 1900 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1901 goto clean_and_return; 1902 } 1903 1904 clean_and_return: 1905 nfc_cb_data_deinit(&cb_data); 1906 CONCURRENCY_UNLOCK(); 1907 } 1908 1909 static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) { 1910 NFCSTATUS ret; 1911 struct nfc_jni_native_data *nat; 1912 struct nfc_jni_callback_data cb_data; 1913 1914 CONCURRENCY_LOCK(); 1915 1916 /* Retrieve native structure address */ 1917 nat = nfc_jni_get_nat(e, o); 1918 1919 /* Create the local semaphore */ 1920 if (!nfc_cb_data_init(&cb_data, NULL)) { 1921 goto clean_and_return; 1922 } 1923 1924 TRACE("****** Deselect Secure Element ******"); 1925 1926 TRACE("phLibNfc_SE_SetMode()"); 1927 /* Set SE mode - Default */ 1928 REENTRANCE_LOCK(); 1929 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, 1930 nfc_jni_se_set_mode_callback, (void *)&cb_data); 1931 REENTRANCE_UNLOCK(); 1932 1933 TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret); 1934 if (ret != NFCSTATUS_PENDING) { 1935 ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1936 goto clean_and_return; 1937 } 1938 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1939 1940 /* Wait for callback response */ 1941 if (sem_wait(&cb_data.sem)) { 1942 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1943 goto clean_and_return; 1944 } 1945 1946 clean_and_return: 1947 nfc_cb_data_deinit(&cb_data); 1948 CONCURRENCY_UNLOCK(); 1949 } 1950 1951 /* Llcp methods */ 1952 1953 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o) 1954 { 1955 NFCSTATUS ret; 1956 bool freeData = false; 1957 jboolean result = JNI_FALSE; 1958 struct nfc_jni_native_data *nat; 1959 struct nfc_jni_callback_data *cb_data; 1960 1961 1962 CONCURRENCY_LOCK(); 1963 1964 /* Memory allocation for cb_data 1965 * This is on the heap because it is used by libnfc 1966 * even after this call has succesfully finished. It is only freed 1967 * upon link closure in nfc_jni_llcp_linkStatus_callback. 1968 */ 1969 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data)); 1970 1971 /* Retrieve native structure address */ 1972 nat = nfc_jni_get_nat(e, o); 1973 1974 /* Create the local semaphore */ 1975 if (!nfc_cb_data_init(cb_data, (void*)nat)) 1976 { 1977 goto clean_and_return; 1978 } 1979 1980 /* Check LLCP compliancy */ 1981 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle); 1982 REENTRANCE_LOCK(); 1983 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle, 1984 nfc_jni_checkLlcp_callback, 1985 nfc_jni_llcp_linkStatus_callback, 1986 (void*)cb_data); 1987 REENTRANCE_UNLOCK(); 1988 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol 1989 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */ 1990 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) 1991 { 1992 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1993 freeData = true; 1994 goto clean_and_return; 1995 } 1996 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1997 1998 /* Wait for callback response */ 1999 if(sem_wait(&cb_data->sem)) 2000 { 2001 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2002 goto clean_and_return; 2003 } 2004 2005 if(cb_data->status == NFCSTATUS_SUCCESS) 2006 { 2007 result = JNI_TRUE; 2008 } 2009 2010 clean_and_return: 2011 nfc_cb_data_deinit(cb_data); 2012 if (freeData) { 2013 free(cb_data); 2014 } 2015 CONCURRENCY_UNLOCK(); 2016 return result; 2017 } 2018 2019 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o) 2020 { 2021 NFCSTATUS ret; 2022 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle); 2023 REENTRANCE_LOCK(); 2024 ret = phLibNfc_Llcp_Activate(hLlcpHandle); 2025 REENTRANCE_UNLOCK(); 2026 if(ret == NFCSTATUS_SUCCESS) 2027 { 2028 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2029 return JNI_TRUE; 2030 } 2031 else 2032 { 2033 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2034 return JNI_FALSE; 2035 } 2036 } 2037 2038 2039 2040 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o, 2041 jint nSap, jstring sn) 2042 { 2043 NFCSTATUS ret; 2044 jobject connectionlessSocket = NULL; 2045 phLibNfc_Handle hLlcpSocket; 2046 struct nfc_jni_native_data *nat; 2047 phNfc_sData_t sWorkingBuffer = {NULL, 0}; 2048 phNfc_sData_t serviceName = {NULL, 0}; 2049 phLibNfc_Llcp_sLinkParameters_t sParams; 2050 jclass clsNativeConnectionlessSocket; 2051 jfieldID f; 2052 2053 /* Retrieve native structure address */ 2054 nat = nfc_jni_get_nat(e, o); 2055 2056 /* Allocate Working buffer length */ 2057 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); 2058 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP 2059 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2060 2061 /* Create socket */ 2062 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)"); 2063 REENTRANCE_LOCK(); 2064 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess, 2065 NULL, 2066 &sWorkingBuffer, 2067 &hLlcpSocket, 2068 nfc_jni_llcp_transport_socket_err_callback, 2069 (void*)nat); 2070 REENTRANCE_UNLOCK(); 2071 2072 if(ret != NFCSTATUS_SUCCESS) 2073 { 2074 lastErrorStatus = ret; 2075 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2076 goto error; 2077 } 2078 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2079 2080 /* Service socket */ 2081 if (sn == NULL) { 2082 serviceName.buffer = NULL; 2083 serviceName.length = 0; 2084 } else { 2085 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2086 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2087 } 2088 2089 /* Bind socket */ 2090 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2091 REENTRANCE_LOCK(); 2092 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2093 REENTRANCE_UNLOCK(); 2094 if(ret != NFCSTATUS_SUCCESS) 2095 { 2096 lastErrorStatus = ret; 2097 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2098 /* Close socket created */ 2099 REENTRANCE_LOCK(); 2100 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2101 REENTRANCE_UNLOCK(); 2102 goto error; 2103 } 2104 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2105 2106 2107 /* Create new NativeLlcpConnectionlessSocket object */ 2108 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) 2109 { 2110 goto error; 2111 } 2112 2113 /* Get NativeConnectionless class object */ 2114 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); 2115 if(e->ExceptionCheck()) 2116 { 2117 goto error; 2118 } 2119 2120 /* Set socket handle */ 2121 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); 2122 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); 2123 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); 2124 2125 /* Set the miu link of the connectionless socket */ 2126 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); 2127 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); 2128 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); 2129 2130 /* Set socket SAP */ 2131 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); 2132 e->SetIntField(connectionlessSocket, f,(jint)nSap); 2133 TRACE("Connectionless socket SAP = %d\n",nSap); 2134 2135 return connectionlessSocket; 2136 error: 2137 if (serviceName.buffer != NULL) { 2138 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2139 } 2140 2141 if (sWorkingBuffer.buffer != NULL) { 2142 free(sWorkingBuffer.buffer); 2143 } 2144 2145 return NULL; 2146 } 2147 2148 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) 2149 { 2150 NFCSTATUS ret; 2151 phLibNfc_Handle hLlcpSocket; 2152 phLibNfc_Llcp_sSocketOptions_t sOptions; 2153 phNfc_sData_t sWorkingBuffer; 2154 phNfc_sData_t serviceName; 2155 struct nfc_jni_native_data *nat; 2156 jobject serviceSocket = NULL; 2157 jclass clsNativeLlcpServiceSocket; 2158 jfieldID f; 2159 2160 /* Retrieve native structure address */ 2161 nat = nfc_jni_get_nat(e, o); 2162 2163 /* Set Connection Oriented socket options */ 2164 sOptions.miu = miu; 2165 sOptions.rw = rw; 2166 2167 /* Allocate Working buffer length */ 2168 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2169 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2170 2171 2172 /* Create socket */ 2173 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); 2174 REENTRANCE_LOCK(); 2175 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2176 &sOptions, 2177 &sWorkingBuffer, 2178 &hLlcpSocket, 2179 nfc_jni_llcp_transport_socket_err_callback, 2180 (void*)nat); 2181 REENTRANCE_UNLOCK(); 2182 2183 if(ret != NFCSTATUS_SUCCESS) 2184 { 2185 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2186 lastErrorStatus = ret; 2187 goto error; 2188 } 2189 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2190 2191 /* Service socket */ 2192 if (sn == NULL) { 2193 serviceName.buffer = NULL; 2194 serviceName.length = 0; 2195 } else { 2196 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2197 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2198 } 2199 2200 /* Bind socket */ 2201 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2202 REENTRANCE_LOCK(); 2203 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2204 REENTRANCE_UNLOCK(); 2205 if(ret != NFCSTATUS_SUCCESS) 2206 { 2207 lastErrorStatus = ret; 2208 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2209 /* Close socket created */ 2210 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2211 goto error; 2212 } 2213 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2214 2215 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket); 2216 REENTRANCE_LOCK(); 2217 ret = phLibNfc_Llcp_Listen( hLlcpSocket, 2218 nfc_jni_llcp_transport_listen_socket_callback, 2219 (void*)hLlcpSocket); 2220 REENTRANCE_UNLOCK(); 2221 2222 if(ret != NFCSTATUS_SUCCESS) 2223 { 2224 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2225 lastErrorStatus = ret; 2226 /* Close created socket */ 2227 REENTRANCE_LOCK(); 2228 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2229 REENTRANCE_UNLOCK(); 2230 goto error; 2231 } 2232 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2233 2234 /* Create new NativeLlcpServiceSocket object */ 2235 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1) 2236 { 2237 ALOGE("Llcp Socket object creation error"); 2238 goto error; 2239 } 2240 2241 /* Get NativeLlcpServiceSocket class object */ 2242 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); 2243 if(e->ExceptionCheck()) 2244 { 2245 ALOGE("Llcp Socket get object class error"); 2246 goto error; 2247 } 2248 2249 /* Set socket handle */ 2250 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); 2251 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); 2252 TRACE("Service socket Handle = %02x\n",hLlcpSocket); 2253 2254 /* Set socket linear buffer length */ 2255 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); 2256 e->SetIntField(serviceSocket, f,(jint)linearBufferLength); 2257 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); 2258 2259 /* Set socket MIU */ 2260 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); 2261 e->SetIntField(serviceSocket, f,(jint)miu); 2262 TRACE("Service socket MIU = %d\n",miu); 2263 2264 /* Set socket RW */ 2265 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); 2266 e->SetIntField(serviceSocket, f,(jint)rw); 2267 TRACE("Service socket RW = %d\n",rw); 2268 2269 return serviceSocket; 2270 error: 2271 if (serviceName.buffer != NULL) { 2272 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2273 } 2274 return NULL; 2275 } 2276 2277 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) 2278 { 2279 jobject clientSocket = NULL; 2280 NFCSTATUS ret; 2281 phLibNfc_Handle hLlcpSocket; 2282 phLibNfc_Llcp_sSocketOptions_t sOptions; 2283 phNfc_sData_t sWorkingBuffer; 2284 struct nfc_jni_native_data *nat; 2285 jclass clsNativeLlcpSocket; 2286 jfieldID f; 2287 2288 /* Retrieve native structure address */ 2289 nat = nfc_jni_get_nat(e, o); 2290 2291 /* Set Connection Oriented socket options */ 2292 sOptions.miu = miu; 2293 sOptions.rw = rw; 2294 2295 /* Allocate Working buffer length */ 2296 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2297 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2298 2299 /* Create socket */ 2300 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)"); 2301 REENTRANCE_LOCK(); 2302 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2303 &sOptions, 2304 &sWorkingBuffer, 2305 &hLlcpSocket, 2306 nfc_jni_llcp_transport_socket_err_callback, 2307 (void*)nat); 2308 REENTRANCE_UNLOCK(); 2309 2310 if(ret != NFCSTATUS_SUCCESS) 2311 { 2312 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2313 lastErrorStatus = ret; 2314 return NULL; 2315 } 2316 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2317 2318 /* Create new NativeLlcpSocket object */ 2319 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1) 2320 { 2321 ALOGE("Llcp socket object creation error"); 2322 return NULL; 2323 } 2324 2325 /* Get NativeConnectionless class object */ 2326 clsNativeLlcpSocket = e->GetObjectClass(clientSocket); 2327 if(e->ExceptionCheck()) 2328 { 2329 ALOGE("Get class object error"); 2330 return NULL; 2331 } 2332 2333 /* Test if an SAP number is present */ 2334 if(nSap != 0) 2335 { 2336 /* Bind socket */ 2337 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2338 REENTRANCE_LOCK(); 2339 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL); 2340 REENTRANCE_UNLOCK(); 2341 if(ret != NFCSTATUS_SUCCESS) 2342 { 2343 lastErrorStatus = ret; 2344 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2345 /* Close socket created */ 2346 REENTRANCE_LOCK(); 2347 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2348 REENTRANCE_UNLOCK(); 2349 return NULL; 2350 } 2351 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2352 2353 /* Set socket SAP */ 2354 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); 2355 e->SetIntField(clientSocket, f,(jint)nSap); 2356 TRACE("socket SAP = %d\n",nSap); 2357 } 2358 2359 /* Set socket handle */ 2360 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); 2361 e->SetIntField(clientSocket, f,(jint)hLlcpSocket); 2362 TRACE("socket Handle = %02x\n",hLlcpSocket); 2363 2364 /* Set socket MIU */ 2365 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); 2366 e->SetIntField(clientSocket, f,(jint)miu); 2367 TRACE("socket MIU = %d\n",miu); 2368 2369 /* Set socket RW */ 2370 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); 2371 e->SetIntField(clientSocket, f,(jint)rw); 2372 TRACE("socket RW = %d\n",rw); 2373 2374 2375 return clientSocket; 2376 } 2377 2378 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o) 2379 { 2380 TRACE("Last Error Status = 0x%02x",lastErrorStatus); 2381 2382 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) 2383 { 2384 return ERROR_BUFFER_TOO_SMALL; 2385 } 2386 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES) 2387 { 2388 return ERROR_INSUFFICIENT_RESOURCES; 2389 } 2390 else 2391 { 2392 return lastErrorStatus; 2393 } 2394 } 2395 2396 static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o) 2397 { 2398 emergency_recovery(NULL); 2399 } 2400 2401 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o, 2402 jint modes) 2403 { 2404 ALOGE("Setting init modes to %x", modes); 2405 struct nfc_jni_native_data *nat = NULL; 2406 nat = nfc_jni_get_nat(e, o); 2407 nat->p2p_initiator_modes = modes; 2408 } 2409 2410 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o, 2411 jint modes) 2412 { 2413 ALOGE("Setting target modes to %x", modes); 2414 struct nfc_jni_native_data *nat = NULL; 2415 nat = nfc_jni_get_nat(e, o); 2416 nat->p2p_target_modes = modes; 2417 } 2418 2419 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) { 2420 bool result = FALSE; 2421 int load_result; 2422 bool wasDisabled = FALSE; 2423 uint8_t OutputBuffer[1]; 2424 uint8_t InputBuffer[1]; 2425 NFCSTATUS status = NFCSTATUS_FAILED; 2426 struct nfc_jni_callback_data cb_data; 2427 2428 /* Create the local semaphore */ 2429 if (!nfc_cb_data_init(&cb_data, NULL)) 2430 { 2431 result = FALSE; 2432 goto clean_and_return; 2433 } 2434 2435 if (takeLock) 2436 { 2437 CONCURRENCY_LOCK(); 2438 } 2439 2440 /* Initialize Driver */ 2441 if(!driverConfigured) 2442 { 2443 result = nfc_jni_configure_driver(nat); 2444 wasDisabled = TRUE; 2445 } 2446 TRACE("com_android_nfc_NfcManager_doDownload()"); 2447 2448 TRACE("Go in Download Mode"); 2449 phLibNfc_Download_Mode(); 2450 2451 TRACE("Load new Firmware Image"); 2452 load_result = phLibNfc_Load_Firmware_Image(); 2453 if(load_result != 0) 2454 { 2455 TRACE("Load new Firmware Image - status = %d",load_result); 2456 result = FALSE; 2457 goto clean_and_return; 2458 } 2459 2460 // Download 2461 gInputParam.buffer = InputBuffer; 2462 gInputParam.length = 0x01; 2463 gOutputParam.buffer = OutputBuffer; 2464 gOutputParam.length = 0x01; 2465 2466 ALOGD("Download new Firmware"); 2467 REENTRANCE_LOCK(); 2468 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); 2469 REENTRANCE_UNLOCK(); 2470 if(status != NFCSTATUS_PENDING) 2471 { 2472 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2473 result = FALSE; 2474 goto clean_and_return; 2475 } 2476 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2477 2478 /* Wait for callback response */ 2479 if(sem_wait(&cb_data.sem)) 2480 { 2481 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2482 result = FALSE; 2483 goto clean_and_return; 2484 } 2485 2486 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we 2487 try to download an old-style firmware on top of a new-style 2488 firmware. Hence, this is expected behavior, and not an 2489 error condition. */ 2490 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED) 2491 { 2492 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2493 result = FALSE; 2494 goto clean_and_return; 2495 } 2496 2497 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED) 2498 { 2499 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip."); 2500 } 2501 2502 /*Download is successful*/ 2503 result = TRUE; 2504 clean_and_return: 2505 TRACE("phLibNfc_HW_Reset()"); 2506 phLibNfc_HW_Reset(); 2507 /* Deinitialize Driver */ 2508 if(wasDisabled) 2509 { 2510 result = nfc_jni_unconfigure_driver(nat); 2511 } 2512 if (takeLock) 2513 { 2514 CONCURRENCY_UNLOCK(); 2515 } 2516 nfc_cb_data_deinit(&cb_data); 2517 return result; 2518 } 2519 2520 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o) 2521 { 2522 struct nfc_jni_native_data *nat = NULL; 2523 nat = nfc_jni_get_nat(e, o); 2524 return performDownload(nat, true); 2525 } 2526 2527 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o) 2528 { 2529 char buffer[100]; 2530 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count); 2531 return e->NewStringUTF(buffer); 2532 } 2533 2534 /* 2535 * JNI registration. 2536 */ 2537 static JNINativeMethod gMethods[] = 2538 { 2539 {"doDownload", "()Z", 2540 (void *)com_android_nfc_NfcManager_doDownload}, 2541 2542 {"initializeNativeStructure", "()Z", 2543 (void *)com_android_nfc_NfcManager_init_native_struc}, 2544 2545 {"doInitialize", "()Z", 2546 (void *)com_android_nfc_NfcManager_initialize}, 2547 2548 {"doDeinitialize", "()Z", 2549 (void *)com_android_nfc_NfcManager_deinitialize}, 2550 2551 {"enableDiscovery", "()V", 2552 (void *)com_android_nfc_NfcManager_enableDiscovery}, 2553 2554 {"doGetSecureElementList", "()[I", 2555 (void *)com_android_nfc_NfcManager_doGetSecureElementList}, 2556 2557 {"doSelectSecureElement", "()V", 2558 (void *)com_android_nfc_NfcManager_doSelectSecureElement}, 2559 2560 {"doDeselectSecureElement", "()V", 2561 (void *)com_android_nfc_NfcManager_doDeselectSecureElement}, 2562 2563 {"doCheckLlcp", "()Z", 2564 (void *)com_android_nfc_NfcManager_doCheckLlcp}, 2565 2566 {"doActivateLlcp", "()Z", 2567 (void *)com_android_nfc_NfcManager_doActivateLlcp}, 2568 2569 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;", 2570 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket}, 2571 2572 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;", 2573 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket}, 2574 2575 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;", 2576 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, 2577 2578 {"doGetLastError", "()I", 2579 (void *)com_android_nfc_NfcManager_doGetLastError}, 2580 2581 {"disableDiscovery", "()V", 2582 (void *)com_android_nfc_NfcManager_disableDiscovery}, 2583 2584 {"doSetTimeout", "(II)Z", 2585 (void *)com_android_nfc_NfcManager_doSetTimeout}, 2586 2587 {"doGetTimeout", "(I)I", 2588 (void *)com_android_nfc_NfcManager_doGetTimeout}, 2589 2590 {"doResetTimeouts", "()V", 2591 (void *)com_android_nfc_NfcManager_doResetTimeouts}, 2592 2593 {"doAbort", "()V", 2594 (void *)com_android_nfc_NfcManager_doAbort}, 2595 2596 {"doSetP2pInitiatorModes","(I)V", 2597 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes}, 2598 2599 {"doSetP2pTargetModes","(I)V", 2600 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes}, 2601 2602 {"doDump", "()Ljava/lang/String;", 2603 (void *)com_android_nfc_NfcManager_doDump}, 2604 }; 2605 2606 2607 int register_com_android_nfc_NativeNfcManager(JNIEnv *e) 2608 { 2609 nfc_jni_native_monitor_t *nfc_jni_native_monitor; 2610 2611 nfc_jni_native_monitor = nfc_jni_init_monitor(); 2612 if(nfc_jni_native_monitor == NULL) 2613 { 2614 ALOGE("NFC Manager cannot recover native monitor %x\n", errno); 2615 return -1; 2616 } 2617 2618 return jniRegisterNativeMethods(e, 2619 "com/android/nfc/dhimpl/NativeNfcManager", 2620 gMethods, NELEM(gMethods)); 2621 } 2622 2623 } /* namespace android */ 2624