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_notifyLlcpLinkActivation; 50 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated; 51 static jmethodID cached_NfcManager_notifyTargetDeselected; 52 53 static jmethodID cached_NfcManager_notifyRfFieldActivated; 54 static jmethodID cached_NfcManager_notifyRfFieldDeactivated; 55 namespace android { 56 57 phLibNfc_Handle storedHandle = 0; 58 59 struct nfc_jni_native_data *exported_nat = NULL; 60 61 /* Internal functions declaration */ 62 static void *nfc_jni_client_thread(void *arg); 63 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status); 64 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status); 65 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status); 66 static void nfc_jni_se_set_mode_callback(void *context, 67 phLibNfc_Handle handle, NFCSTATUS status); 68 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status); 69 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume); 70 static void nfc_jni_Discovery_notification_callback(void *pContext, 71 phLibNfc_RemoteDevList_t *psRemoteDevList, 72 uint8_t uNofRemoteDev, NFCSTATUS status); 73 static void nfc_jni_transaction_callback(void *context, 74 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle, 75 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status); 76 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock); 77 78 extern void set_target_activationBytes(JNIEnv *e, jobject tag, 79 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo); 80 extern void set_target_pollBytes(JNIEnv *e, jobject tag, 81 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo); 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 NFCSTATUS ret; 910 const char * typeName; 911 struct timespec ts; 912 phNfc_sData_t data; 913 int i; 914 int target_index = 0; // Target that will be reported (if multiple can be >0) 915 916 struct nfc_jni_native_data* nat = (struct nfc_jni_native_data *)pContext; 917 918 JNIEnv *e; 919 nat->vm->GetEnv( (void **)&e, nat->env_version); 920 921 if(status == NFCSTATUS_DESELECTED) 922 { 923 LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status); 924 925 /* Notify manager that a target was deselected */ 926 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected); 927 if(e->ExceptionCheck()) 928 { 929 ALOGE("Exception occurred"); 930 kill_client(nat); 931 } 932 } 933 else 934 { 935 LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status); 936 TRACE("Discovered %d tags", uNofRemoteDev); 937 938 target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev); 939 940 ScopedLocalRef<jobject> tag(e, NULL); 941 942 /* Reset device connected flag */ 943 device_connected_flag = 1; 944 phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo; 945 phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev; 946 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 947 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) 948 { 949 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice)); 950 if(e->ExceptionCheck()) 951 { 952 ALOGE("Get Object Class Error"); 953 kill_client(nat); 954 return; 955 } 956 957 /* New target instance */ 958 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); 959 tag.reset(e->NewObject(tag_cls.get(), ctor)); 960 961 /* Set P2P Target mode */ 962 jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I"); 963 964 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 965 { 966 ALOGD("Discovered P2P Initiator"); 967 e->SetIntField(tag.get(), f, (jint)MODE_P2P_INITIATOR); 968 } 969 else 970 { 971 ALOGD("Discovered P2P Target"); 972 e->SetIntField(tag.get(), f, (jint)MODE_P2P_TARGET); 973 } 974 975 if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 976 { 977 /* Set General Bytes */ 978 f = e->GetFieldID(tag_cls.get(), "mGeneralBytes", "[B"); 979 980 TRACE("General Bytes length ="); 981 for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++) 982 { 983 ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]); 984 } 985 986 ScopedLocalRef<jbyteArray> generalBytes(e, e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length)); 987 988 e->SetByteArrayRegion(generalBytes.get(), 0, 989 remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length, 990 (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo); 991 e->SetObjectField(tag.get(), f, generalBytes.get()); 992 } 993 994 /* Set tag handle */ 995 f = e->GetFieldID(tag_cls.get(), "mHandle", "I"); 996 e->SetIntField(tag.get(), f,(jint)remDevHandle); 997 TRACE("Target handle = 0x%08x",remDevHandle); 998 } 999 else 1000 { 1001 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_NfcTag)); 1002 if(e->ExceptionCheck()) 1003 { 1004 kill_client(nat); 1005 return; 1006 } 1007 1008 /* New tag instance */ 1009 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); 1010 tag.reset(e->NewObject(tag_cls.get(), ctor)); 1011 1012 bool multi_protocol = false; 1013 1014 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 1015 { 1016 TRACE("Multiple Protocol TAG detected\n"); 1017 multi_protocol = true; 1018 } 1019 1020 /* Set tag UID */ 1021 jfieldID f = e->GetFieldID(tag_cls.get(), "mUid", "[B"); 1022 data = get_target_uid(remDevInfo); 1023 ScopedLocalRef<jbyteArray> tagUid(e, e->NewByteArray(data.length)); 1024 if(data.length > 0) 1025 { 1026 e->SetByteArrayRegion(tagUid.get(), 0, data.length, (jbyte *)data.buffer); 1027 } 1028 e->SetObjectField(tag.get(), f, tagUid.get()); 1029 1030 /* Generate technology list */ 1031 ScopedLocalRef<jintArray> techList(e, NULL); 1032 ScopedLocalRef<jintArray> handleList(e, NULL); 1033 ScopedLocalRef<jintArray> typeList(e, NULL); 1034 nfc_jni_get_technology_tree(e, psRemoteDevList, 1035 multi_protocol ? uNofRemoteDev : 1, 1036 &techList, &handleList, &typeList); 1037 1038 /* Push the technology list into the java object */ 1039 f = e->GetFieldID(tag_cls.get(), "mTechList", "[I"); 1040 e->SetObjectField(tag.get(), f, techList.get()); 1041 1042 f = e->GetFieldID(tag_cls.get(), "mTechHandles", "[I"); 1043 e->SetObjectField(tag.get(), f, handleList.get()); 1044 1045 f = e->GetFieldID(tag_cls.get(), "mTechLibNfcTypes", "[I"); 1046 e->SetObjectField(tag.get(), f, typeList.get()); 1047 1048 f = e->GetFieldID(tag_cls.get(), "mConnectedTechIndex", "I"); 1049 e->SetIntField(tag.get(), f,(jint)-1); 1050 1051 f = e->GetFieldID(tag_cls.get(), "mConnectedHandle", "I"); 1052 e->SetIntField(tag.get(), f,(jint)-1); 1053 1054 set_target_pollBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo); 1055 1056 set_target_activationBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo); 1057 } 1058 1059 storedHandle = remDevHandle; 1060 if (nat->tag != NULL) { 1061 e->DeleteGlobalRef(nat->tag); 1062 } 1063 nat->tag = e->NewGlobalRef(tag.get()); 1064 1065 /* Notify the service */ 1066 TRACE("Notify Nfc Service"); 1067 if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) 1068 || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) 1069 { 1070 /* Store the handle of the P2P device */ 1071 hLlcpHandle = remDevHandle; 1072 1073 /* Notify manager that new a P2P device was found */ 1074 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag.get()); 1075 if(e->ExceptionCheck()) 1076 { 1077 ALOGE("Exception occurred"); 1078 kill_client(nat); 1079 } 1080 } 1081 else 1082 { 1083 /* Notify manager that new a tag was found */ 1084 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag.get()); 1085 if(e->ExceptionCheck()) 1086 { 1087 ALOGE("Exception occurred"); 1088 kill_client(nat); 1089 } 1090 } 1091 } 1092 } 1093 1094 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status) 1095 { 1096 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1097 1098 LOG_CALLBACK("nfc_jni_init_callback", status); 1099 1100 pContextData->status = status; 1101 sem_post(&pContextData->sem); 1102 } 1103 1104 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status) 1105 { 1106 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1107 1108 LOG_CALLBACK("nfc_jni_deinit_callback", status); 1109 1110 pContextData->status = status; 1111 sem_post(&pContextData->sem); 1112 } 1113 1114 /* Set Secure Element mode callback*/ 1115 static void nfc_jni_smartMX_setModeCb (void* pContext, 1116 phLibNfc_Handle /*hSecureElement*/, 1117 NFCSTATUS status) 1118 { 1119 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1120 1121 LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status); 1122 1123 pContextData->status = status; 1124 sem_post(&pContextData->sem); 1125 } 1126 1127 /* Card Emulation callback */ 1128 static void nfc_jni_transaction_callback(void *context, 1129 phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle /*handle*/, 1130 phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status) 1131 { 1132 JNIEnv *e; 1133 jobject tmp_array = NULL; 1134 jobject mifare_block = NULL; 1135 struct nfc_jni_native_data *nat; 1136 phNfc_sData_t *aid; 1137 phNfc_sData_t *mifare_command; 1138 struct nfc_jni_callback_data *pCallbackData; 1139 int i=0; 1140 1141 LOG_CALLBACK("nfc_jni_transaction_callback", status); 1142 1143 nat = (struct nfc_jni_native_data *)context; 1144 1145 nat->vm->GetEnv( (void **)&e, nat->env_version); 1146 1147 if(status == NFCSTATUS_SUCCESS) 1148 { 1149 switch(evt_type) 1150 { 1151 case phLibNfc_eSE_EvtStartTransaction: 1152 { 1153 TRACE("> SE EVT_START_TRANSACTION"); 1154 }break; 1155 1156 case phLibNfc_eSE_EvtApduReceived: 1157 { 1158 TRACE("> SE EVT_APDU_RECEIVED"); 1159 }break; 1160 1161 case phLibNfc_eSE_EvtCardRemoval: 1162 { 1163 TRACE("> SE EVT_EMV_CARD_REMOVAL"); 1164 }break; 1165 1166 case phLibNfc_eSE_EvtMifareAccess: 1167 { 1168 TRACE("> SE EVT_MIFARE_ACCESS"); 1169 }break; 1170 1171 case phLibNfc_eSE_EvtFieldOn: 1172 { 1173 TRACE("> SE EVT_FIELD_ON"); 1174 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldActivated); 1175 }break; 1176 1177 case phLibNfc_eSE_EvtFieldOff: 1178 { 1179 TRACE("> SE EVT_FIELD_OFF"); 1180 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldDeactivated); 1181 }break; 1182 1183 default: 1184 { 1185 TRACE("Unknown SE event"); 1186 }break; 1187 } 1188 } 1189 else 1190 { 1191 ALOGE("SE transaction notification error"); 1192 goto error; 1193 } 1194 1195 /* Function finished, now clean and return */ 1196 goto clean_and_return; 1197 1198 error: 1199 /* In case of error, just discard the notification */ 1200 ALOGE("Failed to send SE transaction notification"); 1201 e->ExceptionClear(); 1202 1203 clean_and_return: 1204 if(tmp_array != NULL) 1205 { 1206 e->DeleteLocalRef(tmp_array); 1207 } 1208 } 1209 1210 static void nfc_jni_se_set_mode_callback(void *pContext, 1211 phLibNfc_Handle /*handle*/, NFCSTATUS status) 1212 { 1213 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1214 1215 LOG_CALLBACK("nfc_jni_se_set_mode_callback", status); 1216 1217 pContextData->status = status; 1218 sem_post(&pContextData->sem); 1219 } 1220 1221 /* 1222 * NFCManager methods 1223 */ 1224 1225 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume) 1226 { 1227 NFCSTATUS ret; 1228 struct nfc_jni_callback_data cb_data; 1229 int numRetries = 3; 1230 1231 /* Create the local semaphore */ 1232 if (!nfc_cb_data_init(&cb_data, NULL)) 1233 { 1234 goto clean_and_return; 1235 } 1236 /* Reset the PN544 ISO XCHG / sw watchdog timeouts */ 1237 nfc_jni_reset_timeout_values(); 1238 1239 /* Reload the p2p modes */ 1240 nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator 1241 nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target 1242 nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; 1243 1244 /* Reset device connected flag */ 1245 device_connected_flag = 0; 1246 configure: 1247 /* Start Polling loop */ 1248 TRACE("****** Start NFC Discovery ******"); 1249 REENTRANCE_LOCK(); 1250 ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG, 1251 nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1252 REENTRANCE_UNLOCK(); 1253 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1254 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1255 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1256 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1257 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1258 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1259 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1260 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1261 nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret); 1262 1263 if (ret == NFCSTATUS_BUSY && numRetries-- > 0) 1264 { 1265 TRACE("ConfigDiscovery BUSY, retrying"); 1266 usleep(1000000); 1267 goto configure; 1268 } 1269 1270 if(ret != NFCSTATUS_PENDING) 1271 { 1272 emergency_recovery(nat); 1273 goto clean_and_return; 1274 } 1275 1276 /* Wait for callback response */ 1277 if(sem_wait(&cb_data.sem)) 1278 { 1279 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1280 goto clean_and_return; 1281 } 1282 1283 clean_and_return: 1284 nfc_cb_data_deinit(&cb_data); 1285 } 1286 1287 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) 1288 { 1289 phLibNfc_sADD_Cfg_t discovery_cfg; 1290 NFCSTATUS ret; 1291 struct nfc_jni_callback_data cb_data; 1292 int numRetries = 3; 1293 1294 /* Create the local semaphore */ 1295 if (!nfc_cb_data_init(&cb_data, NULL)) 1296 { 1297 goto clean_and_return; 1298 } 1299 1300 discovery_cfg.PollDevInfo.PollEnabled = 0; 1301 discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode; 1302 discovery_cfg.NfcIP_Target_Mode = 0; 1303 discovery_cfg.NfcIP_Tgt_Disable = TRUE; 1304 1305 configure: 1306 /* Start Polling loop */ 1307 TRACE("****** Stop NFC Discovery ******"); 1308 REENTRANCE_LOCK(); 1309 ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); 1310 REENTRANCE_UNLOCK(); 1311 TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", 1312 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", 1313 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", 1314 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", 1315 discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", 1316 discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", 1317 discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", 1318 discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", 1319 discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret); 1320 1321 if (ret == NFCSTATUS_BUSY && numRetries-- > 0) 1322 { 1323 TRACE("ConfigDiscovery BUSY, retrying"); 1324 usleep(1000000); 1325 goto configure; 1326 } 1327 1328 if(ret != NFCSTATUS_PENDING) 1329 { 1330 ALOGE("[STOP] ConfigDiscovery returned %x", ret); 1331 emergency_recovery(nat); 1332 } 1333 1334 /* Wait for callback response */ 1335 if(sem_wait(&cb_data.sem)) 1336 { 1337 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1338 goto clean_and_return; 1339 } 1340 1341 clean_and_return: 1342 nfc_cb_data_deinit(&cb_data); 1343 } 1344 1345 1346 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) 1347 { 1348 struct nfc_jni_native_data *nat; 1349 1350 CONCURRENCY_LOCK(); 1351 1352 /* Retrieve native structure address */ 1353 nat = nfc_jni_get_nat(e, o); 1354 1355 nfc_jni_stop_discovery_locked(nat); 1356 1357 CONCURRENCY_UNLOCK(); 1358 1359 } 1360 1361 // TODO: use enable_lptd 1362 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes, 1363 jboolean, jboolean reader_mode, jboolean restart) 1364 { 1365 NFCSTATUS ret; 1366 struct nfc_jni_native_data *nat; 1367 1368 CONCURRENCY_LOCK(); 1369 1370 nat = nfc_jni_get_nat(e, o); 1371 1372 /* Register callback for remote device notifications. 1373 * Must re-register every time we turn on discovery, since other operations 1374 * (such as opening the Secure Element) can change the remote device 1375 * notification callback*/ 1376 REENTRANCE_LOCK(); 1377 ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat); 1378 REENTRANCE_UNLOCK(); 1379 if(ret != NFCSTATUS_SUCCESS) 1380 { 1381 ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret); 1382 goto clean_and_return; 1383 } 1384 TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n", 1385 nat->registry_info.Jewel==TRUE?"J":"", 1386 nat->registry_info.MifareUL==TRUE?"UL":"", 1387 nat->registry_info.MifareStd==TRUE?"Mi":"", 1388 nat->registry_info.Felica==TRUE?"F":"", 1389 nat->registry_info.ISO14443_4A==TRUE?"4A":"", 1390 nat->registry_info.ISO14443_4B==TRUE?"4B":"", 1391 nat->registry_info.NFC==TRUE?"P2P":"", 1392 nat->registry_info.ISO15693==TRUE?"R":"", ret); 1393 1394 if (modes != 0) 1395 { 1396 if (reader_mode) 1397 { 1398 nat->p2p_initiator_modes = 0; 1399 nat->p2p_target_modes = 0; 1400 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE; 1401 nat->discovery_cfg.Duration = 200000; /* in ms */ 1402 } 1403 else 1404 { 1405 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1406 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1407 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1408 nat->discovery_cfg.Duration = 300000; /* in ms */ 1409 } 1410 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0; 1411 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0; 1412 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0; 1413 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0; 1414 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0; 1415 } 1416 1417 nfc_jni_start_discovery_locked(nat, restart); 1418 clean_and_return: 1419 CONCURRENCY_UNLOCK(); 1420 } 1421 1422 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) { 1423 CONCURRENCY_LOCK(); 1424 nfc_jni_reset_timeout_values(); 1425 CONCURRENCY_UNLOCK(); 1426 } 1427 1428 static void setFelicaTimeout(jint timeout) { 1429 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms. 1430 // It can be set to 0 to disable the timeout altogether, in which case we 1431 // use the sw watchdog as a fallback. 1432 if (timeout <= 255) { 1433 phLibNfc_SetFelicaTimeout(timeout); 1434 } else { 1435 // Disable hw timeout, use sw watchdog for timeout 1436 phLibNfc_SetFelicaTimeout(0); 1437 phLibNfc_SetHciTimeout(timeout); 1438 } 1439 1440 } 1441 // Calculates ceiling log2 of value 1442 static unsigned int log2(int value) { 1443 unsigned int ret = 0; 1444 bool isPowerOf2 = ((value & (value - 1)) == 0); 1445 while ( (value >> ret) > 1 ) ret++; 1446 if (!isPowerOf2) ret++; 1447 return ret; 1448 } 1449 1450 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X 1451 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X 1452 // 1453 // We keep the constant part of the formula in a static; note the factor 1454 // 1000 off, which is due to the fact that the formula calculates seconds, 1455 // but this method gets milliseconds as an argument. 1456 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0; 1457 1458 static int calcTimeout(int timeout_in_ms) { 1459 // timeout = (256 * 16 / 13560000) * 2 ^ X 1460 // First find the first X for which timeout > requested timeout 1461 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor))); 1462 } 1463 1464 static void setIsoDepTimeout(jint timeout) { 1465 if (timeout <= 4900) { 1466 int value = calcTimeout(timeout); 1467 // Then re-compute the actual timeout based on X 1468 double actual_timeout = nxp_nfc_timeout_factor * (1 << value); 1469 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate, 1470 // but it will take some time to get back through the sw layers. 1471 // 500 ms should be enough). 1472 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500)); 1473 value |= 0x10; // bit 4 to enable timeout 1474 phLibNfc_SetIsoXchgTimeout(value); 1475 } 1476 else { 1477 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout 1478 // must be disabled completely, to prevent the PN544 from aborting 1479 // the transaction. We reuse the HCI sw watchdog to catch the timeout 1480 // in that case. 1481 phLibNfc_SetIsoXchgTimeout(0x00); 1482 phLibNfc_SetHciTimeout(timeout); 1483 } 1484 } 1485 1486 static void setNfcATimeout(jint timeout) { 1487 if (timeout <= 4900) { 1488 int value = calcTimeout(timeout); 1489 phLibNfc_SetMifareRawTimeout(value); 1490 } 1491 else { 1492 // Disable mifare raw timeout, use HCI sw watchdog instead 1493 phLibNfc_SetMifareRawTimeout(0x00); 1494 phLibNfc_SetHciTimeout(timeout); 1495 } 1496 } 1497 1498 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject, 1499 jint tech, jint timeout) { 1500 bool success = false; 1501 CONCURRENCY_LOCK(); 1502 if (timeout <= 0) { 1503 ALOGE("Timeout must be positive."); 1504 success = false; 1505 } else { 1506 switch (tech) { 1507 case TARGET_TYPE_MIFARE_CLASSIC: 1508 case TARGET_TYPE_MIFARE_UL: 1509 // Intentional fall-through, Mifare UL, Classic 1510 // transceive just uses raw 3A frames 1511 case TARGET_TYPE_ISO14443_3A: 1512 setNfcATimeout(timeout); 1513 success = true; 1514 break; 1515 case TARGET_TYPE_ISO14443_4: 1516 setIsoDepTimeout(timeout); 1517 success = true; 1518 break; 1519 case TARGET_TYPE_FELICA: 1520 setFelicaTimeout(timeout); 1521 success = true; 1522 break; 1523 default: 1524 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech); 1525 success = false; 1526 } 1527 } 1528 CONCURRENCY_UNLOCK(); 1529 return success; 1530 } 1531 1532 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject, 1533 jint tech) { 1534 int timeout = -1; 1535 CONCURRENCY_LOCK(); 1536 switch (tech) { 1537 case TARGET_TYPE_MIFARE_CLASSIC: 1538 case TARGET_TYPE_MIFARE_UL: 1539 // Intentional fall-through, Mifare UL, Classic 1540 // transceive just uses raw 3A frames 1541 case TARGET_TYPE_ISO14443_3A: 1542 timeout = phLibNfc_GetMifareRawTimeout(); 1543 if (timeout == 0) { 1544 timeout = phLibNfc_GetHciTimeout(); 1545 } else { 1546 // Timeout returned from libnfc needs conversion to ms 1547 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1548 } 1549 break; 1550 case TARGET_TYPE_ISO14443_4: 1551 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only 1552 if (timeout == 0) { 1553 timeout = phLibNfc_GetHciTimeout(); 1554 } else { 1555 // Timeout returned from libnfc needs conversion to ms 1556 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1557 } 1558 break; 1559 case TARGET_TYPE_FELICA: 1560 timeout = phLibNfc_GetFelicaTimeout(); 1561 if (timeout == 0) { 1562 timeout = phLibNfc_GetHciTimeout(); 1563 } else { 1564 // Felica timeout already in ms 1565 } 1566 break; 1567 default: 1568 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech); 1569 break; 1570 } 1571 CONCURRENCY_UNLOCK(); 1572 return timeout; 1573 } 1574 1575 1576 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o) 1577 { 1578 NFCSTATUS status; 1579 struct nfc_jni_native_data *nat = NULL; 1580 jclass cls; 1581 jobject obj; 1582 jfieldID f; 1583 1584 TRACE("****** Init Native Structure ******"); 1585 1586 /* Initialize native structure */ 1587 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); 1588 if(nat == NULL) 1589 { 1590 ALOGD("malloc of nfc_jni_native_data failed"); 1591 return FALSE; 1592 } 1593 memset(nat, 0, sizeof(*nat)); 1594 e->GetJavaVM(&(nat->vm)); 1595 nat->env_version = e->GetVersion(); 1596 nat->manager = e->NewGlobalRef(o); 1597 1598 cls = e->GetObjectClass(o); 1599 f = e->GetFieldID(cls, "mNative", "J"); 1600 e->SetLongField(o, f, (jlong)nat); 1601 1602 /* Initialize native cached references */ 1603 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, 1604 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); 1605 1606 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, 1607 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1608 1609 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls, 1610 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1611 1612 cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls, 1613 "notifyRfFieldActivated", "()V"); 1614 1615 cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls, 1616 "notifyRfFieldDeactivated", "()V"); 1617 1618 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1) 1619 { 1620 ALOGD("Native Structure initialization failed"); 1621 return FALSE; 1622 } 1623 1624 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) 1625 { 1626 ALOGD("Native Structure initialization failed"); 1627 return FALSE; 1628 } 1629 TRACE("****** Init Native Structure OK ******"); 1630 return TRUE; 1631 1632 } 1633 1634 /* Init/Deinit method */ 1635 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) 1636 { 1637 struct nfc_jni_native_data *nat = NULL; 1638 int init_result = JNI_FALSE; 1639 #ifdef TNFC_EMULATOR_ONLY 1640 char value[PROPERTY_VALUE_MAX]; 1641 #endif 1642 jboolean result; 1643 1644 CONCURRENCY_LOCK(); 1645 1646 #ifdef TNFC_EMULATOR_ONLY 1647 if (!property_get("ro.kernel.qemu", value, 0)) 1648 { 1649 ALOGE("NFC Initialization failed: not running in an emulator\n"); 1650 goto clean_and_return; 1651 } 1652 #endif 1653 1654 /* Retrieve native structure address */ 1655 nat = nfc_jni_get_nat(e, o); 1656 1657 nat->seId = SMX_SECURE_ELEMENT_ID; 1658 1659 nat->lto = 150; // LLCP_LTO 1660 nat->miu = 128; // LLCP_MIU 1661 // WKS indicates well-known services; 1 << sap for each supported SAP. 1662 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4) 1663 nat->wks = 0x13; // LLCP_WKS 1664 nat->opt = 0; // LLCP_OPT 1665 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1666 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1667 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE; 1668 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE; 1669 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE; 1670 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE; 1671 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE; 1672 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE; 1673 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1674 1675 nat->registry_info.MifareUL = TRUE; 1676 nat->registry_info.MifareStd = TRUE; 1677 nat->registry_info.ISO14443_4A = TRUE; 1678 nat->registry_info.ISO14443_4B = TRUE; 1679 nat->registry_info.Jewel = TRUE; 1680 nat->registry_info.Felica = TRUE; 1681 nat->registry_info.NFC = TRUE; 1682 nat->registry_info.ISO15693 = TRUE; 1683 1684 exported_nat = nat; 1685 1686 /* Perform the initialization */ 1687 init_result = nfc_jni_initialize(nat); 1688 1689 clean_and_return: 1690 CONCURRENCY_UNLOCK(); 1691 1692 /* Convert the result and return */ 1693 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE; 1694 } 1695 1696 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o) 1697 { 1698 struct timespec ts; 1699 NFCSTATUS status; 1700 int result = JNI_FALSE; 1701 struct nfc_jni_native_data *nat; 1702 int bStackReset = FALSE; 1703 struct nfc_jni_callback_data cb_data; 1704 1705 CONCURRENCY_LOCK(); 1706 1707 /* Retrieve native structure address */ 1708 nat = nfc_jni_get_nat(e, o); 1709 1710 /* Clear previous configuration */ 1711 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t)); 1712 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t)); 1713 1714 /* Create the local semaphore */ 1715 if (nfc_cb_data_init(&cb_data, NULL)) 1716 { 1717 TRACE("phLibNfc_Mgt_DeInitialize()"); 1718 REENTRANCE_LOCK(); 1719 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data); 1720 REENTRANCE_UNLOCK(); 1721 if (status == NFCSTATUS_PENDING) 1722 { 1723 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1724 1725 clock_gettime(CLOCK_REALTIME, &ts); 1726 ts.tv_sec += 5; 1727 1728 /* Wait for callback response */ 1729 if(sem_timedwait(&cb_data.sem, &ts) == -1) 1730 { 1731 ALOGW("Operation timed out"); 1732 bStackReset = TRUE; 1733 } 1734 1735 if(cb_data.status != NFCSTATUS_SUCCESS) 1736 { 1737 ALOGE("Failed to deinit the stack"); 1738 bStackReset = TRUE; 1739 } 1740 } 1741 else 1742 { 1743 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1744 bStackReset = TRUE; 1745 } 1746 nfc_cb_data_deinit(&cb_data); 1747 } 1748 else 1749 { 1750 ALOGE("Failed to create semaphore (errno=0x%08x)", errno); 1751 bStackReset = TRUE; 1752 } 1753 1754 kill_client(nat); 1755 1756 if(bStackReset == TRUE) 1757 { 1758 /* Complete deinit. failed, try hard restart of NFC */ 1759 ALOGW("Reseting stack..."); 1760 emergency_recovery(nat); 1761 } 1762 1763 result = nfc_jni_unconfigure_driver(nat); 1764 1765 TRACE("NFC Deinitialized"); 1766 1767 CONCURRENCY_UNLOCK(); 1768 1769 return TRUE; 1770 } 1771 1772 /* Llcp methods */ 1773 1774 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o) 1775 { 1776 NFCSTATUS ret; 1777 bool freeData = false; 1778 jboolean result = JNI_FALSE; 1779 struct nfc_jni_native_data *nat; 1780 struct nfc_jni_callback_data *cb_data; 1781 1782 1783 CONCURRENCY_LOCK(); 1784 1785 /* Memory allocation for cb_data 1786 * This is on the heap because it is used by libnfc 1787 * even after this call has succesfully finished. It is only freed 1788 * upon link closure in nfc_jni_llcp_linkStatus_callback. 1789 */ 1790 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data)); 1791 1792 /* Retrieve native structure address */ 1793 nat = nfc_jni_get_nat(e, o); 1794 1795 /* Create the local semaphore */ 1796 if (!nfc_cb_data_init(cb_data, (void*)nat)) 1797 { 1798 goto clean_and_return; 1799 } 1800 1801 /* Check LLCP compliancy */ 1802 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle); 1803 REENTRANCE_LOCK(); 1804 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle, 1805 nfc_jni_checkLlcp_callback, 1806 nfc_jni_llcp_linkStatus_callback, 1807 (void*)cb_data); 1808 REENTRANCE_UNLOCK(); 1809 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol 1810 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */ 1811 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) 1812 { 1813 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1814 freeData = true; 1815 goto clean_and_return; 1816 } 1817 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1818 1819 /* Wait for callback response */ 1820 if(sem_wait(&cb_data->sem)) 1821 { 1822 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1823 goto clean_and_return; 1824 } 1825 1826 if(cb_data->status == NFCSTATUS_SUCCESS) 1827 { 1828 result = JNI_TRUE; 1829 } 1830 1831 clean_and_return: 1832 nfc_cb_data_deinit(cb_data); 1833 if (freeData) { 1834 free(cb_data); 1835 } 1836 CONCURRENCY_UNLOCK(); 1837 return result; 1838 } 1839 1840 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject) 1841 { 1842 NFCSTATUS ret; 1843 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle); 1844 REENTRANCE_LOCK(); 1845 ret = phLibNfc_Llcp_Activate(hLlcpHandle); 1846 REENTRANCE_UNLOCK(); 1847 if(ret == NFCSTATUS_SUCCESS) 1848 { 1849 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1850 return JNI_TRUE; 1851 } 1852 else 1853 { 1854 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1855 return JNI_FALSE; 1856 } 1857 } 1858 1859 1860 1861 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o, 1862 jint nSap, jstring sn) 1863 { 1864 NFCSTATUS ret; 1865 jobject connectionlessSocket = NULL; 1866 phLibNfc_Handle hLlcpSocket; 1867 struct nfc_jni_native_data *nat; 1868 phNfc_sData_t sWorkingBuffer = {NULL, 0}; 1869 phNfc_sData_t serviceName = {NULL, 0}; 1870 phLibNfc_Llcp_sLinkParameters_t sParams; 1871 jclass clsNativeConnectionlessSocket; 1872 jfieldID f; 1873 1874 /* Retrieve native structure address */ 1875 nat = nfc_jni_get_nat(e, o); 1876 1877 /* Allocate Working buffer length */ 1878 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); 1879 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP 1880 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 1881 1882 /* Create socket */ 1883 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)"); 1884 REENTRANCE_LOCK(); 1885 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess, 1886 NULL, 1887 &sWorkingBuffer, 1888 &hLlcpSocket, 1889 nfc_jni_llcp_transport_socket_err_callback, 1890 (void*)nat); 1891 REENTRANCE_UNLOCK(); 1892 1893 if(ret != NFCSTATUS_SUCCESS) 1894 { 1895 lastErrorStatus = ret; 1896 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1897 goto error; 1898 } 1899 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1900 1901 /* Service socket */ 1902 if (sn == NULL) { 1903 serviceName.buffer = NULL; 1904 serviceName.length = 0; 1905 } else { 1906 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 1907 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 1908 } 1909 1910 /* Bind socket */ 1911 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 1912 REENTRANCE_LOCK(); 1913 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 1914 REENTRANCE_UNLOCK(); 1915 if(ret != NFCSTATUS_SUCCESS) 1916 { 1917 lastErrorStatus = ret; 1918 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1919 /* Close socket created */ 1920 REENTRANCE_LOCK(); 1921 ret = phLibNfc_Llcp_Close(hLlcpSocket); 1922 REENTRANCE_UNLOCK(); 1923 goto error; 1924 } 1925 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1926 1927 1928 /* Create new NativeLlcpConnectionlessSocket object */ 1929 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) 1930 { 1931 goto error; 1932 } 1933 1934 /* Get NativeConnectionless class object */ 1935 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); 1936 if(e->ExceptionCheck()) 1937 { 1938 goto error; 1939 } 1940 1941 /* Set socket handle */ 1942 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); 1943 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); 1944 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); 1945 1946 /* Set the miu link of the connectionless socket */ 1947 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); 1948 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); 1949 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); 1950 1951 /* Set socket SAP */ 1952 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); 1953 e->SetIntField(connectionlessSocket, f,(jint)nSap); 1954 TRACE("Connectionless socket SAP = %d\n",nSap); 1955 1956 return connectionlessSocket; 1957 error: 1958 if (serviceName.buffer != NULL) { 1959 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 1960 } 1961 1962 if (sWorkingBuffer.buffer != NULL) { 1963 free(sWorkingBuffer.buffer); 1964 } 1965 1966 return NULL; 1967 } 1968 1969 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) 1970 { 1971 NFCSTATUS ret; 1972 phLibNfc_Handle hLlcpSocket; 1973 phLibNfc_Llcp_sSocketOptions_t sOptions; 1974 phNfc_sData_t sWorkingBuffer; 1975 phNfc_sData_t serviceName; 1976 struct nfc_jni_native_data *nat; 1977 jobject serviceSocket = NULL; 1978 jclass clsNativeLlcpServiceSocket; 1979 jfieldID f; 1980 1981 /* Retrieve native structure address */ 1982 nat = nfc_jni_get_nat(e, o); 1983 1984 /* Set Connection Oriented socket options */ 1985 sOptions.miu = miu; 1986 sOptions.rw = rw; 1987 1988 /* Allocate Working buffer length */ 1989 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 1990 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 1991 1992 1993 /* Create socket */ 1994 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); 1995 REENTRANCE_LOCK(); 1996 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 1997 &sOptions, 1998 &sWorkingBuffer, 1999 &hLlcpSocket, 2000 nfc_jni_llcp_transport_socket_err_callback, 2001 (void*)nat); 2002 REENTRANCE_UNLOCK(); 2003 2004 if(ret != NFCSTATUS_SUCCESS) 2005 { 2006 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2007 lastErrorStatus = ret; 2008 goto error; 2009 } 2010 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2011 2012 /* Service socket */ 2013 if (sn == NULL) { 2014 serviceName.buffer = NULL; 2015 serviceName.length = 0; 2016 } else { 2017 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2018 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2019 } 2020 2021 /* Bind socket */ 2022 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2023 REENTRANCE_LOCK(); 2024 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2025 REENTRANCE_UNLOCK(); 2026 if(ret != NFCSTATUS_SUCCESS) 2027 { 2028 lastErrorStatus = ret; 2029 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2030 /* Close socket created */ 2031 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2032 goto error; 2033 } 2034 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2035 2036 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket); 2037 REENTRANCE_LOCK(); 2038 ret = phLibNfc_Llcp_Listen( hLlcpSocket, 2039 nfc_jni_llcp_transport_listen_socket_callback, 2040 (void*)hLlcpSocket); 2041 REENTRANCE_UNLOCK(); 2042 2043 if(ret != NFCSTATUS_SUCCESS) 2044 { 2045 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2046 lastErrorStatus = ret; 2047 /* Close created socket */ 2048 REENTRANCE_LOCK(); 2049 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2050 REENTRANCE_UNLOCK(); 2051 goto error; 2052 } 2053 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2054 2055 /* Create new NativeLlcpServiceSocket object */ 2056 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1) 2057 { 2058 ALOGE("Llcp Socket object creation error"); 2059 goto error; 2060 } 2061 2062 /* Get NativeLlcpServiceSocket class object */ 2063 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); 2064 if(e->ExceptionCheck()) 2065 { 2066 ALOGE("Llcp Socket get object class error"); 2067 goto error; 2068 } 2069 2070 /* Set socket handle */ 2071 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); 2072 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); 2073 TRACE("Service socket Handle = %02x\n",hLlcpSocket); 2074 2075 /* Set socket linear buffer length */ 2076 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); 2077 e->SetIntField(serviceSocket, f,(jint)linearBufferLength); 2078 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); 2079 2080 /* Set socket MIU */ 2081 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); 2082 e->SetIntField(serviceSocket, f,(jint)miu); 2083 TRACE("Service socket MIU = %d\n",miu); 2084 2085 /* Set socket RW */ 2086 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); 2087 e->SetIntField(serviceSocket, f,(jint)rw); 2088 TRACE("Service socket RW = %d\n",rw); 2089 2090 return serviceSocket; 2091 error: 2092 if (serviceName.buffer != NULL) { 2093 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2094 } 2095 return NULL; 2096 } 2097 2098 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) 2099 { 2100 jobject clientSocket = NULL; 2101 NFCSTATUS ret; 2102 phLibNfc_Handle hLlcpSocket; 2103 phLibNfc_Llcp_sSocketOptions_t sOptions; 2104 phNfc_sData_t sWorkingBuffer; 2105 struct nfc_jni_native_data *nat; 2106 jclass clsNativeLlcpSocket; 2107 jfieldID f; 2108 2109 /* Retrieve native structure address */ 2110 nat = nfc_jni_get_nat(e, o); 2111 2112 /* Set Connection Oriented socket options */ 2113 sOptions.miu = miu; 2114 sOptions.rw = rw; 2115 2116 /* Allocate Working buffer length */ 2117 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2118 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2119 2120 /* Create socket */ 2121 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)"); 2122 REENTRANCE_LOCK(); 2123 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2124 &sOptions, 2125 &sWorkingBuffer, 2126 &hLlcpSocket, 2127 nfc_jni_llcp_transport_socket_err_callback, 2128 (void*)nat); 2129 REENTRANCE_UNLOCK(); 2130 2131 if(ret != NFCSTATUS_SUCCESS) 2132 { 2133 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2134 lastErrorStatus = ret; 2135 return NULL; 2136 } 2137 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2138 2139 /* Create new NativeLlcpSocket object */ 2140 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1) 2141 { 2142 ALOGE("Llcp socket object creation error"); 2143 return NULL; 2144 } 2145 2146 /* Get NativeConnectionless class object */ 2147 clsNativeLlcpSocket = e->GetObjectClass(clientSocket); 2148 if(e->ExceptionCheck()) 2149 { 2150 ALOGE("Get class object error"); 2151 return NULL; 2152 } 2153 2154 /* Test if an SAP number is present */ 2155 if(nSap != 0) 2156 { 2157 /* Bind socket */ 2158 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2159 REENTRANCE_LOCK(); 2160 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL); 2161 REENTRANCE_UNLOCK(); 2162 if(ret != NFCSTATUS_SUCCESS) 2163 { 2164 lastErrorStatus = ret; 2165 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2166 /* Close socket created */ 2167 REENTRANCE_LOCK(); 2168 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2169 REENTRANCE_UNLOCK(); 2170 return NULL; 2171 } 2172 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2173 2174 /* Set socket SAP */ 2175 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); 2176 e->SetIntField(clientSocket, f,(jint)nSap); 2177 TRACE("socket SAP = %d\n",nSap); 2178 } 2179 2180 /* Set socket handle */ 2181 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); 2182 e->SetIntField(clientSocket, f,(jint)hLlcpSocket); 2183 TRACE("socket Handle = %02x\n",hLlcpSocket); 2184 2185 /* Set socket MIU */ 2186 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); 2187 e->SetIntField(clientSocket, f,(jint)miu); 2188 TRACE("socket MIU = %d\n",miu); 2189 2190 /* Set socket RW */ 2191 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); 2192 e->SetIntField(clientSocket, f,(jint)rw); 2193 TRACE("socket RW = %d\n",rw); 2194 2195 2196 return clientSocket; 2197 } 2198 2199 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject) 2200 { 2201 TRACE("Last Error Status = 0x%02x",lastErrorStatus); 2202 2203 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) 2204 { 2205 return ERROR_BUFFER_TOO_SMALL; 2206 } 2207 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES) 2208 { 2209 return ERROR_INSUFFICIENT_RESOURCES; 2210 } 2211 else 2212 { 2213 return lastErrorStatus; 2214 } 2215 } 2216 2217 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject) 2218 { 2219 emergency_recovery(NULL); 2220 } 2221 2222 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o, 2223 jint modes) 2224 { 2225 ALOGE("Setting init modes to %x", modes); 2226 struct nfc_jni_native_data *nat = NULL; 2227 nat = nfc_jni_get_nat(e, o); 2228 nat->p2p_initiator_modes = modes; 2229 } 2230 2231 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o, 2232 jint modes) 2233 { 2234 ALOGE("Setting target modes to %x", modes); 2235 struct nfc_jni_native_data *nat = NULL; 2236 nat = nfc_jni_get_nat(e, o); 2237 nat->p2p_target_modes = modes; 2238 } 2239 2240 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) { 2241 bool result = FALSE; 2242 int load_result; 2243 bool wasDisabled = FALSE; 2244 uint8_t OutputBuffer[1]; 2245 uint8_t InputBuffer[1]; 2246 NFCSTATUS status = NFCSTATUS_FAILED; 2247 struct nfc_jni_callback_data cb_data; 2248 2249 /* Create the local semaphore */ 2250 if (!nfc_cb_data_init(&cb_data, NULL)) 2251 { 2252 result = FALSE; 2253 goto clean_and_return; 2254 } 2255 2256 if (takeLock) 2257 { 2258 CONCURRENCY_LOCK(); 2259 } 2260 2261 /* Initialize Driver */ 2262 if(!driverConfigured) 2263 { 2264 result = nfc_jni_configure_driver(nat); 2265 wasDisabled = TRUE; 2266 } 2267 TRACE("com_android_nfc_NfcManager_doDownload()"); 2268 2269 TRACE("Go in Download Mode"); 2270 phLibNfc_Download_Mode(); 2271 2272 TRACE("Load new Firmware Image"); 2273 load_result = phLibNfc_Load_Firmware_Image(); 2274 if(load_result != 0) 2275 { 2276 TRACE("Load new Firmware Image - status = %d",load_result); 2277 result = FALSE; 2278 goto clean_and_return; 2279 } 2280 2281 // Download 2282 gInputParam.buffer = InputBuffer; 2283 gInputParam.length = 0x01; 2284 gOutputParam.buffer = OutputBuffer; 2285 gOutputParam.length = 0x01; 2286 2287 ALOGD("Download new Firmware"); 2288 REENTRANCE_LOCK(); 2289 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); 2290 REENTRANCE_UNLOCK(); 2291 if(status != NFCSTATUS_PENDING) 2292 { 2293 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2294 result = FALSE; 2295 goto clean_and_return; 2296 } 2297 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2298 2299 /* Wait for callback response */ 2300 if(sem_wait(&cb_data.sem)) 2301 { 2302 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2303 result = FALSE; 2304 goto clean_and_return; 2305 } 2306 2307 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we 2308 try to download an old-style firmware on top of a new-style 2309 firmware. Hence, this is expected behavior, and not an 2310 error condition. */ 2311 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED) 2312 { 2313 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2314 result = FALSE; 2315 goto clean_and_return; 2316 } 2317 2318 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED) 2319 { 2320 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip."); 2321 } 2322 2323 /*Download is successful*/ 2324 result = TRUE; 2325 clean_and_return: 2326 TRACE("phLibNfc_HW_Reset()"); 2327 phLibNfc_HW_Reset(); 2328 /* Deinitialize Driver */ 2329 if(wasDisabled) 2330 { 2331 result = nfc_jni_unconfigure_driver(nat); 2332 } 2333 if (takeLock) 2334 { 2335 CONCURRENCY_UNLOCK(); 2336 } 2337 nfc_cb_data_deinit(&cb_data); 2338 return result; 2339 } 2340 2341 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o) 2342 { 2343 struct nfc_jni_native_data *nat = NULL; 2344 nat = nfc_jni_get_nat(e, o); 2345 return performDownload(nat, true); 2346 } 2347 2348 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject) 2349 { 2350 char buffer[100]; 2351 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count); 2352 return e->NewStringUTF(buffer); 2353 } 2354 2355 /* 2356 * JNI registration. 2357 */ 2358 static JNINativeMethod gMethods[] = 2359 { 2360 {"doDownload", "()Z", 2361 (void *)com_android_nfc_NfcManager_doDownload}, 2362 2363 {"initializeNativeStructure", "()Z", 2364 (void *)com_android_nfc_NfcManager_init_native_struc}, 2365 2366 {"doInitialize", "()Z", 2367 (void *)com_android_nfc_NfcManager_initialize}, 2368 2369 {"doDeinitialize", "()Z", 2370 (void *)com_android_nfc_NfcManager_deinitialize}, 2371 2372 {"doEnableDiscovery", "(IZZZ)V", 2373 (void *)com_android_nfc_NfcManager_enableDiscovery}, 2374 2375 {"doCheckLlcp", "()Z", 2376 (void *)com_android_nfc_NfcManager_doCheckLlcp}, 2377 2378 {"doActivateLlcp", "()Z", 2379 (void *)com_android_nfc_NfcManager_doActivateLlcp}, 2380 2381 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;", 2382 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket}, 2383 2384 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;", 2385 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket}, 2386 2387 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;", 2388 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, 2389 2390 {"doGetLastError", "()I", 2391 (void *)com_android_nfc_NfcManager_doGetLastError}, 2392 2393 {"disableDiscovery", "()V", 2394 (void *)com_android_nfc_NfcManager_disableDiscovery}, 2395 2396 {"doSetTimeout", "(II)Z", 2397 (void *)com_android_nfc_NfcManager_doSetTimeout}, 2398 2399 {"doGetTimeout", "(I)I", 2400 (void *)com_android_nfc_NfcManager_doGetTimeout}, 2401 2402 {"doResetTimeouts", "()V", 2403 (void *)com_android_nfc_NfcManager_doResetTimeouts}, 2404 2405 {"doAbort", "()V", 2406 (void *)com_android_nfc_NfcManager_doAbort}, 2407 2408 {"doSetP2pInitiatorModes","(I)V", 2409 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes}, 2410 2411 {"doSetP2pTargetModes","(I)V", 2412 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes}, 2413 2414 {"doDump", "()Ljava/lang/String;", 2415 (void *)com_android_nfc_NfcManager_doDump}, 2416 }; 2417 2418 2419 int register_com_android_nfc_NativeNfcManager(JNIEnv *e) 2420 { 2421 nfc_jni_native_monitor_t *nfc_jni_native_monitor; 2422 2423 nfc_jni_native_monitor = nfc_jni_init_monitor(); 2424 if(nfc_jni_native_monitor == NULL) 2425 { 2426 ALOGE("NFC Manager cannot recover native monitor %x\n", errno); 2427 return -1; 2428 } 2429 2430 return jniRegisterNativeMethods(e, 2431 "com/android/nfc/dhimpl/NativeNfcManager", 2432 gMethods, NELEM(gMethods)); 2433 } 2434 2435 } /* namespace android */ 2436