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 char aid_str[AID_MAXLEN * 2 + 1]; 1168 aid_str[0] = '\0'; 1169 for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) { 1170 snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]); 1171 } 1172 ALOGD("> AID: %s", aid_str); 1173 1174 tmp_array = e->NewByteArray(aid->length); 1175 if (tmp_array == NULL) 1176 { 1177 goto error; 1178 } 1179 1180 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer); 1181 if(e->ExceptionCheck()) 1182 { 1183 goto error; 1184 } 1185 } 1186 else 1187 { 1188 goto error; 1189 } 1190 1191 TRACE("Notify Nfc Service"); 1192 /* Notify manager that a new event occurred on a SE */ 1193 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array); 1194 if(e->ExceptionCheck()) 1195 { 1196 goto error; 1197 } 1198 } 1199 else 1200 { 1201 ALOGD("> NO AID DETECTED"); 1202 } 1203 }break; 1204 1205 case phLibNfc_eSE_EvtApduReceived: 1206 { 1207 phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid); 1208 TRACE("> SE EVT_APDU_RECEIVED"); 1209 1210 if (apdu != NULL) { 1211 TRACE(" APDU length=%d", apdu->length); 1212 tmp_array = e->NewByteArray(apdu->length); 1213 if (tmp_array == NULL) { 1214 goto error; 1215 } 1216 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer); 1217 if (e->ExceptionCheck()) { 1218 goto error; 1219 } 1220 } else { 1221 TRACE(" APDU EMPTY"); 1222 } 1223 1224 TRACE("Notify Nfc Service"); 1225 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array); 1226 }break; 1227 1228 case phLibNfc_eSE_EvtCardRemoval: 1229 { 1230 TRACE("> SE EVT_EMV_CARD_REMOVAL"); 1231 TRACE("Notify Nfc Service"); 1232 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval); 1233 }break; 1234 1235 case phLibNfc_eSE_EvtMifareAccess: 1236 { 1237 TRACE("> SE EVT_MIFARE_ACCESS"); 1238 mifare_command = &(evt_info->UiccEvtInfo.aid); 1239 TRACE("> MIFARE Block: %d",mifare_command->buffer[1]); 1240 tmp_array = e->NewByteArray(2); 1241 if (tmp_array == NULL) 1242 { 1243 goto error; 1244 } 1245 1246 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer); 1247 if(e->ExceptionCheck()) 1248 { 1249 goto error; 1250 } 1251 TRACE("Notify Nfc Service"); 1252 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block); 1253 }break; 1254 1255 case phLibNfc_eSE_EvtFieldOn: 1256 { 1257 TRACE("> SE EVT_FIELD_ON"); 1258 TRACE("Notify Nfc Service"); 1259 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated); 1260 }break; 1261 1262 case phLibNfc_eSE_EvtFieldOff: 1263 { 1264 TRACE("> SE EVT_FIELD_OFF"); 1265 TRACE("Notify Nfc Service"); 1266 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated); 1267 }break; 1268 1269 default: 1270 { 1271 TRACE("Unknown SE event"); 1272 }break; 1273 } 1274 } 1275 else 1276 { 1277 ALOGE("SE transaction notification error"); 1278 goto error; 1279 } 1280 1281 /* Function finished, now clean and return */ 1282 goto clean_and_return; 1283 1284 error: 1285 /* In case of error, just discard the notification */ 1286 ALOGE("Failed to send SE transaction notification"); 1287 e->ExceptionClear(); 1288 1289 clean_and_return: 1290 if(tmp_array != NULL) 1291 { 1292 e->DeleteLocalRef(tmp_array); 1293 } 1294 } 1295 1296 static void nfc_jni_se_set_mode_callback(void *pContext, 1297 phLibNfc_Handle handle, NFCSTATUS status) 1298 { 1299 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1300 1301 LOG_CALLBACK("nfc_jni_se_set_mode_callback", status); 1302 1303 pContextData->status = status; 1304 sem_post(&pContextData->sem); 1305 } 1306 1307 /* 1308 * NFCManager methods 1309 */ 1310 1311 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume) 1312 { 1313 NFCSTATUS ret; 1314 struct nfc_jni_callback_data cb_data; 1315 1316 /* Create the local semaphore */ 1317 if (!nfc_cb_data_init(&cb_data, NULL)) 1318 { 1319 goto clean_and_return; 1320 } 1321 /* Reset the PN544 ISO XCHG / sw watchdog timeouts */ 1322 nfc_jni_reset_timeout_values(); 1323 1324 /* Reload the p2p modes */ 1325 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator 1326 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target 1327 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; 1328 1329 /* Reset device connected flag */ 1330 device_connected_flag = 0; 1331 1332 /* Start Polling loop */ 1333 TRACE("****** Start NFC Discovery ******"); 1334 REENTRANCE_LOCK(); 1335 ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG, 1336 nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1337 REENTRANCE_UNLOCK(); 1338 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1339 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1340 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1341 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1342 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1343 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1344 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1345 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1346 nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret); 1347 1348 if(ret != NFCSTATUS_PENDING) 1349 { 1350 emergency_recovery(nat); 1351 goto clean_and_return; 1352 } 1353 1354 /* Wait for callback response */ 1355 if(sem_wait(&cb_data.sem)) 1356 { 1357 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1358 goto clean_and_return; 1359 } 1360 1361 clean_and_return: 1362 nfc_cb_data_deinit(&cb_data); 1363 } 1364 1365 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) 1366 { 1367 phLibNfc_sADD_Cfg_t discovery_cfg; 1368 NFCSTATUS ret; 1369 struct nfc_jni_callback_data cb_data; 1370 1371 /* Create the local semaphore */ 1372 if (!nfc_cb_data_init(&cb_data, NULL)) 1373 { 1374 goto clean_and_return; 1375 } 1376 1377 discovery_cfg.PollDevInfo.PollEnabled = 0; 1378 discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode; 1379 discovery_cfg.NfcIP_Target_Mode = 0; 1380 discovery_cfg.NfcIP_Tgt_Disable = TRUE; 1381 1382 /* Start Polling loop */ 1383 TRACE("****** Stop NFC Discovery ******"); 1384 REENTRANCE_LOCK(); 1385 ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1386 REENTRANCE_UNLOCK(); 1387 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1388 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1389 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1390 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1391 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1392 discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1393 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1394 discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1395 discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret); 1396 1397 if(ret != NFCSTATUS_PENDING) 1398 { 1399 emergency_recovery(nat); 1400 } 1401 1402 /* Wait for callback response */ 1403 if(sem_wait(&cb_data.sem)) 1404 { 1405 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1406 goto clean_and_return; 1407 } 1408 1409 clean_and_return: 1410 nfc_cb_data_deinit(&cb_data); 1411 } 1412 1413 1414 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) 1415 { 1416 struct nfc_jni_native_data *nat; 1417 1418 CONCURRENCY_LOCK(); 1419 1420 /* Retrieve native structure address */ 1421 nat = nfc_jni_get_nat(e, o); 1422 1423 nfc_jni_stop_discovery_locked(nat); 1424 1425 CONCURRENCY_UNLOCK(); 1426 1427 } 1428 1429 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) { 1430 NFCSTATUS ret; 1431 struct nfc_jni_native_data *nat; 1432 1433 CONCURRENCY_LOCK(); 1434 1435 nat = nfc_jni_get_nat(e, o); 1436 1437 /* Register callback for remote device notifications. 1438 * Must re-register every time we turn on discovery, since other operations 1439 * (such as opening the Secure Element) can change the remote device 1440 * notification callback*/ 1441 REENTRANCE_LOCK(); 1442 ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat); 1443 REENTRANCE_UNLOCK(); 1444 if(ret != NFCSTATUS_SUCCESS) 1445 { 1446 ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret); 1447 goto clean_and_return; 1448 } 1449 TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n", 1450 nat->registry_info.Jewel==TRUE?"J":"", 1451 nat->registry_info.MifareUL==TRUE?"UL":"", 1452 nat->registry_info.MifareStd==TRUE?"Mi":"", 1453 nat->registry_info.Felica==TRUE?"F":"", 1454 nat->registry_info.ISO14443_4A==TRUE?"4A":"", 1455 nat->registry_info.ISO14443_4B==TRUE?"4B":"", 1456 nat->registry_info.NFC==TRUE?"P2P":"", 1457 nat->registry_info.ISO15693==TRUE?"R":"", ret); 1458 1459 nfc_jni_start_discovery_locked(nat, false); 1460 clean_and_return: 1461 CONCURRENCY_UNLOCK(); 1462 } 1463 1464 static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) { 1465 CONCURRENCY_LOCK(); 1466 nfc_jni_reset_timeout_values(); 1467 CONCURRENCY_UNLOCK(); 1468 } 1469 1470 static void setFelicaTimeout(jint timeout) { 1471 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms. 1472 // It can be set to 0 to disable the timeout altogether, in which case we 1473 // use the sw watchdog as a fallback. 1474 if (timeout <= 255) { 1475 phLibNfc_SetFelicaTimeout(timeout); 1476 } else { 1477 // Disable hw timeout, use sw watchdog for timeout 1478 phLibNfc_SetFelicaTimeout(0); 1479 phLibNfc_SetHciTimeout(timeout); 1480 } 1481 1482 } 1483 // Calculates ceiling log2 of value 1484 static unsigned int log2(int value) { 1485 unsigned int ret = 0; 1486 bool isPowerOf2 = ((value & (value - 1)) == 0); 1487 while ( (value >> ret) > 1 ) ret++; 1488 if (!isPowerOf2) ret++; 1489 return ret; 1490 } 1491 1492 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X 1493 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X 1494 // 1495 // We keep the constant part of the formula in a static; note the factor 1496 // 1000 off, which is due to the fact that the formula calculates seconds, 1497 // but this method gets milliseconds as an argument. 1498 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0; 1499 1500 static int calcTimeout(int timeout_in_ms) { 1501 // timeout = (256 * 16 / 13560000) * 2 ^ X 1502 // First find the first X for which timeout > requested timeout 1503 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor))); 1504 } 1505 1506 static void setIsoDepTimeout(jint timeout) { 1507 if (timeout <= 4900) { 1508 int value = calcTimeout(timeout); 1509 // Then re-compute the actual timeout based on X 1510 double actual_timeout = nxp_nfc_timeout_factor * (1 << value); 1511 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate, 1512 // but it will take some time to get back through the sw layers. 1513 // 500 ms should be enough). 1514 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500)); 1515 value |= 0x10; // bit 4 to enable timeout 1516 phLibNfc_SetIsoXchgTimeout(value); 1517 } 1518 else { 1519 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout 1520 // must be disabled completely, to prevent the PN544 from aborting 1521 // the transaction. We reuse the HCI sw watchdog to catch the timeout 1522 // in that case. 1523 phLibNfc_SetIsoXchgTimeout(0x00); 1524 phLibNfc_SetHciTimeout(timeout); 1525 } 1526 } 1527 1528 static void setNfcATimeout(jint timeout) { 1529 if (timeout <= 4900) { 1530 int value = calcTimeout(timeout); 1531 phLibNfc_SetMifareRawTimeout(value); 1532 } 1533 else { 1534 // Disable mifare raw timeout, use HCI sw watchdog instead 1535 phLibNfc_SetMifareRawTimeout(0x00); 1536 phLibNfc_SetHciTimeout(timeout); 1537 } 1538 } 1539 1540 static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o, 1541 jint tech, jint timeout) { 1542 bool success = false; 1543 CONCURRENCY_LOCK(); 1544 if (timeout <= 0) { 1545 ALOGE("Timeout must be positive."); 1546 return false; 1547 } else { 1548 switch (tech) { 1549 case TARGET_TYPE_MIFARE_CLASSIC: 1550 case TARGET_TYPE_MIFARE_UL: 1551 // Intentional fall-through, Mifare UL, Classic 1552 // transceive just uses raw 3A frames 1553 case TARGET_TYPE_ISO14443_3A: 1554 setNfcATimeout(timeout); 1555 success = true; 1556 break; 1557 case TARGET_TYPE_ISO14443_4: 1558 setIsoDepTimeout(timeout); 1559 success = true; 1560 break; 1561 case TARGET_TYPE_FELICA: 1562 setFelicaTimeout(timeout); 1563 success = true; 1564 break; 1565 default: 1566 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech); 1567 success = false; 1568 } 1569 } 1570 CONCURRENCY_UNLOCK(); 1571 return success; 1572 } 1573 1574 static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o, 1575 jint tech) { 1576 int timeout = -1; 1577 CONCURRENCY_LOCK(); 1578 switch (tech) { 1579 case TARGET_TYPE_MIFARE_CLASSIC: 1580 case TARGET_TYPE_MIFARE_UL: 1581 // Intentional fall-through, Mifare UL, Classic 1582 // transceive just uses raw 3A frames 1583 case TARGET_TYPE_ISO14443_3A: 1584 timeout = phLibNfc_GetMifareRawTimeout(); 1585 if (timeout == 0) { 1586 timeout = phLibNfc_GetHciTimeout(); 1587 } else { 1588 // Timeout returned from libnfc needs conversion to ms 1589 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1590 } 1591 break; 1592 case TARGET_TYPE_ISO14443_4: 1593 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only 1594 if (timeout == 0) { 1595 timeout = phLibNfc_GetHciTimeout(); 1596 } else { 1597 // Timeout returned from libnfc needs conversion to ms 1598 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1599 } 1600 break; 1601 case TARGET_TYPE_FELICA: 1602 timeout = phLibNfc_GetFelicaTimeout(); 1603 if (timeout == 0) { 1604 timeout = phLibNfc_GetHciTimeout(); 1605 } else { 1606 // Felica timeout already in ms 1607 } 1608 break; 1609 default: 1610 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech); 1611 break; 1612 } 1613 CONCURRENCY_UNLOCK(); 1614 return timeout; 1615 } 1616 1617 1618 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o) 1619 { 1620 NFCSTATUS status; 1621 struct nfc_jni_native_data *nat = NULL; 1622 jclass cls; 1623 jobject obj; 1624 jfieldID f; 1625 1626 TRACE("****** Init Native Structure ******"); 1627 1628 /* Initialize native structure */ 1629 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); 1630 if(nat == NULL) 1631 { 1632 ALOGD("malloc of nfc_jni_native_data failed"); 1633 return FALSE; 1634 } 1635 memset(nat, 0, sizeof(*nat)); 1636 e->GetJavaVM(&(nat->vm)); 1637 nat->env_version = e->GetVersion(); 1638 nat->manager = e->NewGlobalRef(o); 1639 1640 cls = e->GetObjectClass(o); 1641 f = e->GetFieldID(cls, "mNative", "I"); 1642 e->SetIntField(o, f, (jint)nat); 1643 1644 /* Initialize native cached references */ 1645 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, 1646 "notifyNdefMessageListeners","(Lcom/android/nfc/nxp/NativeNfcTag;)V"); 1647 1648 cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls, 1649 "notifyTransactionListeners", "([B)V"); 1650 1651 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, 1652 "notifyLlcpLinkActivation","(Lcom/android/nfc/nxp/NativeP2pDevice;)V"); 1653 1654 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls, 1655 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/nxp/NativeP2pDevice;)V"); 1656 1657 cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls, 1658 "notifyTargetDeselected","()V"); 1659 1660 cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls, 1661 "notifySeFieldActivated", "()V"); 1662 1663 cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls, 1664 "notifySeFieldDeactivated", "()V"); 1665 1666 cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls, 1667 "notifySeApduReceived", "([B)V"); 1668 1669 cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls, 1670 "notifySeMifareAccess", "([B)V"); 1671 1672 cached_NfcManager_notifySeEmvCardRemoval = e->GetMethodID(cls, 1673 "notifySeEmvCardRemoval", "()V"); 1674 1675 if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeNfcTag",&(nat->cached_NfcTag)) == -1) 1676 { 1677 ALOGD("Native Structure initialization failed"); 1678 return FALSE; 1679 } 1680 1681 if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) 1682 { 1683 ALOGD("Native Structure initialization failed"); 1684 return FALSE; 1685 } 1686 TRACE("****** Init Native Structure OK ******"); 1687 return TRUE; 1688 1689 } 1690 1691 /* Init/Deinit method */ 1692 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) 1693 { 1694 struct nfc_jni_native_data *nat = NULL; 1695 int init_result = JNI_FALSE; 1696 #ifdef TNFC_EMULATOR_ONLY 1697 char value[PROPERTY_VALUE_MAX]; 1698 #endif 1699 jboolean result; 1700 1701 CONCURRENCY_LOCK(); 1702 1703 #ifdef TNFC_EMULATOR_ONLY 1704 if (!property_get("ro.kernel.qemu", value, 0)) 1705 { 1706 ALOGE("NFC Initialization failed: not running in an emulator\n"); 1707 goto clean_and_return; 1708 } 1709 #endif 1710 1711 /* Retrieve native structure address */ 1712 nat = nfc_jni_get_nat(e, o); 1713 1714 nat->seId = SMX_SECURE_ELEMENT_ID; 1715 1716 nat->lto = 150; // LLCP_LTO 1717 nat->miu = 128; // LLCP_MIU 1718 // WKS indicates well-known services; 1 << sap for each supported SAP. 1719 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4) 1720 nat->wks = 0x13; // LLCP_WKS 1721 nat->opt = 0; // LLCP_OPT 1722 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1723 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1724 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE; 1725 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE; 1726 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE; 1727 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE; 1728 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE; 1729 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE; 1730 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1731 1732 nat->registry_info.MifareUL = TRUE; 1733 nat->registry_info.MifareStd = TRUE; 1734 nat->registry_info.ISO14443_4A = TRUE; 1735 nat->registry_info.ISO14443_4B = TRUE; 1736 nat->registry_info.Jewel = TRUE; 1737 nat->registry_info.Felica = TRUE; 1738 nat->registry_info.NFC = TRUE; 1739 nat->registry_info.ISO15693 = TRUE; 1740 1741 exported_nat = nat; 1742 1743 /* Perform the initialization */ 1744 init_result = nfc_jni_initialize(nat); 1745 1746 clean_and_return: 1747 CONCURRENCY_UNLOCK(); 1748 1749 /* Convert the result and return */ 1750 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE; 1751 } 1752 1753 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o) 1754 { 1755 struct timespec ts; 1756 NFCSTATUS status; 1757 int result = JNI_FALSE; 1758 struct nfc_jni_native_data *nat; 1759 int bStackReset = FALSE; 1760 struct nfc_jni_callback_data cb_data; 1761 1762 CONCURRENCY_LOCK(); 1763 1764 /* Retrieve native structure address */ 1765 nat = nfc_jni_get_nat(e, o); 1766 1767 /* Clear previous configuration */ 1768 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t)); 1769 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t)); 1770 1771 /* Create the local semaphore */ 1772 if (nfc_cb_data_init(&cb_data, NULL)) 1773 { 1774 TRACE("phLibNfc_Mgt_DeInitialize()"); 1775 REENTRANCE_LOCK(); 1776 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data); 1777 REENTRANCE_UNLOCK(); 1778 if (status == NFCSTATUS_PENDING) 1779 { 1780 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1781 1782 clock_gettime(CLOCK_REALTIME, &ts); 1783 ts.tv_sec += 5; 1784 1785 /* Wait for callback response */ 1786 if(sem_timedwait(&cb_data.sem, &ts) == -1) 1787 { 1788 ALOGW("Operation timed out"); 1789 bStackReset = TRUE; 1790 } 1791 1792 if(cb_data.status != NFCSTATUS_SUCCESS) 1793 { 1794 ALOGE("Failed to deinit the stack"); 1795 bStackReset = TRUE; 1796 } 1797 } 1798 else 1799 { 1800 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1801 bStackReset = TRUE; 1802 } 1803 nfc_cb_data_deinit(&cb_data); 1804 } 1805 else 1806 { 1807 ALOGE("Failed to create semaphore (errno=0x%08x)", errno); 1808 bStackReset = TRUE; 1809 } 1810 1811 kill_client(nat); 1812 1813 if(bStackReset == TRUE) 1814 { 1815 /* Complete deinit. failed, try hard restart of NFC */ 1816 ALOGW("Reseting stack..."); 1817 emergency_recovery(nat); 1818 } 1819 1820 result = nfc_jni_unconfigure_driver(nat); 1821 1822 TRACE("NFC Deinitialized"); 1823 1824 CONCURRENCY_UNLOCK(); 1825 1826 return TRUE; 1827 } 1828 1829 /* Secure Element methods */ 1830 static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) { 1831 NFCSTATUS ret; 1832 jintArray list= NULL; 1833 phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE]; 1834 uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE; 1835 1836 TRACE("****** Get Secure Element List ******"); 1837 1838 TRACE("phLibNfc_SE_GetSecureElementList()"); 1839 REENTRANCE_LOCK(); 1840 ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count); 1841 REENTRANCE_UNLOCK(); 1842 if (ret != NFCSTATUS_SUCCESS) { 1843 ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, 1844 nfc_jni_get_status_name(ret)); 1845 return list; 1846 } 1847 TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, 1848 nfc_jni_get_status_name(ret)); 1849 1850 TRACE("Nb SE: %d", se_count); 1851 list =e->NewIntArray(se_count); 1852 for (i = 0; i < se_count; i++) { 1853 if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { 1854 ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected"); 1855 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); 1856 } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) { 1857 ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected"); 1858 ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); 1859 } 1860 e->SetIntArrayRegion(list, i, 1, (jint*)&se_list[i].hSecureElement); 1861 } 1862 1863 e->DeleteLocalRef(list); 1864 1865 return list; 1866 } 1867 1868 static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) { 1869 NFCSTATUS ret; 1870 struct nfc_jni_native_data *nat; 1871 struct nfc_jni_callback_data cb_data; 1872 1873 CONCURRENCY_LOCK(); 1874 1875 /* Retrieve native structure address */ 1876 nat = nfc_jni_get_nat(e, o); 1877 1878 /* Create the local semaphore */ 1879 if (!nfc_cb_data_init(&cb_data, NULL)) { 1880 goto clean_and_return; 1881 } 1882 1883 TRACE("****** Select Secure Element ******"); 1884 1885 TRACE("phLibNfc_SE_SetMode()"); 1886 /* Set SE mode - Virtual */ 1887 REENTRANCE_LOCK(); 1888 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback, 1889 (void *)&cb_data); 1890 REENTRANCE_UNLOCK(); 1891 if (ret != NFCSTATUS_PENDING) { 1892 ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1893 goto clean_and_return; 1894 } 1895 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1896 1897 /* Wait for callback response */ 1898 if (sem_wait(&cb_data.sem)) { 1899 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1900 goto clean_and_return; 1901 } 1902 1903 clean_and_return: 1904 nfc_cb_data_deinit(&cb_data); 1905 CONCURRENCY_UNLOCK(); 1906 } 1907 1908 static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) { 1909 NFCSTATUS ret; 1910 struct nfc_jni_native_data *nat; 1911 struct nfc_jni_callback_data cb_data; 1912 1913 CONCURRENCY_LOCK(); 1914 1915 /* Retrieve native structure address */ 1916 nat = nfc_jni_get_nat(e, o); 1917 1918 /* Create the local semaphore */ 1919 if (!nfc_cb_data_init(&cb_data, NULL)) { 1920 goto clean_and_return; 1921 } 1922 1923 TRACE("****** Deselect Secure Element ******"); 1924 1925 TRACE("phLibNfc_SE_SetMode()"); 1926 /* Set SE mode - Default */ 1927 REENTRANCE_LOCK(); 1928 ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, 1929 nfc_jni_se_set_mode_callback, (void *)&cb_data); 1930 REENTRANCE_UNLOCK(); 1931 1932 TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret); 1933 if (ret != NFCSTATUS_PENDING) { 1934 ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1935 goto clean_and_return; 1936 } 1937 TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1938 1939 /* Wait for callback response */ 1940 if (sem_wait(&cb_data.sem)) { 1941 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1942 goto clean_and_return; 1943 } 1944 1945 clean_and_return: 1946 nfc_cb_data_deinit(&cb_data); 1947 CONCURRENCY_UNLOCK(); 1948 } 1949 1950 /* Llcp methods */ 1951 1952 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o) 1953 { 1954 NFCSTATUS ret; 1955 bool freeData = false; 1956 jboolean result = JNI_FALSE; 1957 struct nfc_jni_native_data *nat; 1958 struct nfc_jni_callback_data *cb_data; 1959 1960 1961 CONCURRENCY_LOCK(); 1962 1963 /* Memory allocation for cb_data 1964 * This is on the heap because it is used by libnfc 1965 * even after this call has succesfully finished. It is only freed 1966 * upon link closure in nfc_jni_llcp_linkStatus_callback. 1967 */ 1968 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data)); 1969 1970 /* Retrieve native structure address */ 1971 nat = nfc_jni_get_nat(e, o); 1972 1973 /* Create the local semaphore */ 1974 if (!nfc_cb_data_init(cb_data, (void*)nat)) 1975 { 1976 goto clean_and_return; 1977 } 1978 1979 /* Check LLCP compliancy */ 1980 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle); 1981 REENTRANCE_LOCK(); 1982 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle, 1983 nfc_jni_checkLlcp_callback, 1984 nfc_jni_llcp_linkStatus_callback, 1985 (void*)cb_data); 1986 REENTRANCE_UNLOCK(); 1987 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol 1988 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */ 1989 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) 1990 { 1991 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1992 freeData = true; 1993 goto clean_and_return; 1994 } 1995 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1996 1997 /* Wait for callback response */ 1998 if(sem_wait(&cb_data->sem)) 1999 { 2000 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2001 goto clean_and_return; 2002 } 2003 2004 if(cb_data->status == NFCSTATUS_SUCCESS) 2005 { 2006 result = JNI_TRUE; 2007 } 2008 2009 clean_and_return: 2010 nfc_cb_data_deinit(cb_data); 2011 if (freeData) { 2012 free(cb_data); 2013 } 2014 CONCURRENCY_UNLOCK(); 2015 return result; 2016 } 2017 2018 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o) 2019 { 2020 NFCSTATUS ret; 2021 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle); 2022 REENTRANCE_LOCK(); 2023 ret = phLibNfc_Llcp_Activate(hLlcpHandle); 2024 REENTRANCE_UNLOCK(); 2025 if(ret == NFCSTATUS_SUCCESS) 2026 { 2027 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2028 return JNI_TRUE; 2029 } 2030 else 2031 { 2032 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2033 return JNI_FALSE; 2034 } 2035 } 2036 2037 2038 2039 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o, 2040 jint nSap, jstring sn) 2041 { 2042 NFCSTATUS ret; 2043 jobject connectionlessSocket = NULL; 2044 phLibNfc_Handle hLlcpSocket; 2045 struct nfc_jni_native_data *nat; 2046 phNfc_sData_t sWorkingBuffer = {NULL, 0}; 2047 phNfc_sData_t serviceName = {NULL, 0}; 2048 phLibNfc_Llcp_sLinkParameters_t sParams; 2049 jclass clsNativeConnectionlessSocket; 2050 jfieldID f; 2051 2052 /* Retrieve native structure address */ 2053 nat = nfc_jni_get_nat(e, o); 2054 2055 /* Allocate Working buffer length */ 2056 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); 2057 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP 2058 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2059 2060 /* Create socket */ 2061 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)"); 2062 REENTRANCE_LOCK(); 2063 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess, 2064 NULL, 2065 &sWorkingBuffer, 2066 &hLlcpSocket, 2067 nfc_jni_llcp_transport_socket_err_callback, 2068 (void*)nat); 2069 REENTRANCE_UNLOCK(); 2070 2071 if(ret != NFCSTATUS_SUCCESS) 2072 { 2073 lastErrorStatus = ret; 2074 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2075 goto error; 2076 } 2077 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2078 2079 /* Service socket */ 2080 if (sn == NULL) { 2081 serviceName.buffer = NULL; 2082 serviceName.length = 0; 2083 } else { 2084 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2085 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2086 } 2087 2088 /* Bind socket */ 2089 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2090 REENTRANCE_LOCK(); 2091 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2092 REENTRANCE_UNLOCK(); 2093 if(ret != NFCSTATUS_SUCCESS) 2094 { 2095 lastErrorStatus = ret; 2096 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2097 /* Close socket created */ 2098 REENTRANCE_LOCK(); 2099 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2100 REENTRANCE_UNLOCK(); 2101 goto error; 2102 } 2103 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2104 2105 2106 /* Create new NativeLlcpConnectionlessSocket object */ 2107 if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) 2108 { 2109 goto error; 2110 } 2111 2112 /* Get NativeConnectionless class object */ 2113 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); 2114 if(e->ExceptionCheck()) 2115 { 2116 goto error; 2117 } 2118 2119 /* Set socket handle */ 2120 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); 2121 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); 2122 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); 2123 2124 /* Set the miu link of the connectionless socket */ 2125 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); 2126 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); 2127 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); 2128 2129 /* Set socket SAP */ 2130 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); 2131 e->SetIntField(connectionlessSocket, f,(jint)nSap); 2132 TRACE("Connectionless socket SAP = %d\n",nSap); 2133 2134 return connectionlessSocket; 2135 error: 2136 if (serviceName.buffer != NULL) { 2137 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2138 } 2139 2140 if (sWorkingBuffer.buffer != NULL) { 2141 free(sWorkingBuffer.buffer); 2142 } 2143 2144 return NULL; 2145 } 2146 2147 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) 2148 { 2149 NFCSTATUS ret; 2150 phLibNfc_Handle hLlcpSocket; 2151 phLibNfc_Llcp_sSocketOptions_t sOptions; 2152 phNfc_sData_t sWorkingBuffer; 2153 phNfc_sData_t serviceName; 2154 struct nfc_jni_native_data *nat; 2155 jobject serviceSocket = NULL; 2156 jclass clsNativeLlcpServiceSocket; 2157 jfieldID f; 2158 2159 /* Retrieve native structure address */ 2160 nat = nfc_jni_get_nat(e, o); 2161 2162 /* Set Connection Oriented socket options */ 2163 sOptions.miu = miu; 2164 sOptions.rw = rw; 2165 2166 /* Allocate Working buffer length */ 2167 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2168 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2169 2170 2171 /* Create socket */ 2172 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); 2173 REENTRANCE_LOCK(); 2174 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2175 &sOptions, 2176 &sWorkingBuffer, 2177 &hLlcpSocket, 2178 nfc_jni_llcp_transport_socket_err_callback, 2179 (void*)nat); 2180 REENTRANCE_UNLOCK(); 2181 2182 if(ret != NFCSTATUS_SUCCESS) 2183 { 2184 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2185 lastErrorStatus = ret; 2186 goto error; 2187 } 2188 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2189 2190 /* Service socket */ 2191 if (sn == NULL) { 2192 serviceName.buffer = NULL; 2193 serviceName.length = 0; 2194 } else { 2195 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2196 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2197 } 2198 2199 /* Bind socket */ 2200 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2201 REENTRANCE_LOCK(); 2202 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2203 REENTRANCE_UNLOCK(); 2204 if(ret != NFCSTATUS_SUCCESS) 2205 { 2206 lastErrorStatus = ret; 2207 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2208 /* Close socket created */ 2209 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2210 goto error; 2211 } 2212 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2213 2214 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket); 2215 REENTRANCE_LOCK(); 2216 ret = phLibNfc_Llcp_Listen( hLlcpSocket, 2217 nfc_jni_llcp_transport_listen_socket_callback, 2218 (void*)hLlcpSocket); 2219 REENTRANCE_UNLOCK(); 2220 2221 if(ret != NFCSTATUS_SUCCESS) 2222 { 2223 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2224 lastErrorStatus = ret; 2225 /* Close created socket */ 2226 REENTRANCE_LOCK(); 2227 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2228 REENTRANCE_UNLOCK(); 2229 goto error; 2230 } 2231 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2232 2233 /* Create new NativeLlcpServiceSocket object */ 2234 if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpServiceSocket",&(serviceSocket)) == -1) 2235 { 2236 ALOGE("Llcp Socket object creation error"); 2237 goto error; 2238 } 2239 2240 /* Get NativeLlcpServiceSocket class object */ 2241 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); 2242 if(e->ExceptionCheck()) 2243 { 2244 ALOGE("Llcp Socket get object class error"); 2245 goto error; 2246 } 2247 2248 /* Set socket handle */ 2249 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); 2250 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); 2251 TRACE("Service socket Handle = %02x\n",hLlcpSocket); 2252 2253 /* Set socket linear buffer length */ 2254 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); 2255 e->SetIntField(serviceSocket, f,(jint)linearBufferLength); 2256 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); 2257 2258 /* Set socket MIU */ 2259 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); 2260 e->SetIntField(serviceSocket, f,(jint)miu); 2261 TRACE("Service socket MIU = %d\n",miu); 2262 2263 /* Set socket RW */ 2264 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); 2265 e->SetIntField(serviceSocket, f,(jint)rw); 2266 TRACE("Service socket RW = %d\n",rw); 2267 2268 return serviceSocket; 2269 error: 2270 if (serviceName.buffer != NULL) { 2271 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2272 } 2273 return NULL; 2274 } 2275 2276 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) 2277 { 2278 jobject clientSocket = NULL; 2279 NFCSTATUS ret; 2280 phLibNfc_Handle hLlcpSocket; 2281 phLibNfc_Llcp_sSocketOptions_t sOptions; 2282 phNfc_sData_t sWorkingBuffer; 2283 struct nfc_jni_native_data *nat; 2284 jclass clsNativeLlcpSocket; 2285 jfieldID f; 2286 2287 /* Retrieve native structure address */ 2288 nat = nfc_jni_get_nat(e, o); 2289 2290 /* Set Connection Oriented socket options */ 2291 sOptions.miu = miu; 2292 sOptions.rw = rw; 2293 2294 /* Allocate Working buffer length */ 2295 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2296 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2297 2298 /* Create socket */ 2299 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)"); 2300 REENTRANCE_LOCK(); 2301 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2302 &sOptions, 2303 &sWorkingBuffer, 2304 &hLlcpSocket, 2305 nfc_jni_llcp_transport_socket_err_callback, 2306 (void*)nat); 2307 REENTRANCE_UNLOCK(); 2308 2309 if(ret != NFCSTATUS_SUCCESS) 2310 { 2311 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2312 lastErrorStatus = ret; 2313 return NULL; 2314 } 2315 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2316 2317 /* Create new NativeLlcpSocket object */ 2318 if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpSocket",&(clientSocket)) == -1) 2319 { 2320 ALOGE("Llcp socket object creation error"); 2321 return NULL; 2322 } 2323 2324 /* Get NativeConnectionless class object */ 2325 clsNativeLlcpSocket = e->GetObjectClass(clientSocket); 2326 if(e->ExceptionCheck()) 2327 { 2328 ALOGE("Get class object error"); 2329 return NULL; 2330 } 2331 2332 /* Test if an SAP number is present */ 2333 if(nSap != 0) 2334 { 2335 /* Bind socket */ 2336 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2337 REENTRANCE_LOCK(); 2338 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL); 2339 REENTRANCE_UNLOCK(); 2340 if(ret != NFCSTATUS_SUCCESS) 2341 { 2342 lastErrorStatus = ret; 2343 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2344 /* Close socket created */ 2345 REENTRANCE_LOCK(); 2346 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2347 REENTRANCE_UNLOCK(); 2348 return NULL; 2349 } 2350 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2351 2352 /* Set socket SAP */ 2353 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); 2354 e->SetIntField(clientSocket, f,(jint)nSap); 2355 TRACE("socket SAP = %d\n",nSap); 2356 } 2357 2358 /* Set socket handle */ 2359 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); 2360 e->SetIntField(clientSocket, f,(jint)hLlcpSocket); 2361 TRACE("socket Handle = %02x\n",hLlcpSocket); 2362 2363 /* Set socket MIU */ 2364 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); 2365 e->SetIntField(clientSocket, f,(jint)miu); 2366 TRACE("socket MIU = %d\n",miu); 2367 2368 /* Set socket RW */ 2369 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); 2370 e->SetIntField(clientSocket, f,(jint)rw); 2371 TRACE("socket RW = %d\n",rw); 2372 2373 2374 return clientSocket; 2375 } 2376 2377 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o) 2378 { 2379 TRACE("Last Error Status = 0x%02x",lastErrorStatus); 2380 2381 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) 2382 { 2383 return ERROR_BUFFER_TOO_SMALL; 2384 } 2385 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES) 2386 { 2387 return ERROR_INSUFFICIENT_RESOURCES; 2388 } 2389 else 2390 { 2391 return lastErrorStatus; 2392 } 2393 } 2394 2395 static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o) 2396 { 2397 emergency_recovery(NULL); 2398 } 2399 2400 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o, 2401 jint modes) 2402 { 2403 ALOGE("Setting init modes to %x", modes); 2404 struct nfc_jni_native_data *nat = NULL; 2405 nat = nfc_jni_get_nat(e, o); 2406 nat->p2p_initiator_modes = modes; 2407 } 2408 2409 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o, 2410 jint modes) 2411 { 2412 ALOGE("Setting target modes to %x", modes); 2413 struct nfc_jni_native_data *nat = NULL; 2414 nat = nfc_jni_get_nat(e, o); 2415 nat->p2p_target_modes = modes; 2416 } 2417 2418 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) { 2419 bool result = FALSE; 2420 int load_result; 2421 bool wasDisabled = FALSE; 2422 uint8_t OutputBuffer[1]; 2423 uint8_t InputBuffer[1]; 2424 NFCSTATUS status = NFCSTATUS_FAILED; 2425 struct nfc_jni_callback_data cb_data; 2426 2427 /* Create the local semaphore */ 2428 if (!nfc_cb_data_init(&cb_data, NULL)) 2429 { 2430 result = FALSE; 2431 goto clean_and_return; 2432 } 2433 2434 if (takeLock) 2435 { 2436 CONCURRENCY_LOCK(); 2437 } 2438 2439 /* Initialize Driver */ 2440 if(!driverConfigured) 2441 { 2442 result = nfc_jni_configure_driver(nat); 2443 wasDisabled = TRUE; 2444 } 2445 TRACE("com_android_nfc_NfcManager_doDownload()"); 2446 2447 TRACE("Go in Download Mode"); 2448 phLibNfc_Download_Mode(); 2449 2450 TRACE("Load new Firmware Image"); 2451 load_result = phLibNfc_Load_Firmware_Image(); 2452 if(load_result != 0) 2453 { 2454 TRACE("Load new Firmware Image - status = %d",load_result); 2455 result = FALSE; 2456 goto clean_and_return; 2457 } 2458 2459 // Download 2460 gInputParam.buffer = InputBuffer; 2461 gInputParam.length = 0x01; 2462 gOutputParam.buffer = OutputBuffer; 2463 gOutputParam.length = 0x01; 2464 2465 ALOGD("Download new Firmware"); 2466 REENTRANCE_LOCK(); 2467 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); 2468 REENTRANCE_UNLOCK(); 2469 if(status != NFCSTATUS_PENDING) 2470 { 2471 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2472 result = FALSE; 2473 goto clean_and_return; 2474 } 2475 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2476 2477 /* Wait for callback response */ 2478 if(sem_wait(&cb_data.sem)) 2479 { 2480 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2481 result = FALSE; 2482 goto clean_and_return; 2483 } 2484 2485 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we 2486 try to download an old-style firmware on top of a new-style 2487 firmware. Hence, this is expected behavior, and not an 2488 error condition. */ 2489 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED) 2490 { 2491 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2492 result = FALSE; 2493 goto clean_and_return; 2494 } 2495 2496 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED) 2497 { 2498 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip."); 2499 } 2500 2501 /*Download is successful*/ 2502 result = TRUE; 2503 clean_and_return: 2504 TRACE("phLibNfc_HW_Reset()"); 2505 phLibNfc_HW_Reset(); 2506 /* Deinitialize Driver */ 2507 if(wasDisabled) 2508 { 2509 result = nfc_jni_unconfigure_driver(nat); 2510 } 2511 if (takeLock) 2512 { 2513 CONCURRENCY_UNLOCK(); 2514 } 2515 nfc_cb_data_deinit(&cb_data); 2516 return result; 2517 } 2518 2519 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o) 2520 { 2521 struct nfc_jni_native_data *nat = NULL; 2522 nat = nfc_jni_get_nat(e, o); 2523 return performDownload(nat, true); 2524 } 2525 2526 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o) 2527 { 2528 char buffer[100]; 2529 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count); 2530 return e->NewStringUTF(buffer); 2531 } 2532 2533 /* 2534 * JNI registration. 2535 */ 2536 static JNINativeMethod gMethods[] = 2537 { 2538 {"doDownload", "()Z", 2539 (void *)com_android_nfc_NfcManager_doDownload}, 2540 2541 {"initializeNativeStructure", "()Z", 2542 (void *)com_android_nfc_NfcManager_init_native_struc}, 2543 2544 {"doInitialize", "()Z", 2545 (void *)com_android_nfc_NfcManager_initialize}, 2546 2547 {"doDeinitialize", "()Z", 2548 (void *)com_android_nfc_NfcManager_deinitialize}, 2549 2550 {"enableDiscovery", "()V", 2551 (void *)com_android_nfc_NfcManager_enableDiscovery}, 2552 2553 {"doGetSecureElementList", "()[I", 2554 (void *)com_android_nfc_NfcManager_doGetSecureElementList}, 2555 2556 {"doSelectSecureElement", "()V", 2557 (void *)com_android_nfc_NfcManager_doSelectSecureElement}, 2558 2559 {"doDeselectSecureElement", "()V", 2560 (void *)com_android_nfc_NfcManager_doDeselectSecureElement}, 2561 2562 {"doCheckLlcp", "()Z", 2563 (void *)com_android_nfc_NfcManager_doCheckLlcp}, 2564 2565 {"doActivateLlcp", "()Z", 2566 (void *)com_android_nfc_NfcManager_doActivateLlcp}, 2567 2568 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/nxp/NativeLlcpConnectionlessSocket;", 2569 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket}, 2570 2571 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/nxp/NativeLlcpServiceSocket;", 2572 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket}, 2573 2574 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/nxp/NativeLlcpSocket;", 2575 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, 2576 2577 {"doGetLastError", "()I", 2578 (void *)com_android_nfc_NfcManager_doGetLastError}, 2579 2580 {"disableDiscovery", "()V", 2581 (void *)com_android_nfc_NfcManager_disableDiscovery}, 2582 2583 {"doSetTimeout", "(II)Z", 2584 (void *)com_android_nfc_NfcManager_doSetTimeout}, 2585 2586 {"doGetTimeout", "(I)I", 2587 (void *)com_android_nfc_NfcManager_doGetTimeout}, 2588 2589 {"doResetTimeouts", "()V", 2590 (void *)com_android_nfc_NfcManager_doResetTimeouts}, 2591 2592 {"doAbort", "()V", 2593 (void *)com_android_nfc_NfcManager_doAbort}, 2594 2595 {"doSetP2pInitiatorModes","(I)V", 2596 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes}, 2597 2598 {"doSetP2pTargetModes","(I)V", 2599 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes}, 2600 2601 {"doDump", "()Ljava/lang/String;", 2602 (void *)com_android_nfc_NfcManager_doDump}, 2603 }; 2604 2605 2606 int register_com_android_nfc_NativeNfcManager(JNIEnv *e) 2607 { 2608 nfc_jni_native_monitor_t *nfc_jni_native_monitor; 2609 2610 nfc_jni_native_monitor = nfc_jni_init_monitor(); 2611 if(nfc_jni_native_monitor == NULL) 2612 { 2613 ALOGE("NFC Manager cannot recover native monitor %x\n", errno); 2614 return -1; 2615 } 2616 2617 return jniRegisterNativeMethods(e, 2618 "com/android/nfc/nxp/NativeNfcManager", 2619 gMethods, NELEM(gMethods)); 2620 } 2621 2622 } /* namespace android */ 2623