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