com_android_nfc_NativeNfcSecureElement.cpp revision a8d8c1fa5058573c0d9d1305549c4326737db0b8
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 phNfc_sData_t *com_android_nfc_jni_transceive_buffer;
220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_ioctl_buffer;
230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sRemoteDevInformation_t* SecureElementInfo;
240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int secureElementHandle;
250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasextern void                 *gHWRef;
260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int SecureElementTech;
270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasnamespace android {
290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
30ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomasstatic void com_android_nfc_jni_ioctl_callback ( void*            pContext,
310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phNfc_sData_t*   Outparam_Cb,
320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            NFCSTATUS        status)
330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
34ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
35ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if (status == NFCSTATUS_SUCCESS )
370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
38c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL successful",status);
390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
42c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL error",status);
430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
45ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   com_android_nfc_jni_ioctl_buffer = Outparam_Cb;
46ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
47ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->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{
53ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
54ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status);
560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_transceive_buffer = pResBuffer;
58ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
59ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_connect_callback(void *pContext,
640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_Handle hRemoteDev,
650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
67ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
69ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   LOG_CALLBACK("com_android_nfc_jni_connect_callback", status);
700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
71ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
72ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_disconnect_callback(void *pContext,
760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               phLibNfc_Handle hRemoteDev,
770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               NFCSTATUS status)
780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
79ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
80ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status);
820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
83ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
84ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* Set Secure Element mode callback*/
880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_smartMX_setModeCb (void*            pContext,
890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas							                                phLibNfc_Handle  hSecureElement,
900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                              NFCSTATUS        status)
910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
92ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
93ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if(status==NFCSTATUS_SUCCESS)
950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
96c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is Successful",status);
97c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    TRACE("SE Handle: %lu", hSecureElement);
980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
1000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
101c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is failed\n ",status);
1020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
1030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
104ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
105ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext,
1090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     phLibNfc_RemoteDevList_t *psRemoteDevList,
1100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     uint8_t uNofRemoteDev,
1110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     NFCSTATUS status)
1120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
113ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int i;
1160412f53e664083dc5307bbcf18c0002b26180203Nick Pelly   JNIEnv *e = nfc_get_env();
1170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status == NFCSTATUS_DESELECTED)
1190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status);
1210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
1230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status);
125a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      TRACE("Discovered %d secure elements", uNofRemoteDev);
1260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
129c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Multiple Protocol supported\n");
130a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         secureElementHandle = psRemoteDevList[1].hTargetDev;
1310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
1330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
134a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         secureElementHandle = psRemoteDevList->hTargetDev;
1350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
136a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
137a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      TRACE("Secure Element Handle: 0x%08x", secureElementHandle);
138a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
139a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      /* Set type name */
140a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      jintArray techList;
141a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      jintArray handleList;
142a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      jintArray typeList;
143a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList,
144a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton            &handleList, &typeList);
145a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
146a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      // TODO: Should use the "connected" technology, for now use the first
147a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      if ((techList != NULL) && e->GetArrayLength(techList) > 0) {
148a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         jint* technologies = e->GetIntArrayElements(techList, 0);
149a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         SecureElementTech = technologies[0];
150a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         e->ReleaseIntArrayElements(techList, technologies, JNI_ABORT);
151a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         TRACE("Store Secure Element Info\n");
152a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
153a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
154a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         TRACE("Discovered secure element: tech=%d", SecureElementTech);
155a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      }
156a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      else {
157a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         LOGE("Discovered secure element, but could not resolve tech");
158a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         status = NFCSTATUS_FAILED;
159a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      }
1600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
162ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
163ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
1680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int semResult;
1710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
1730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
1740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sADD_Cfg_t discovery_cfg;
1750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Registry_Info_t registry_info;
176c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        InParam;
177c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        OutParam;
1780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
179c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioGetValue[3] = {0x00, 0xF8, 0x2B};
180c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioSetValue[4];
181c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              gpioValue;
182c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              Output_Buff[10];
1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              reg_value;
1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              mask_value;
185ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
186c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
187ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
188ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
189ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
190ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
191ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
192ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
1930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
1940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
1950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
1960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
1970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
1980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
1990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
2000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
2010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
2030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
204c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Open Secure Element");
2050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
207c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = ExternalRFDetected;
208c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
209c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
210c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()");
211c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
212ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
213c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
2140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
215c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL status error");
217c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
218ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
219ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Wait for callback response */
220ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL semaphore error");
2230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
226ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
2270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("READ MEM ERROR");
2290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
231c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
238c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("External RF Field detected");
2390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
241c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
243c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_SE_GetSecureElementList()");
2440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
247c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
2480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
253c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> SMX detected");
254c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
260c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
264c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_NtfRegister()");
265ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)&cb_data);
2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
2680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
269c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Register Notification error");
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
272c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
2740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
275c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_SE_SetMode: Wired mode");
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
277c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     phLibNfc_SE_ActModeWired,
278c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     com_android_nfc_jni_smartMX_setModeCb,
279c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     (void *)&cb_data);
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
283c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("\n> SE Set SmartMX mode ERROR \n" );
2840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
286c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
287ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
288ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
2890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
290c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
293c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
294ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
2950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
2960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE set mode failed");
2970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
299c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
300c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Waiting for notification");
301ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
302ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
304c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
3050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
307c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
308ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE detection failed");
3110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
312ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
314c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
3160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
317c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX)");
3180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
319ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
3200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
326c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
327c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
329ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
330ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         {
331c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("CONNECT semaphore error");
332ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas             goto clean_and_return;
333ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
334c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
336ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
338c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element connect error");
339c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
340c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
341c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
342c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_UNLOCK();
343c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
344c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Get GPIO information */
345c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_LOCK();
346c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioGetValue;
347c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 3;
348c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
349c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
350c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
351c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
352c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
353c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
354c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
355c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
356c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
357c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
358c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
359c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
360c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
361c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
362c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
363c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
364c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
365c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
366c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
367c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
368c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
369c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
370c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
371c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
372c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue = Ox%02x",gpioValue);
373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Set GPIO information */
375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[0] = 0x00;
376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[1] = 0xF8;
377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[2] = 0x2B;
378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[3] = (gpioValue | 0x40);
379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         for(i=0;i<4;i++)
383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("0x%02x",GpioSetValue[i]);
385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioSetValue;
388c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 4;
389c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
394c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
395c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             goto clean_and_return;
398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
400c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
401c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
4100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
4110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
4120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
4130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Return the Handle of the SecureElement */
4140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
4150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
4170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         LOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
4190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
4200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
4230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("phLibNfc_SE_GetSecureElementList(): Error");
4250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
4300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return 0;
4310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
4350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
4370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
4380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
4390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
4400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
4410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
4420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
443ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
444c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    InParam;
445c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    OutParam;
446c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          Output_Buff[10];
447c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioGetValue[3] = {0x00, 0xF8, 0x2B};
448c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioSetValue[4];
449c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          gpioValue;
450ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
451ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
452ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
453ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
454ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
455ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
4560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
457c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Close Secure element function ");
458c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
461c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
4620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
466ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas                                          (void *)&cb_data);
4670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
4680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
4690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
473c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
476ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
477ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
478ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
479ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
480c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
4810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
482ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
4830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas     LOGE("\n> Disconnect SE ERROR \n" );
4850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
487c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_UNLOCK();
488c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
489c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Get GPIO information */
490c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_LOCK();
491c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioGetValue;
492c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
493c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
494c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
495c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
496c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
497c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
498c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
499c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
500c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
501c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
502c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
503c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
504c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
505c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
506c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
507c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
508c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
509c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
510c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
511c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
512c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
513c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
514c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
515c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
516c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
517c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
518c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue = Ox%02x",gpioValue);
519c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
520c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Set GPIO information */
521c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[0] = 0x00;
522c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[1] = 0xF8;
523c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[2] = 0x2B;
524c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[3] = (gpioValue & 0xBF);
525c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
526c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
527c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   for(i=0;i<4;i++)
529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       TRACE("0x%02x",GpioSetValue[i]);
531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioSetValue;
534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 4;
535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
540c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
541c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
547c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
548c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
553c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
554c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
5600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
5620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
5630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
5640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
5670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
5680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
5690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
5700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
5710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
5720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
5730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
5740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
5750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
5770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
578ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
579ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
580ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
581ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
582ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
583ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
584ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
5850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
586c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Exchange APDU function ");
5870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
5890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
590c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Secure Element tech: %d\n", tech);
5910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
5930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
5940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
5960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
5970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
5980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
5990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
6030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
6050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
6060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
6090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
6100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
6110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
6120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
6140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
618c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
6200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
621ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas		   com_android_nfc_jni_transceive_callback, (void *)&cb_data);
6220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
6230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
6240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
628c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
631ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
632ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
633c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("TRANSCEIVE semaphore error");
634ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
635ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
637ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
639c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("TRANSCEIVE error");
6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
6450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
6480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
6590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
6600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
6620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
6640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
6670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
668c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element UID function ");
6690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
6700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
6740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
6750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
6760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
6780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
6800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
686c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element Type function ");
6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      techList = e->NewIntArray(1);
6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
6920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return techList;
6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
6950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
6970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doOpenSecureElementConnection", "()I",
7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doDisconnect", "(I)Z",
7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
7100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
7120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
7130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
7160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      "com/android/nfc/NativeNfcSecureElement",
7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
726