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