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