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 <semaphore.h> 18 19#include "com_android_nfc.h" 20 21static phNfc_sData_t *com_android_nfc_jni_transceive_buffer; 22static phNfc_sData_t *com_android_nfc_jni_ioctl_buffer; 23static phNfc_sRemoteDevInformation_t* SecureElementInfo; 24static int secureElementHandle; 25extern void *gHWRef; 26static int SecureElementTech; 27extern uint8_t device_connected_flag; 28 29namespace android { 30 31static void com_android_nfc_jni_ioctl_callback ( void* pContext, 32 phNfc_sData_t* Outparam_Cb, 33 NFCSTATUS status) 34{ 35 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 36 37 if (status == NFCSTATUS_SUCCESS ) 38 { 39 LOG_CALLBACK("> IOCTL successful",status); 40 } 41 else 42 { 43 LOG_CALLBACK("> IOCTL error",status); 44 } 45 46 com_android_nfc_jni_ioctl_buffer = Outparam_Cb; 47 pContextData->status = status; 48 sem_post(&pContextData->sem); 49} 50 51static void com_android_nfc_jni_transceive_callback(void *pContext, 52 phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) 53{ 54 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 55 56 LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status); 57 58 com_android_nfc_jni_transceive_buffer = pResBuffer; 59 pContextData->status = status; 60 sem_post(&pContextData->sem); 61} 62 63 64static void com_android_nfc_jni_connect_callback(void *pContext, 65 phLibNfc_Handle hRemoteDev, 66 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) 67{ 68 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 69 70 LOG_CALLBACK("com_android_nfc_jni_connect_callback", status); 71 72 pContextData->status = status; 73 sem_post(&pContextData->sem); 74} 75 76static void com_android_nfc_jni_disconnect_callback(void *pContext, 77 phLibNfc_Handle hRemoteDev, 78 NFCSTATUS status) 79{ 80 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 81 82 LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status); 83 84 pContextData->status = status; 85 sem_post(&pContextData->sem); 86} 87 88/* Set Secure Element mode callback*/ 89static void com_android_nfc_jni_smartMX_setModeCb (void* pContext, 90 phLibNfc_Handle hSecureElement, 91 NFCSTATUS status) 92{ 93 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 94 95 if(status==NFCSTATUS_SUCCESS) 96 { 97 LOG_CALLBACK("SE Set Mode is Successful",status); 98 TRACE("SE Handle: %lu", hSecureElement); 99 } 100 else 101 { 102 LOG_CALLBACK("SE Set Mode is failed\n ",status); 103 } 104 105 pContextData->status = status; 106 sem_post(&pContextData->sem); 107} 108 109static void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext, 110 phLibNfc_RemoteDevList_t *psRemoteDevList, 111 uint8_t uNofRemoteDev, 112 NFCSTATUS status) 113{ 114 struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 115 NFCSTATUS ret; 116 int i; 117 JNIEnv *e = nfc_get_env(); 118 119 if(status == NFCSTATUS_DESELECTED) 120 { 121 LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status); 122 } 123 else 124 { 125 LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status); 126 TRACE("Discovered %d secure elements", uNofRemoteDev); 127 128 if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 129 { 130 bool foundHandle = false; 131 TRACE("Multiple Protocol supported\n"); 132 for (i=0; i<uNofRemoteDev; i++) { 133 // Always open the phNfc_eISO14443_A_PICC protocol 134 TRACE("Protocol %d handle=%x type=%d", i, psRemoteDevList[i].hTargetDev, 135 psRemoteDevList[i].psRemoteDevInfo->RemDevType); 136 if (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC) { 137 secureElementHandle = psRemoteDevList[i].hTargetDev; 138 foundHandle = true; 139 } 140 } 141 if (!foundHandle) { 142 ALOGE("Could not find ISO-DEP secure element"); 143 status = NFCSTATUS_FAILED; 144 goto clean_and_return; 145 } 146 } 147 else 148 { 149 secureElementHandle = psRemoteDevList->hTargetDev; 150 } 151 152 TRACE("Secure Element Handle: 0x%08x", secureElementHandle); 153 154 /* Set type name */ 155 jintArray techList; 156 nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, NULL, NULL); 157 158 // TODO: Should use the "connected" technology, for now use the first 159 if ((techList != NULL) && e->GetArrayLength(techList) > 0) { 160 e->GetIntArrayRegion(techList, 0, 1, &SecureElementTech); 161 TRACE("Store Secure Element Info\n"); 162 SecureElementInfo = psRemoteDevList->psRemoteDevInfo; 163 164 TRACE("Discovered secure element: tech=%d", SecureElementTech); 165 } 166 else { 167 ALOGE("Discovered secure element, but could not resolve tech"); 168 status = NFCSTATUS_FAILED; 169 } 170 171 // This thread may not return to the virtual machine for a long time 172 // so make sure to delete the local refernce to the tech list. 173 e->DeleteLocalRef(techList); 174 } 175 176clean_and_return: 177 pContextData->status = status; 178 sem_post(&pContextData->sem); 179} 180 181 182static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o) 183{ 184 NFCSTATUS ret; 185 int semResult; 186 187 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; 188 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; 189 phLibNfc_sADD_Cfg_t discovery_cfg; 190 phLibNfc_Registry_Info_t registry_info; 191 phNfc_sData_t InParam; 192 phNfc_sData_t OutParam; 193 uint8_t ExternalRFDetected[3] = {0x00, 0xFC, 0x01}; 194 uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; 195 uint8_t GpioSetValue[4]; 196 uint8_t gpioValue; 197 uint8_t Output_Buff[10]; 198 uint8_t reg_value; 199 uint8_t mask_value; 200 struct nfc_jni_callback_data cb_data; 201 struct nfc_jni_callback_data cb_data_SE_Notification; 202 203 /* Create the local semaphore */ 204 if (!nfc_cb_data_init(&cb_data, NULL)) 205 { 206 goto clean_and_return; 207 } 208 209 /* Create the local semaphore */ 210 if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL)) 211 { 212 goto clean_and_return; 213 } 214 215 /* Registery */ 216 registry_info.MifareUL = TRUE; 217 registry_info.MifareStd = TRUE; 218 registry_info.ISO14443_4A = TRUE; 219 registry_info.ISO14443_4B = TRUE; 220 registry_info.Jewel = TRUE; 221 registry_info.Felica = TRUE; 222 registry_info.NFC = FALSE; 223 224 CONCURRENCY_LOCK(); 225 226 TRACE("Open Secure Element"); 227 228 /* Check if NFC device is already connected to a tag or P2P peer */ 229 if (device_connected_flag == 1) 230 { 231 ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag"); 232 goto clean_and_return; 233 } 234 235 /* Test if External RF field is detected */ 236 InParam.buffer = ExternalRFDetected; 237 InParam.length = 3; 238 OutParam.buffer = Output_Buff; 239 TRACE("phLibNfc_Mgt_IoCtl()"); 240 REENTRANCE_LOCK(); 241 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 242 REENTRANCE_UNLOCK(); 243 if(ret!=NFCSTATUS_PENDING) 244 { 245 ALOGE("IOCTL status error"); 246 goto clean_and_return; 247 } 248 249 /* Wait for callback response */ 250 if(sem_wait(&cb_data.sem)) 251 { 252 ALOGE("IOCTL semaphore error"); 253 goto clean_and_return; 254 } 255 256 if(cb_data.status != NFCSTATUS_SUCCESS) 257 { 258 ALOGE("READ MEM ERROR"); 259 goto clean_and_return; 260 } 261 262 /* Check the value */ 263 reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0]; 264 mask_value = reg_value & 0x40; 265 266 if(mask_value == 0x40) 267 { 268 // There is an external RF field present, fail the open request 269 ALOGD("Unable to open SE connection, external RF Field detected"); 270 goto clean_and_return; 271 } 272 273 /* Get Secure Element List */ 274 TRACE("phLibNfc_SE_GetSecureElementList()"); 275 ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE); 276 if (ret == NFCSTATUS_SUCCESS) 277 { 278 TRACE("\n> Number of Secure Element(s) : %d\n", No_SE); 279 /* Display Secure Element information */ 280 for (i = 0; i<No_SE; i++) 281 { 282 if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) 283 { 284 TRACE("> SMX detected"); 285 TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement); 286 /* save SMARTMX index */ 287 SmartMX_detected = 1; 288 SmartMX_index = i; 289 } 290 } 291 292 if(SmartMX_detected) 293 { 294 REENTRANCE_LOCK(); 295 TRACE("phLibNfc_RemoteDev_NtfRegister()"); 296 ret = phLibNfc_RemoteDev_NtfRegister(®istry_info, 297 com_android_nfc_jni_open_secure_element_notification_callback, 298 (void *)&cb_data_SE_Notification); 299 REENTRANCE_UNLOCK(); 300 if(ret != NFCSTATUS_SUCCESS) 301 { 302 ALOGE("Register Notification error"); 303 goto clean_and_return; 304 } 305 306 /* Set wired mode */ 307 REENTRANCE_LOCK(); 308 TRACE("phLibNfc_SE_SetMode: Wired mode"); 309 ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement, 310 phLibNfc_SE_ActModeWired, 311 com_android_nfc_jni_smartMX_setModeCb, 312 (void *)&cb_data); 313 REENTRANCE_UNLOCK(); 314 if (ret != NFCSTATUS_PENDING ) 315 { 316 ALOGE("\n> SE Set SmartMX mode ERROR \n" ); 317 goto clean_and_return; 318 } 319 320 /* Wait for callback response */ 321 if(sem_wait(&cb_data.sem)) 322 { 323 ALOGE("Secure Element opening error"); 324 goto clean_and_return; 325 } 326 327 if(cb_data.status != NFCSTATUS_SUCCESS) 328 { 329 ALOGE("SE set mode failed"); 330 goto clean_and_return; 331 } 332 333 TRACE("Waiting for notification"); 334 /* Wait for callback response */ 335 if(sem_wait(&cb_data_SE_Notification.sem)) 336 { 337 ALOGE("Secure Element opening error"); 338 goto clean_and_return; 339 } 340 341 if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS && 342 cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS) 343 { 344 ALOGE("SE detection failed"); 345 goto clean_and_return; 346 } 347 CONCURRENCY_UNLOCK(); 348 349 /* Connect Tag */ 350 CONCURRENCY_LOCK(); 351 TRACE("phLibNfc_RemoteDev_Connect(SMX)"); 352 REENTRANCE_LOCK(); 353 ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data); 354 REENTRANCE_UNLOCK(); 355 if(ret != NFCSTATUS_PENDING) 356 { 357 ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 358 goto clean_and_return; 359 } 360 TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 361 362 /* Wait for callback response */ 363 if(sem_wait(&cb_data.sem)) 364 { 365 ALOGE("CONNECT semaphore error"); 366 goto clean_and_return; 367 } 368 369 /* Connect Status */ 370 if(cb_data.status != NFCSTATUS_SUCCESS) 371 { 372 ALOGE("Secure Element connect error"); 373 goto clean_and_return; 374 } 375 376 CONCURRENCY_UNLOCK(); 377 378 /* Get GPIO information */ 379 CONCURRENCY_LOCK(); 380 InParam.buffer = GpioGetValue; 381 InParam.length = 3; 382 OutParam.buffer = Output_Buff; 383 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); 384 REENTRANCE_LOCK(); 385 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 386 REENTRANCE_UNLOCK(); 387 if(ret!=NFCSTATUS_PENDING) 388 { 389 ALOGE("IOCTL status error"); 390 } 391 392 /* Wait for callback response */ 393 if(sem_wait(&cb_data.sem)) 394 { 395 ALOGE("IOCTL semaphore error"); 396 goto clean_and_return; 397 } 398 399 if(cb_data.status != NFCSTATUS_SUCCESS) 400 { 401 ALOGE("READ MEM ERROR"); 402 goto clean_and_return; 403 } 404 405 gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; 406 TRACE("GpioValue = Ox%02x",gpioValue); 407 408 /* Set GPIO information */ 409 GpioSetValue[0] = 0x00; 410 GpioSetValue[1] = 0xF8; 411 GpioSetValue[2] = 0x2B; 412 GpioSetValue[3] = (gpioValue | 0x40); 413 414 TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); 415 416 for(i=0;i<4;i++) 417 { 418 TRACE("0x%02x",GpioSetValue[i]); 419 } 420 421 InParam.buffer = GpioSetValue; 422 InParam.length = 4; 423 OutParam.buffer = Output_Buff; 424 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); 425 REENTRANCE_LOCK(); 426 ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 427 REENTRANCE_UNLOCK(); 428 if(ret!=NFCSTATUS_PENDING) 429 { 430 ALOGE("IOCTL status error"); 431 goto clean_and_return; 432 } 433 434 /* Wait for callback response */ 435 if(sem_wait(&cb_data.sem)) 436 { 437 ALOGE("IOCTL semaphore error"); 438 goto clean_and_return; 439 } 440 441 if(cb_data.status != NFCSTATUS_SUCCESS) 442 { 443 ALOGE("READ MEM ERROR"); 444 goto clean_and_return; 445 } 446 CONCURRENCY_UNLOCK(); 447 448 nfc_cb_data_deinit(&cb_data); 449 nfc_cb_data_deinit(&cb_data_SE_Notification); 450 451 /* Return the Handle of the SecureElement */ 452 return secureElementHandle; 453 } 454 else 455 { 456 ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected"); 457 goto clean_and_return; 458 } 459 } 460 else 461 { 462 ALOGE("phLibNfc_SE_GetSecureElementList(): Error"); 463 goto clean_and_return; 464 } 465 466clean_and_return: 467 nfc_cb_data_deinit(&cb_data); 468 nfc_cb_data_deinit(&cb_data_SE_Notification); 469 470 CONCURRENCY_UNLOCK(); 471 return 0; 472} 473 474 475static jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle) 476{ 477 jclass cls; 478 jfieldID f; 479 NFCSTATUS status; 480 jboolean result = JNI_FALSE; 481 phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; 482 uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; 483 uint32_t SmartMX_Handle; 484 struct nfc_jni_callback_data cb_data; 485 phNfc_sData_t InParam; 486 phNfc_sData_t OutParam; 487 uint8_t Output_Buff[10]; 488 uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; 489 uint8_t GpioSetValue[4]; 490 uint8_t gpioValue; 491 492 /* Create the local semaphore */ 493 if (!nfc_cb_data_init(&cb_data, NULL)) 494 { 495 goto clean_and_return; 496 } 497 498 TRACE("Close Secure element function "); 499 500 CONCURRENCY_LOCK(); 501 /* Disconnect */ 502 TRACE("Disconnecting from SMX (handle = 0x%x)", handle); 503 REENTRANCE_LOCK(); 504 status = phLibNfc_RemoteDev_Disconnect(handle, 505 NFC_SMARTMX_RELEASE, 506 com_android_nfc_jni_disconnect_callback, 507 (void *)&cb_data); 508 REENTRANCE_UNLOCK(); 509 if(status != NFCSTATUS_PENDING) 510 { 511 ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 512 goto clean_and_return; 513 } 514 TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 515 516 /* Wait for callback response */ 517 if(sem_wait(&cb_data.sem)) 518 { 519 goto clean_and_return; 520 } 521 522 /* Disconnect Status */ 523 if(cb_data.status != NFCSTATUS_SUCCESS) 524 { 525 ALOGE("\n> Disconnect SE ERROR \n" ); 526 goto clean_and_return; 527 } 528 CONCURRENCY_UNLOCK(); 529 530 /* Get GPIO information */ 531 CONCURRENCY_LOCK(); 532 InParam.buffer = GpioGetValue; 533 InParam.length = 3; 534 OutParam.buffer = Output_Buff; 535 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); 536 REENTRANCE_LOCK(); 537 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 538 REENTRANCE_UNLOCK(); 539 if(status!=NFCSTATUS_PENDING) 540 { 541 ALOGE("IOCTL status error"); 542 goto clean_and_return; 543 } 544 545 /* Wait for callback response */ 546 if(sem_wait(&cb_data.sem)) 547 { 548 ALOGE("IOCTL semaphore error"); 549 goto clean_and_return; 550 } 551 552 if(cb_data.status != NFCSTATUS_SUCCESS) 553 { 554 ALOGE("READ MEM ERROR"); 555 goto clean_and_return; 556 } 557 558 gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; 559 TRACE("GpioValue = Ox%02x",gpioValue); 560 561 /* Set GPIO information */ 562 GpioSetValue[0] = 0x00; 563 GpioSetValue[1] = 0xF8; 564 GpioSetValue[2] = 0x2B; 565 GpioSetValue[3] = (gpioValue & 0xBF); 566 567 TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); 568 569 for(i=0;i<4;i++) 570 { 571 TRACE("0x%02x",GpioSetValue[i]); 572 } 573 574 InParam.buffer = GpioSetValue; 575 InParam.length = 4; 576 OutParam.buffer = Output_Buff; 577 TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); 578 REENTRANCE_LOCK(); 579 status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 580 REENTRANCE_UNLOCK(); 581 if(status!=NFCSTATUS_PENDING) 582 { 583 ALOGE("IOCTL status error"); 584 goto clean_and_return; 585 } 586 587 /* Wait for callback response */ 588 if(sem_wait(&cb_data.sem)) 589 { 590 ALOGE("IOCTL semaphore error"); 591 goto clean_and_return; 592 } 593 594 if(cb_data.status != NFCSTATUS_SUCCESS) 595 { 596 ALOGE("READ MEM ERROR"); 597 goto clean_and_return; 598 } 599 600 result = JNI_TRUE; 601 602clean_and_return: 603 nfc_cb_data_deinit(&cb_data); 604 605 CONCURRENCY_UNLOCK(); 606 return result; 607} 608 609static jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e, 610 jobject o,jint handle, jbyteArray data) 611{ 612 uint8_t offset = 0; 613 uint8_t *buf; 614 uint32_t buflen; 615 phLibNfc_sTransceiveInfo_t transceive_info; 616 jbyteArray result = NULL; 617 int res; 618 619 int tech = SecureElementTech; 620 NFCSTATUS status; 621 struct nfc_jni_callback_data cb_data; 622 623 /* Create the local semaphore */ 624 if (!nfc_cb_data_init(&cb_data, NULL)) 625 { 626 goto clean_and_return; 627 } 628 629 TRACE("Exchange APDU function "); 630 631 CONCURRENCY_LOCK(); 632 633 TRACE("Secure Element tech: %d\n", tech); 634 635 buf = (uint8_t *)e->GetByteArrayElements(data, NULL); 636 buflen = (uint32_t)e->GetArrayLength(data); 637 638 /* Prepare transceive info structure */ 639 if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL) 640 { 641 offset = 2; 642 transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; 643 transceive_info.addr = (uint8_t)buf[1]; 644 } 645 else if(tech == TARGET_TYPE_ISO14443_4) 646 { 647 transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; 648 transceive_info.addr = 0; 649 } 650 651 transceive_info.sSendData.buffer = buf + offset; 652 transceive_info.sSendData.length = buflen - offset; 653 transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); 654 transceive_info.sRecvData.length = 1024; 655 656 if(transceive_info.sRecvData.buffer == NULL) 657 { 658 goto clean_and_return; 659 } 660 661 TRACE("phLibNfc_RemoteDev_Transceive(SMX)"); 662 REENTRANCE_LOCK(); 663 status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, 664 com_android_nfc_jni_transceive_callback, (void *)&cb_data); 665 REENTRANCE_UNLOCK(); 666 if(status != NFCSTATUS_PENDING) 667 { 668 ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 669 goto clean_and_return; 670 } 671 TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 672 673 /* Wait for callback response */ 674 if(sem_wait(&cb_data.sem)) 675 { 676 ALOGE("TRANSCEIVE semaphore error"); 677 goto clean_and_return; 678 } 679 680 if(cb_data.status != NFCSTATUS_SUCCESS) 681 { 682 ALOGE("TRANSCEIVE error"); 683 goto clean_and_return; 684 } 685 686 /* Copy results back to Java */ 687 result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length); 688 if(result != NULL) 689 { 690 e->SetByteArrayRegion(result, 0, 691 com_android_nfc_jni_transceive_buffer->length, 692 (jbyte *)com_android_nfc_jni_transceive_buffer->buffer); 693 } 694 695clean_and_return: 696 nfc_cb_data_deinit(&cb_data); 697 698 if(transceive_info.sRecvData.buffer != NULL) 699 { 700 free(transceive_info.sRecvData.buffer); 701 } 702 703 e->ReleaseByteArrayElements(data, 704 (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); 705 706 CONCURRENCY_UNLOCK(); 707 708 return result; 709} 710 711static jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle) 712{ 713 TRACE("Get Secure element UID function "); 714 jbyteArray SecureElementUid; 715 716 if(handle == secureElementHandle) 717 { 718 SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength); 719 e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid); 720 return SecureElementUid; 721 } 722 else 723 { 724 return NULL; 725 } 726} 727 728static jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle) 729{ 730 jintArray techList; 731 TRACE("Get Secure element Type function "); 732 733 if(handle == secureElementHandle) 734 { 735 techList = e->NewIntArray(1); 736 e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech); 737 return techList; 738 } 739 else 740 { 741 return NULL; 742 } 743} 744 745 746/* 747 * JNI registration. 748 */ 749static JNINativeMethod gMethods[] = 750{ 751 {"doNativeOpenSecureElementConnection", "()I", 752 (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection}, 753 {"doNativeDisconnectSecureElementConnection", "(I)Z", 754 (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect}, 755 {"doTransceive", "(I[B)[B", 756 (void *)com_android_nfc_NativeNfcSecureElement_doTransceive}, 757 {"doGetUid", "(I)[B", 758 (void *)com_android_nfc_NativeNfcSecureElement_doGetUid}, 759 {"doGetTechList", "(I)[I", 760 (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList}, 761}; 762 763int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) 764{ 765 return jniRegisterNativeMethods(e, 766 "com/android/nfc/dhimpl/NativeNfcSecureElement", 767 gMethods, NELEM(gMethods)); 768} 769 770} // namespace android 771