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