com_android_nfc_NativeNfcSecureElement.cpp revision 0bd11735e8a28db1692f28abcc3e065abae0e8dd
10bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
20bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Copyright (C) 2010 The Android Open Source Project
30bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
40bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Licensed under the Apache License, Version 2.0 (the "License");
50bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * you may not use this file except in compliance with the License.
60bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * You may obtain a copy of the License at
70bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
80bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *      http://www.apache.org/licenses/LICENSE-2.0
90bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Unless required by applicable law or agreed to in writing, software
110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * distributed under the License is distributed on an "AS IS" BASIS,
120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * See the License for the specific language governing permissions and
140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * limitations under the License.
150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include <semaphore.h>
180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include "com_android_nfc.h"
200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic sem_t com_android_nfc_jni_secure_element_sem;
220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic NFCSTATUS com_android_nfc_jni_cb_status = NFCSTATUS_FAILED;
230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_transceive_buffer;
240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_ioctl_buffer;
250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sRemoteDevInformation_t* SecureElementInfo;
260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int secureElementHandle;
270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasextern void                 *gHWRef;
280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int SecureElementTech;
290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasnamespace android {
310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_ioctl_callback ( void*            context,
330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phNfc_sData_t*   Outparam_Cb,
340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            NFCSTATUS        status)
350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if (status == NFCSTATUS_SUCCESS )
370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas		LOGD("> IOCTL successful");
390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas		LOGD("> IOCTL error");
430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_cb_status = status;
450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_ioctl_buffer = Outparam_Cb;
460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_transceive_callback(void *pContext,
510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status);
540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_cb_status = status;
560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_transceive_buffer = pResBuffer;
570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_connect_callback(void *pContext,
630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_Handle hRemoteDev,
640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_connect_callback", status);
670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_cb_status = status;
690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_disconnect_callback(void *pContext,
740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               phLibNfc_Handle hRemoteDev,
750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               NFCSTATUS status)
760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status);
780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_cb_status = status;
800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* Set Secure Element mode callback*/
850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_smartMX_setModeCb (void*            pContext,
860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas							                                phLibNfc_Handle  hSecureElement,
870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                              NFCSTATUS        status)
880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if(status==NFCSTATUS_SUCCESS)
900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas		LOGD("SE Set Mode is Successful");
920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas		LOGD("SE Handle: %lu", hSecureElement);
930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    LOGD("SE Set Mode is failed\n ");
970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	com_android_nfc_jni_cb_status = status;
1000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
1020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext,
1050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     phLibNfc_RemoteDevList_t *psRemoteDevList,
1060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     uint8_t uNofRemoteDev,
1070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     NFCSTATUS status)
1080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   JNIEnv *e;
1100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int i;
1120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status == NFCSTATUS_DESELECTED)
1140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status);
1160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
1180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status);
1200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGI("Discovered %d tags", uNofRemoteDev);
1210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
1240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Multiple Protocol supported\n");
1250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Secure Element Handle: 0x%08x",psRemoteDevList[1].hTargetDev);
1270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         secureElementHandle = psRemoteDevList[1].hTargetDev;
1280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set type name */
1300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         SecureElementTech = get_technology_type(psRemoteDevList[1].psRemoteDevInfo->RemDevType,
1310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                        psRemoteDevList[1].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
1320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Store Secure Element Info\n");
1340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
1350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Discovered secure element: tech=%d", SecureElementTech);
1370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
1390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
1400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Secure Element Handle: 0x%08x",psRemoteDevList->hTargetDev);
1410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         secureElementHandle = psRemoteDevList->hTargetDev;
1420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set type name */
1440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         SecureElementTech = get_technology_type(psRemoteDevList->psRemoteDevInfo->RemDevType,
1450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                         psRemoteDevList->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
1460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Store Secure Element Info\n");
1480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
1490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Discovered secure element: tech=%d", SecureElementTech);
1510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_cb_status = status;
1550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_post(&com_android_nfc_jni_secure_element_sem);
1560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
1600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int semResult;
1630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
1650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
1660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sADD_Cfg_t discovery_cfg;
1670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Registry_Info_t registry_info;
1680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phNfc_sData_t			InParam;
1690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phNfc_sData_t			OutParam;
1700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
1710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t					Output_Buff[50];
1720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              reg_value;
1730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              mask_value;
1740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
1760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
1770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
1780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
1790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
1800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
1810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
1820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
1850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Open Secure Element");
1870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
1890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	InParam.buffer = ExternalRFDetected;
1900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	InParam.length = 3;
1910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	OutParam.buffer = Output_Buff;
1920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	LOGD("phLibNfc_Mgt_IoCtl()");
1930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)e);
1940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
1950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
1960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL status error");
1970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
1980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   semResult = sem_wait(&com_android_nfc_jni_secure_element_sem);
1990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (semResult)
2000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL semaphore error");
2020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS)
2060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("READ MEM ERROR");
2080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGD("External RF Field detected");
2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("phLibNfc_SE_GetSecureElementList()");
2230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGD("\n> Number of Secure Element(s) : %d\n", No_SE);
2270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           LOGD("> SMX detected");
2330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           LOGD("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
2390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
2430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("phLibNfc_RemoteDev_NtfRegister()");
2440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)e);
2450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
2470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGW("Register Notification error");
2490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
2540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("phLibNfc_SE_SetMode: Wired mode");
2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
2560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas									         phLibNfc_SE_ActModeWired,
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas									         com_android_nfc_jni_smartMX_setModeCb,
2580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas									         (void*)e);
2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
2610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGD("\n> SE Set SmartMX mode ERROR \n" );
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         semResult = sem_wait(&com_android_nfc_jni_secure_element_sem);
2670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (semResult)
2680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGW("Secure Element opening error");
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS)
2740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE set mode failed");
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("Waiting for notification");
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         semResult = sem_wait(&com_android_nfc_jni_secure_element_sem);
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (semResult)
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGW("Secure Element opening error");
2840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS && com_android_nfc_jni_cb_status != NFCSTATUS_MULTIPLE_PROTOCOLS)
2880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE detection failed");
2900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
2930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
2950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
2960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("phLibNfc_RemoteDev_Connect(SMX)");
2970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
2980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)e);
2990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
3050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
3080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         sem_wait(&com_android_nfc_jni_secure_element_sem);
3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
3110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS)
3120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
3170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Return the Handle of the SecureElement */
3180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
3190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
3200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
3210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         LOGD("phLibNfc_SE_GetSecureElementList(): No SMX detected");
3230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
3240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
3250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
3260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
3270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
3280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGD("phLibNfc_SE_GetSecureElementList(): Error");
3290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
3310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
3330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
3340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return 0;
3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
3360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
3390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
3400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
3410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
3420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
3430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
3440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
3450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
3460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
3470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Close Secure element function ");
3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
3510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
3520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGI("Disconnecting from SMX (handle = 0x%x)", handle);
3530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
3540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
3550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
3560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
3570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          (void *)e);
3580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
3590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
3600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
3610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
3620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
3630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
3640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
3650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
3670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_wait(&com_android_nfc_jni_secure_element_sem);
3680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
3700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS)
3710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
3720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas     LOGE("\n> Disconnect SE ERROR \n" );
3730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
3740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
3750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
3770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
3790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
3800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
3810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
3820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
3840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
3850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
3860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
3870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
3880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
3890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
3900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
3910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
3920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
3940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
3950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Exchange APDU function ");
3970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
3980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
3990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Secure Element tech: %d\n", tech);
4010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
4030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
4040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
4060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
4070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
4090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
4100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
4110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
4130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
4150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
4160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
4190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
4200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
4210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
4220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
4240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("phLibNfc_RemoteDev_Transceive(SMX)");
4290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
4300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
4310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas		   com_android_nfc_jni_transceive_callback, (void *)e);
4320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
4330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
4340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
4410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   sem_wait(&com_android_nfc_jni_secure_element_sem);
4420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(com_android_nfc_jni_cb_status != NFCSTATUS_SUCCESS)
4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
4490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
4500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
4510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
4550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
4610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
4670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
4690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
4720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Get Secure element UID function ");
4740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
4750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
4770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
4790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
4800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
4810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
4830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
4850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
4890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
4910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOGD("Get Secure element Type function ");
4920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
4940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      techList = e->NewIntArray(1);
4960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
4970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return techList;
4980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
5000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
5010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
5020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
5030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
5070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
5080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
5100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
5110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doOpenSecureElementConnection", "()I",
5120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
5130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doDisconnect", "(I)Z",
5140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
5150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
5160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
5170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
5180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
5190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
5200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
5210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
5220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
5240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
5250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(sem_init(&com_android_nfc_jni_secure_element_sem, 0, 0) == -1)
5260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return -1;
5270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
5290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      "com/android/nfc/NativeNfcSecureElement",
5300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
5310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
534