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