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