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 enable_p2p, 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 1397 if (enable_p2p) 1398 { 1399 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1400 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1401 nat->discovery_cfg.Duration = 300000; /* in ms */ 1402 } 1403 else 1404 { 1405 nat->p2p_initiator_modes = 0; 1406 nat->p2p_target_modes = 0; 1407 nat->discovery_cfg.Duration = 200000; /* in ms */ 1408 1409 } 1410 1411 if (reader_mode) 1412 { 1413 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE; 1414 nat->discovery_cfg.Duration = 200000; /* in ms */ 1415 } 1416 else 1417 { 1418 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1419 nat->discovery_cfg.Duration = 300000; /* in ms */ 1420 } 1421 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0; 1422 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0; 1423 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0; 1424 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0; 1425 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0; 1426 } 1427 1428 nfc_jni_start_discovery_locked(nat, false); 1429 clean_and_return: 1430 CONCURRENCY_UNLOCK(); 1431 } 1432 1433 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) { 1434 CONCURRENCY_LOCK(); 1435 nfc_jni_reset_timeout_values(); 1436 CONCURRENCY_UNLOCK(); 1437 } 1438 1439 static void setFelicaTimeout(jint timeout) { 1440 // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms. 1441 // It can be set to 0 to disable the timeout altogether, in which case we 1442 // use the sw watchdog as a fallback. 1443 if (timeout <= 255) { 1444 phLibNfc_SetFelicaTimeout(timeout); 1445 } else { 1446 // Disable hw timeout, use sw watchdog for timeout 1447 phLibNfc_SetFelicaTimeout(0); 1448 phLibNfc_SetHciTimeout(timeout); 1449 } 1450 1451 } 1452 // Calculates ceiling log2 of value 1453 static unsigned int log2(int value) { 1454 unsigned int ret = 0; 1455 bool isPowerOf2 = ((value & (value - 1)) == 0); 1456 while ( (value >> ret) > 1 ) ret++; 1457 if (!isPowerOf2) ret++; 1458 return ret; 1459 } 1460 1461 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X 1462 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X 1463 // 1464 // We keep the constant part of the formula in a static; note the factor 1465 // 1000 off, which is due to the fact that the formula calculates seconds, 1466 // but this method gets milliseconds as an argument. 1467 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0; 1468 1469 static int calcTimeout(int timeout_in_ms) { 1470 // timeout = (256 * 16 / 13560000) * 2 ^ X 1471 // First find the first X for which timeout > requested timeout 1472 return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor))); 1473 } 1474 1475 static void setIsoDepTimeout(jint timeout) { 1476 if (timeout <= 4900) { 1477 int value = calcTimeout(timeout); 1478 // Then re-compute the actual timeout based on X 1479 double actual_timeout = nxp_nfc_timeout_factor * (1 << value); 1480 // Set the sw watchdog a bit longer (The PN544 timeout is very accurate, 1481 // but it will take some time to get back through the sw layers. 1482 // 500 ms should be enough). 1483 phLibNfc_SetHciTimeout(ceil(actual_timeout + 500)); 1484 value |= 0x10; // bit 4 to enable timeout 1485 phLibNfc_SetIsoXchgTimeout(value); 1486 } 1487 else { 1488 // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout 1489 // must be disabled completely, to prevent the PN544 from aborting 1490 // the transaction. We reuse the HCI sw watchdog to catch the timeout 1491 // in that case. 1492 phLibNfc_SetIsoXchgTimeout(0x00); 1493 phLibNfc_SetHciTimeout(timeout); 1494 } 1495 } 1496 1497 static void setNfcATimeout(jint timeout) { 1498 if (timeout <= 4900) { 1499 int value = calcTimeout(timeout); 1500 phLibNfc_SetMifareRawTimeout(value); 1501 } 1502 else { 1503 // Disable mifare raw timeout, use HCI sw watchdog instead 1504 phLibNfc_SetMifareRawTimeout(0x00); 1505 phLibNfc_SetHciTimeout(timeout); 1506 } 1507 } 1508 1509 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject, 1510 jint tech, jint timeout) { 1511 bool success = false; 1512 CONCURRENCY_LOCK(); 1513 if (timeout <= 0) { 1514 ALOGE("Timeout must be positive."); 1515 success = false; 1516 } else { 1517 switch (tech) { 1518 case TARGET_TYPE_MIFARE_CLASSIC: 1519 case TARGET_TYPE_MIFARE_UL: 1520 // Intentional fall-through, Mifare UL, Classic 1521 // transceive just uses raw 3A frames 1522 case TARGET_TYPE_ISO14443_3A: 1523 setNfcATimeout(timeout); 1524 success = true; 1525 break; 1526 case TARGET_TYPE_ISO14443_4: 1527 setIsoDepTimeout(timeout); 1528 success = true; 1529 break; 1530 case TARGET_TYPE_FELICA: 1531 setFelicaTimeout(timeout); 1532 success = true; 1533 break; 1534 default: 1535 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech); 1536 success = false; 1537 } 1538 } 1539 CONCURRENCY_UNLOCK(); 1540 return success; 1541 } 1542 1543 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject, 1544 jint tech) { 1545 int timeout = -1; 1546 CONCURRENCY_LOCK(); 1547 switch (tech) { 1548 case TARGET_TYPE_MIFARE_CLASSIC: 1549 case TARGET_TYPE_MIFARE_UL: 1550 // Intentional fall-through, Mifare UL, Classic 1551 // transceive just uses raw 3A frames 1552 case TARGET_TYPE_ISO14443_3A: 1553 timeout = phLibNfc_GetMifareRawTimeout(); 1554 if (timeout == 0) { 1555 timeout = phLibNfc_GetHciTimeout(); 1556 } else { 1557 // Timeout returned from libnfc needs conversion to ms 1558 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1559 } 1560 break; 1561 case TARGET_TYPE_ISO14443_4: 1562 timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only 1563 if (timeout == 0) { 1564 timeout = phLibNfc_GetHciTimeout(); 1565 } else { 1566 // Timeout returned from libnfc needs conversion to ms 1567 timeout = (nxp_nfc_timeout_factor * (1 << timeout)); 1568 } 1569 break; 1570 case TARGET_TYPE_FELICA: 1571 timeout = phLibNfc_GetFelicaTimeout(); 1572 if (timeout == 0) { 1573 timeout = phLibNfc_GetHciTimeout(); 1574 } else { 1575 // Felica timeout already in ms 1576 } 1577 break; 1578 default: 1579 ALOGW("doGetTimeout: Timeout not supported for tech %d", tech); 1580 break; 1581 } 1582 CONCURRENCY_UNLOCK(); 1583 return timeout; 1584 } 1585 1586 1587 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o) 1588 { 1589 NFCSTATUS status; 1590 struct nfc_jni_native_data *nat = NULL; 1591 jclass cls; 1592 jobject obj; 1593 jfieldID f; 1594 1595 TRACE("****** Init Native Structure ******"); 1596 1597 /* Initialize native structure */ 1598 nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); 1599 if(nat == NULL) 1600 { 1601 ALOGD("malloc of nfc_jni_native_data failed"); 1602 return FALSE; 1603 } 1604 memset(nat, 0, sizeof(*nat)); 1605 e->GetJavaVM(&(nat->vm)); 1606 nat->env_version = e->GetVersion(); 1607 nat->manager = e->NewGlobalRef(o); 1608 1609 cls = e->GetObjectClass(o); 1610 f = e->GetFieldID(cls, "mNative", "J"); 1611 e->SetLongField(o, f, (jlong)nat); 1612 1613 /* Initialize native cached references */ 1614 cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, 1615 "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); 1616 1617 cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, 1618 "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1619 1620 cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls, 1621 "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); 1622 1623 cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls, 1624 "notifyRfFieldActivated", "()V"); 1625 1626 cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls, 1627 "notifyRfFieldDeactivated", "()V"); 1628 1629 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1) 1630 { 1631 ALOGD("Native Structure initialization failed"); 1632 return FALSE; 1633 } 1634 1635 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) 1636 { 1637 ALOGD("Native Structure initialization failed"); 1638 return FALSE; 1639 } 1640 TRACE("****** Init Native Structure OK ******"); 1641 return TRUE; 1642 1643 } 1644 1645 /* Init/Deinit method */ 1646 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) 1647 { 1648 struct nfc_jni_native_data *nat = NULL; 1649 int init_result = JNI_FALSE; 1650 #ifdef TNFC_EMULATOR_ONLY 1651 char value[PROPERTY_VALUE_MAX]; 1652 #endif 1653 jboolean result; 1654 1655 CONCURRENCY_LOCK(); 1656 1657 #ifdef TNFC_EMULATOR_ONLY 1658 if (!property_get("ro.kernel.qemu", value, 0)) 1659 { 1660 ALOGE("NFC Initialization failed: not running in an emulator\n"); 1661 goto clean_and_return; 1662 } 1663 #endif 1664 1665 /* Retrieve native structure address */ 1666 nat = nfc_jni_get_nat(e, o); 1667 1668 nat->seId = SMX_SECURE_ELEMENT_ID; 1669 1670 nat->lto = 150; // LLCP_LTO 1671 nat->miu = 128; // LLCP_MIU 1672 // WKS indicates well-known services; 1 << sap for each supported SAP. 1673 // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4) 1674 nat->wks = 0x13; // LLCP_WKS 1675 nat->opt = 0; // LLCP_OPT 1676 nat->p2p_initiator_modes = phNfc_eP2P_ALL; 1677 nat->p2p_target_modes = 0x0E; // All passive except 106, active 1678 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE; 1679 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE; 1680 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE; 1681 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE; 1682 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE; 1683 nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE; 1684 nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; 1685 1686 nat->registry_info.MifareUL = TRUE; 1687 nat->registry_info.MifareStd = TRUE; 1688 nat->registry_info.ISO14443_4A = TRUE; 1689 nat->registry_info.ISO14443_4B = TRUE; 1690 nat->registry_info.Jewel = TRUE; 1691 nat->registry_info.Felica = TRUE; 1692 nat->registry_info.NFC = TRUE; 1693 nat->registry_info.ISO15693 = TRUE; 1694 1695 exported_nat = nat; 1696 1697 /* Perform the initialization */ 1698 init_result = nfc_jni_initialize(nat); 1699 1700 clean_and_return: 1701 CONCURRENCY_UNLOCK(); 1702 1703 /* Convert the result and return */ 1704 return (init_result==TRUE)?JNI_TRUE:JNI_FALSE; 1705 } 1706 1707 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o) 1708 { 1709 struct timespec ts; 1710 NFCSTATUS status; 1711 int result = JNI_FALSE; 1712 struct nfc_jni_native_data *nat; 1713 int bStackReset = FALSE; 1714 struct nfc_jni_callback_data cb_data; 1715 1716 CONCURRENCY_LOCK(); 1717 1718 /* Retrieve native structure address */ 1719 nat = nfc_jni_get_nat(e, o); 1720 1721 /* Clear previous configuration */ 1722 memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t)); 1723 memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t)); 1724 1725 /* Create the local semaphore */ 1726 if (nfc_cb_data_init(&cb_data, NULL)) 1727 { 1728 TRACE("phLibNfc_Mgt_DeInitialize()"); 1729 REENTRANCE_LOCK(); 1730 status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data); 1731 REENTRANCE_UNLOCK(); 1732 if (status == NFCSTATUS_PENDING) 1733 { 1734 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1735 1736 clock_gettime(CLOCK_REALTIME, &ts); 1737 ts.tv_sec += 5; 1738 1739 /* Wait for callback response */ 1740 if(sem_timedwait(&cb_data.sem, &ts) == -1) 1741 { 1742 ALOGW("Operation timed out"); 1743 bStackReset = TRUE; 1744 } 1745 1746 if(cb_data.status != NFCSTATUS_SUCCESS) 1747 { 1748 ALOGE("Failed to deinit the stack"); 1749 bStackReset = TRUE; 1750 } 1751 } 1752 else 1753 { 1754 TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 1755 bStackReset = TRUE; 1756 } 1757 nfc_cb_data_deinit(&cb_data); 1758 } 1759 else 1760 { 1761 ALOGE("Failed to create semaphore (errno=0x%08x)", errno); 1762 bStackReset = TRUE; 1763 } 1764 1765 kill_client(nat); 1766 1767 if(bStackReset == TRUE) 1768 { 1769 /* Complete deinit. failed, try hard restart of NFC */ 1770 ALOGW("Reseting stack..."); 1771 emergency_recovery(nat); 1772 } 1773 1774 result = nfc_jni_unconfigure_driver(nat); 1775 1776 TRACE("NFC Deinitialized"); 1777 1778 CONCURRENCY_UNLOCK(); 1779 1780 return TRUE; 1781 } 1782 1783 /* Llcp methods */ 1784 1785 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o) 1786 { 1787 NFCSTATUS ret; 1788 bool freeData = false; 1789 jboolean result = JNI_FALSE; 1790 struct nfc_jni_native_data *nat; 1791 struct nfc_jni_callback_data *cb_data; 1792 1793 1794 CONCURRENCY_LOCK(); 1795 1796 /* Memory allocation for cb_data 1797 * This is on the heap because it is used by libnfc 1798 * even after this call has succesfully finished. It is only freed 1799 * upon link closure in nfc_jni_llcp_linkStatus_callback. 1800 */ 1801 cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data)); 1802 1803 /* Retrieve native structure address */ 1804 nat = nfc_jni_get_nat(e, o); 1805 1806 /* Create the local semaphore */ 1807 if (!nfc_cb_data_init(cb_data, (void*)nat)) 1808 { 1809 goto clean_and_return; 1810 } 1811 1812 /* Check LLCP compliancy */ 1813 TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle); 1814 REENTRANCE_LOCK(); 1815 ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle, 1816 nfc_jni_checkLlcp_callback, 1817 nfc_jni_llcp_linkStatus_callback, 1818 (void*)cb_data); 1819 REENTRANCE_UNLOCK(); 1820 /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol 1821 * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */ 1822 if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) 1823 { 1824 ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1825 freeData = true; 1826 goto clean_and_return; 1827 } 1828 TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1829 1830 /* Wait for callback response */ 1831 if(sem_wait(&cb_data->sem)) 1832 { 1833 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 1834 goto clean_and_return; 1835 } 1836 1837 if(cb_data->status == NFCSTATUS_SUCCESS) 1838 { 1839 result = JNI_TRUE; 1840 } 1841 1842 clean_and_return: 1843 nfc_cb_data_deinit(cb_data); 1844 if (freeData) { 1845 free(cb_data); 1846 } 1847 CONCURRENCY_UNLOCK(); 1848 return result; 1849 } 1850 1851 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject) 1852 { 1853 NFCSTATUS ret; 1854 TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle); 1855 REENTRANCE_LOCK(); 1856 ret = phLibNfc_Llcp_Activate(hLlcpHandle); 1857 REENTRANCE_UNLOCK(); 1858 if(ret == NFCSTATUS_SUCCESS) 1859 { 1860 TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1861 return JNI_TRUE; 1862 } 1863 else 1864 { 1865 ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1866 return JNI_FALSE; 1867 } 1868 } 1869 1870 1871 1872 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o, 1873 jint nSap, jstring sn) 1874 { 1875 NFCSTATUS ret; 1876 jobject connectionlessSocket = NULL; 1877 phLibNfc_Handle hLlcpSocket; 1878 struct nfc_jni_native_data *nat; 1879 phNfc_sData_t sWorkingBuffer = {NULL, 0}; 1880 phNfc_sData_t serviceName = {NULL, 0}; 1881 phLibNfc_Llcp_sLinkParameters_t sParams; 1882 jclass clsNativeConnectionlessSocket; 1883 jfieldID f; 1884 1885 /* Retrieve native structure address */ 1886 nat = nfc_jni_get_nat(e, o); 1887 1888 /* Allocate Working buffer length */ 1889 phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); 1890 sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP 1891 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 1892 1893 /* Create socket */ 1894 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)"); 1895 REENTRANCE_LOCK(); 1896 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess, 1897 NULL, 1898 &sWorkingBuffer, 1899 &hLlcpSocket, 1900 nfc_jni_llcp_transport_socket_err_callback, 1901 (void*)nat); 1902 REENTRANCE_UNLOCK(); 1903 1904 if(ret != NFCSTATUS_SUCCESS) 1905 { 1906 lastErrorStatus = ret; 1907 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1908 goto error; 1909 } 1910 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1911 1912 /* Service socket */ 1913 if (sn == NULL) { 1914 serviceName.buffer = NULL; 1915 serviceName.length = 0; 1916 } else { 1917 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 1918 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 1919 } 1920 1921 /* Bind socket */ 1922 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 1923 REENTRANCE_LOCK(); 1924 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 1925 REENTRANCE_UNLOCK(); 1926 if(ret != NFCSTATUS_SUCCESS) 1927 { 1928 lastErrorStatus = ret; 1929 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1930 /* Close socket created */ 1931 REENTRANCE_LOCK(); 1932 ret = phLibNfc_Llcp_Close(hLlcpSocket); 1933 REENTRANCE_UNLOCK(); 1934 goto error; 1935 } 1936 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 1937 1938 1939 /* Create new NativeLlcpConnectionlessSocket object */ 1940 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) 1941 { 1942 goto error; 1943 } 1944 1945 /* Get NativeConnectionless class object */ 1946 clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); 1947 if(e->ExceptionCheck()) 1948 { 1949 goto error; 1950 } 1951 1952 /* Set socket handle */ 1953 f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); 1954 e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); 1955 TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); 1956 1957 /* Set the miu link of the connectionless socket */ 1958 f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); 1959 e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); 1960 TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); 1961 1962 /* Set socket SAP */ 1963 f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); 1964 e->SetIntField(connectionlessSocket, f,(jint)nSap); 1965 TRACE("Connectionless socket SAP = %d\n",nSap); 1966 1967 return connectionlessSocket; 1968 error: 1969 if (serviceName.buffer != NULL) { 1970 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 1971 } 1972 1973 if (sWorkingBuffer.buffer != NULL) { 1974 free(sWorkingBuffer.buffer); 1975 } 1976 1977 return NULL; 1978 } 1979 1980 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) 1981 { 1982 NFCSTATUS ret; 1983 phLibNfc_Handle hLlcpSocket; 1984 phLibNfc_Llcp_sSocketOptions_t sOptions; 1985 phNfc_sData_t sWorkingBuffer; 1986 phNfc_sData_t serviceName; 1987 struct nfc_jni_native_data *nat; 1988 jobject serviceSocket = NULL; 1989 jclass clsNativeLlcpServiceSocket; 1990 jfieldID f; 1991 1992 /* Retrieve native structure address */ 1993 nat = nfc_jni_get_nat(e, o); 1994 1995 /* Set Connection Oriented socket options */ 1996 sOptions.miu = miu; 1997 sOptions.rw = rw; 1998 1999 /* Allocate Working buffer length */ 2000 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2001 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2002 2003 2004 /* Create socket */ 2005 TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); 2006 REENTRANCE_LOCK(); 2007 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2008 &sOptions, 2009 &sWorkingBuffer, 2010 &hLlcpSocket, 2011 nfc_jni_llcp_transport_socket_err_callback, 2012 (void*)nat); 2013 REENTRANCE_UNLOCK(); 2014 2015 if(ret != NFCSTATUS_SUCCESS) 2016 { 2017 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2018 lastErrorStatus = ret; 2019 goto error; 2020 } 2021 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2022 2023 /* Service socket */ 2024 if (sn == NULL) { 2025 serviceName.buffer = NULL; 2026 serviceName.length = 0; 2027 } else { 2028 serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); 2029 serviceName.length = (uint32_t)e->GetStringUTFLength(sn); 2030 } 2031 2032 /* Bind socket */ 2033 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2034 REENTRANCE_LOCK(); 2035 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); 2036 REENTRANCE_UNLOCK(); 2037 if(ret != NFCSTATUS_SUCCESS) 2038 { 2039 lastErrorStatus = ret; 2040 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2041 /* Close socket created */ 2042 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2043 goto error; 2044 } 2045 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2046 2047 TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket); 2048 REENTRANCE_LOCK(); 2049 ret = phLibNfc_Llcp_Listen( hLlcpSocket, 2050 nfc_jni_llcp_transport_listen_socket_callback, 2051 (void*)hLlcpSocket); 2052 REENTRANCE_UNLOCK(); 2053 2054 if(ret != NFCSTATUS_SUCCESS) 2055 { 2056 ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2057 lastErrorStatus = ret; 2058 /* Close created socket */ 2059 REENTRANCE_LOCK(); 2060 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2061 REENTRANCE_UNLOCK(); 2062 goto error; 2063 } 2064 TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2065 2066 /* Create new NativeLlcpServiceSocket object */ 2067 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1) 2068 { 2069 ALOGE("Llcp Socket object creation error"); 2070 goto error; 2071 } 2072 2073 /* Get NativeLlcpServiceSocket class object */ 2074 clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); 2075 if(e->ExceptionCheck()) 2076 { 2077 ALOGE("Llcp Socket get object class error"); 2078 goto error; 2079 } 2080 2081 /* Set socket handle */ 2082 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); 2083 e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); 2084 TRACE("Service socket Handle = %02x\n",hLlcpSocket); 2085 2086 /* Set socket linear buffer length */ 2087 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); 2088 e->SetIntField(serviceSocket, f,(jint)linearBufferLength); 2089 TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); 2090 2091 /* Set socket MIU */ 2092 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); 2093 e->SetIntField(serviceSocket, f,(jint)miu); 2094 TRACE("Service socket MIU = %d\n",miu); 2095 2096 /* Set socket RW */ 2097 f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); 2098 e->SetIntField(serviceSocket, f,(jint)rw); 2099 TRACE("Service socket RW = %d\n",rw); 2100 2101 return serviceSocket; 2102 error: 2103 if (serviceName.buffer != NULL) { 2104 e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); 2105 } 2106 return NULL; 2107 } 2108 2109 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) 2110 { 2111 jobject clientSocket = NULL; 2112 NFCSTATUS ret; 2113 phLibNfc_Handle hLlcpSocket; 2114 phLibNfc_Llcp_sSocketOptions_t sOptions; 2115 phNfc_sData_t sWorkingBuffer; 2116 struct nfc_jni_native_data *nat; 2117 jclass clsNativeLlcpSocket; 2118 jfieldID f; 2119 2120 /* Retrieve native structure address */ 2121 nat = nfc_jni_get_nat(e, o); 2122 2123 /* Set Connection Oriented socket options */ 2124 sOptions.miu = miu; 2125 sOptions.rw = rw; 2126 2127 /* Allocate Working buffer length */ 2128 sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; 2129 sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); 2130 2131 /* Create socket */ 2132 TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)"); 2133 REENTRANCE_LOCK(); 2134 ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, 2135 &sOptions, 2136 &sWorkingBuffer, 2137 &hLlcpSocket, 2138 nfc_jni_llcp_transport_socket_err_callback, 2139 (void*)nat); 2140 REENTRANCE_UNLOCK(); 2141 2142 if(ret != NFCSTATUS_SUCCESS) 2143 { 2144 ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2145 lastErrorStatus = ret; 2146 return NULL; 2147 } 2148 TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2149 2150 /* Create new NativeLlcpSocket object */ 2151 if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1) 2152 { 2153 ALOGE("Llcp socket object creation error"); 2154 return NULL; 2155 } 2156 2157 /* Get NativeConnectionless class object */ 2158 clsNativeLlcpSocket = e->GetObjectClass(clientSocket); 2159 if(e->ExceptionCheck()) 2160 { 2161 ALOGE("Get class object error"); 2162 return NULL; 2163 } 2164 2165 /* Test if an SAP number is present */ 2166 if(nSap != 0) 2167 { 2168 /* Bind socket */ 2169 TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); 2170 REENTRANCE_LOCK(); 2171 ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL); 2172 REENTRANCE_UNLOCK(); 2173 if(ret != NFCSTATUS_SUCCESS) 2174 { 2175 lastErrorStatus = ret; 2176 ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2177 /* Close socket created */ 2178 REENTRANCE_LOCK(); 2179 ret = phLibNfc_Llcp_Close(hLlcpSocket); 2180 REENTRANCE_UNLOCK(); 2181 return NULL; 2182 } 2183 TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 2184 2185 /* Set socket SAP */ 2186 f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); 2187 e->SetIntField(clientSocket, f,(jint)nSap); 2188 TRACE("socket SAP = %d\n",nSap); 2189 } 2190 2191 /* Set socket handle */ 2192 f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); 2193 e->SetIntField(clientSocket, f,(jint)hLlcpSocket); 2194 TRACE("socket Handle = %02x\n",hLlcpSocket); 2195 2196 /* Set socket MIU */ 2197 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); 2198 e->SetIntField(clientSocket, f,(jint)miu); 2199 TRACE("socket MIU = %d\n",miu); 2200 2201 /* Set socket RW */ 2202 f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); 2203 e->SetIntField(clientSocket, f,(jint)rw); 2204 TRACE("socket RW = %d\n",rw); 2205 2206 2207 return clientSocket; 2208 } 2209 2210 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject) 2211 { 2212 TRACE("Last Error Status = 0x%02x",lastErrorStatus); 2213 2214 if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) 2215 { 2216 return ERROR_BUFFER_TOO_SMALL; 2217 } 2218 else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES) 2219 { 2220 return ERROR_INSUFFICIENT_RESOURCES; 2221 } 2222 else 2223 { 2224 return lastErrorStatus; 2225 } 2226 } 2227 2228 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject) 2229 { 2230 emergency_recovery(NULL); 2231 } 2232 2233 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o, 2234 jint modes) 2235 { 2236 ALOGE("Setting init modes to %x", modes); 2237 struct nfc_jni_native_data *nat = NULL; 2238 nat = nfc_jni_get_nat(e, o); 2239 nat->p2p_initiator_modes = modes; 2240 } 2241 2242 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o, 2243 jint modes) 2244 { 2245 ALOGE("Setting target modes to %x", modes); 2246 struct nfc_jni_native_data *nat = NULL; 2247 nat = nfc_jni_get_nat(e, o); 2248 nat->p2p_target_modes = modes; 2249 } 2250 2251 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) { 2252 bool result = FALSE; 2253 int load_result; 2254 bool wasDisabled = FALSE; 2255 uint8_t OutputBuffer[1]; 2256 uint8_t InputBuffer[1]; 2257 NFCSTATUS status = NFCSTATUS_FAILED; 2258 struct nfc_jni_callback_data cb_data; 2259 2260 /* Create the local semaphore */ 2261 if (!nfc_cb_data_init(&cb_data, NULL)) 2262 { 2263 result = FALSE; 2264 goto clean_and_return; 2265 } 2266 2267 if (takeLock) 2268 { 2269 CONCURRENCY_LOCK(); 2270 } 2271 2272 /* Initialize Driver */ 2273 if(!driverConfigured) 2274 { 2275 result = nfc_jni_configure_driver(nat); 2276 wasDisabled = TRUE; 2277 } 2278 TRACE("com_android_nfc_NfcManager_doDownload()"); 2279 2280 TRACE("Go in Download Mode"); 2281 phLibNfc_Download_Mode(); 2282 2283 TRACE("Load new Firmware Image"); 2284 load_result = phLibNfc_Load_Firmware_Image(); 2285 if(load_result != 0) 2286 { 2287 TRACE("Load new Firmware Image - status = %d",load_result); 2288 result = FALSE; 2289 goto clean_and_return; 2290 } 2291 2292 // Download 2293 gInputParam.buffer = InputBuffer; 2294 gInputParam.length = 0x01; 2295 gOutputParam.buffer = OutputBuffer; 2296 gOutputParam.length = 0x01; 2297 2298 ALOGD("Download new Firmware"); 2299 REENTRANCE_LOCK(); 2300 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); 2301 REENTRANCE_UNLOCK(); 2302 if(status != NFCSTATUS_PENDING) 2303 { 2304 ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2305 result = FALSE; 2306 goto clean_and_return; 2307 } 2308 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2309 2310 /* Wait for callback response */ 2311 if(sem_wait(&cb_data.sem)) 2312 { 2313 ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); 2314 result = FALSE; 2315 goto clean_and_return; 2316 } 2317 2318 /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we 2319 try to download an old-style firmware on top of a new-style 2320 firmware. Hence, this is expected behavior, and not an 2321 error condition. */ 2322 if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED) 2323 { 2324 TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 2325 result = FALSE; 2326 goto clean_and_return; 2327 } 2328 2329 if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED) 2330 { 2331 ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip."); 2332 } 2333 2334 /*Download is successful*/ 2335 result = TRUE; 2336 clean_and_return: 2337 TRACE("phLibNfc_HW_Reset()"); 2338 phLibNfc_HW_Reset(); 2339 /* Deinitialize Driver */ 2340 if(wasDisabled) 2341 { 2342 result = nfc_jni_unconfigure_driver(nat); 2343 } 2344 if (takeLock) 2345 { 2346 CONCURRENCY_UNLOCK(); 2347 } 2348 nfc_cb_data_deinit(&cb_data); 2349 return result; 2350 } 2351 2352 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o) 2353 { 2354 struct nfc_jni_native_data *nat = NULL; 2355 nat = nfc_jni_get_nat(e, o); 2356 return performDownload(nat, true); 2357 } 2358 2359 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject) 2360 { 2361 char buffer[100]; 2362 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count); 2363 return e->NewStringUTF(buffer); 2364 } 2365 2366 /* 2367 * JNI registration. 2368 */ 2369 static JNINativeMethod gMethods[] = 2370 { 2371 {"doDownload", "()Z", 2372 (void *)com_android_nfc_NfcManager_doDownload}, 2373 2374 {"initializeNativeStructure", "()Z", 2375 (void *)com_android_nfc_NfcManager_init_native_struc}, 2376 2377 {"doInitialize", "()Z", 2378 (void *)com_android_nfc_NfcManager_initialize}, 2379 2380 {"doDeinitialize", "()Z", 2381 (void *)com_android_nfc_NfcManager_deinitialize}, 2382 2383 {"doEnableDiscovery", "(IZZZZ)V", 2384 (void *)com_android_nfc_NfcManager_enableDiscovery}, 2385 2386 {"doCheckLlcp", "()Z", 2387 (void *)com_android_nfc_NfcManager_doCheckLlcp}, 2388 2389 {"doActivateLlcp", "()Z", 2390 (void *)com_android_nfc_NfcManager_doActivateLlcp}, 2391 2392 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;", 2393 (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket}, 2394 2395 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;", 2396 (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket}, 2397 2398 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;", 2399 (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, 2400 2401 {"doGetLastError", "()I", 2402 (void *)com_android_nfc_NfcManager_doGetLastError}, 2403 2404 {"disableDiscovery", "()V", 2405 (void *)com_android_nfc_NfcManager_disableDiscovery}, 2406 2407 {"doSetTimeout", "(II)Z", 2408 (void *)com_android_nfc_NfcManager_doSetTimeout}, 2409 2410 {"doGetTimeout", "(I)I", 2411 (void *)com_android_nfc_NfcManager_doGetTimeout}, 2412 2413 {"doResetTimeouts", "()V", 2414 (void *)com_android_nfc_NfcManager_doResetTimeouts}, 2415 2416 {"doAbort", "()V", 2417 (void *)com_android_nfc_NfcManager_doAbort}, 2418 2419 {"doSetP2pInitiatorModes","(I)V", 2420 (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes}, 2421 2422 {"doSetP2pTargetModes","(I)V", 2423 (void *)com_android_nfc_NfcManager_doSetP2pTargetModes}, 2424 2425 {"doDump", "()Ljava/lang/String;", 2426 (void *)com_android_nfc_NfcManager_doDump}, 2427 }; 2428 2429 2430 int register_com_android_nfc_NativeNfcManager(JNIEnv *e) 2431 { 2432 nfc_jni_native_monitor_t *nfc_jni_native_monitor; 2433 2434 nfc_jni_native_monitor = nfc_jni_init_monitor(); 2435 if(nfc_jni_native_monitor == NULL) 2436 { 2437 ALOGE("NFC Manager cannot recover native monitor %x\n", errno); 2438 return -1; 2439 } 2440 2441 return jniRegisterNativeMethods(e, 2442 "com/android/nfc/dhimpl/NativeNfcManager", 2443 gMethods, NELEM(gMethods)); 2444 } 2445 2446 } /* namespace android */ 2447