com_android_nfc_NativeNfcSecureElement.cpp revision 7d4e962f71c5db6d71aca046bd1416f53a10653b
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;
2704a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomasextern uint8_t device_connected_flag;
280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasnamespace android {
300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
31ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomasstatic void com_android_nfc_jni_ioctl_callback ( void*            pContext,
320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phNfc_sData_t*   Outparam_Cb,
330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            NFCSTATUS        status)
340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
35ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
36ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if (status == NFCSTATUS_SUCCESS )
380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
39c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL successful",status);
400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
43c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL error",status);
440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
46ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   com_android_nfc_jni_ioctl_buffer = Outparam_Cb;
47ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
48ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_transceive_callback(void *pContext,
520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
54ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
55ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status);
570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_transceive_buffer = pResBuffer;
59ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
60ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_connect_callback(void *pContext,
650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_Handle hRemoteDev,
660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
68ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
70ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   LOG_CALLBACK("com_android_nfc_jni_connect_callback", status);
710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
72ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
73ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_disconnect_callback(void *pContext,
770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               phLibNfc_Handle hRemoteDev,
780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               NFCSTATUS status)
790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
80ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
81ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status);
830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
84ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
85ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* Set Secure Element mode callback*/
890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_smartMX_setModeCb (void*            pContext,
900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas							                                phLibNfc_Handle  hSecureElement,
910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                              NFCSTATUS        status)
920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
93ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
94ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if(status==NFCSTATUS_SUCCESS)
960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
97c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is Successful",status);
98c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    TRACE("SE Handle: %lu", hSecureElement);
990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
1000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
1010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
102c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is failed\n ",status);
1030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
1040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
105ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
106ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext,
1100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     phLibNfc_RemoteDevList_t *psRemoteDevList,
1110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     uint8_t uNofRemoteDev,
1120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     NFCSTATUS status)
1130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
114ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int i;
1170412f53e664083dc5307bbcf18c0002b26180203Nick Pelly   JNIEnv *e = nfc_get_env();
1180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status == NFCSTATUS_DESELECTED)
1200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status);
1220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
1240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status);
126a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      TRACE("Discovered %d secure elements", uNofRemoteDev);
1270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
130a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly         bool foundHandle = false;
131c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Multiple Protocol supported\n");
132a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly         for (i=0; i<uNofRemoteDev; i++) {
133a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             // Always open the phNfc_eISO14443_A_PICC protocol
134a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             TRACE("Protocol %d handle=%x type=%d", i, psRemoteDevList[i].hTargetDev,
135a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly                     psRemoteDevList[i].psRemoteDevInfo->RemDevType);
136a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             if (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC) {
137a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly                 secureElementHandle = psRemoteDevList[i].hTargetDev;
138a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly                 foundHandle = true;
139a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             }
140a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly         }
141a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly         if (!foundHandle) {
142a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             LOGE("Could not find ISO-DEP secure element");
143a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             status = NFCSTATUS_FAILED;
144a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly             goto clean_and_return;
145a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly         }
1460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
1480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
149a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         secureElementHandle = psRemoteDevList->hTargetDev;
1500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
151a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
152a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      TRACE("Secure Element Handle: 0x%08x", secureElementHandle);
153a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
154a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      /* Set type name */
155a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      jintArray techList;
1566a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton      nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, NULL, NULL);
157a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
158a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      // TODO: Should use the "connected" technology, for now use the first
159a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      if ((techList != NULL) && e->GetArrayLength(techList) > 0) {
16084f234a73bb3e149ce8c7ff768bd467fdeac27bfJeff Hamilton         e->GetIntArrayRegion(techList, 0, 1, &SecureElementTech);
161a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         TRACE("Store Secure Element Info\n");
162a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
163a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton
164a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         TRACE("Discovered secure element: tech=%d", SecureElementTech);
165a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      }
166a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      else {
167a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         LOGE("Discovered secure element, but could not resolve tech");
168a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton         status = NFCSTATUS_FAILED;
169a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton      }
1706a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton
1716a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton      // This thread may not return to the virtual machine for a long time
1726a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton      // so make sure to delete the local refernce to the tech list.
17384f234a73bb3e149ce8c7ff768bd467fdeac27bfJeff Hamilton      e->DeleteLocalRef(techList);
1740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
175a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly
176a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pellyclean_and_return:
177ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
178ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int semResult;
1860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
1880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
1890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sADD_Cfg_t discovery_cfg;
1900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Registry_Info_t registry_info;
191c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        InParam;
192c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        OutParam;
1930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
194c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioGetValue[3] = {0x00, 0xF8, 0x2B};
195c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioSetValue[4];
196c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              gpioValue;
197c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              Output_Buff[10];
1980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              reg_value;
1990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              mask_value;
200ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
201c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
202ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
203ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
204ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
205ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
206ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
207ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
2080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
2090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
2100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
2110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
2120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
2130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
2140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
2150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
219c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Open Secure Element");
2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
22104a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   /* Check if NFC device is already connected to a tag or P2P peer */
22204a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   if (device_connected_flag == 1)
22304a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   {
2247d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block       ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag");
22504a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas       goto clean_and_return;
22604a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   }
22704a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas
2280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
229c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = ExternalRFDetected;
230c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
231c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
232c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()");
233c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
234ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
235c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
2360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
237c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
2380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL status error");
23904a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas      goto clean_and_return;
240c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
241ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
242ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Wait for callback response */
243ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
2440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL semaphore error");
2460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
249ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
2500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("READ MEM ERROR");
2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
254c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
261275376f9e469a9e014d82978ba3b8d57fe4a7739Jeff Hamilton      // There is an external RF field present, fail the open request
2627d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Unable to open SE connection, external RF Field detected");
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
265c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
267c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_SE_GetSecureElementList()");
2680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
271c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
2720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
277c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> SMX detected");
278c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
284c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
288c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_NtfRegister()");
289ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)&cb_data);
2900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
293c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Register Notification error");
2940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
296c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
2980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
299c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_SE_SetMode: Wired mode");
3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
301c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     phLibNfc_SE_ActModeWired,
302c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     com_android_nfc_jni_smartMX_setModeCb,
303c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     (void *)&cb_data);
3040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
307c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("\n> SE Set SmartMX mode ERROR \n" );
3080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
310c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
311ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
312ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
314c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
317c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
318ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE set mode failed");
3210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
323c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
324c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Waiting for notification");
325ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
326ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
328c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
3290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
331c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
332ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
3330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE detection failed");
3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
336ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
3370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
338c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
3400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
341c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX)");
3420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
343ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
3440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
350c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
351c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
353ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
354ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         {
355c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("CONNECT semaphore error");
356ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas             goto clean_and_return;
357ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
358c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
360ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
362c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element connect error");
363c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
364c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
365c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
366c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_UNLOCK();
367c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
368c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Get GPIO information */
369c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_LOCK();
370c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioGetValue;
371c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 3;
372c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
388c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
389c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
394c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
395c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue = Ox%02x",gpioValue);
397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Set GPIO information */
399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[0] = 0x00;
400c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[1] = 0xF8;
401c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[2] = 0x2B;
402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[3] = (gpioValue | 0x40);
403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         for(i=0;i<4;i++)
407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("0x%02x",GpioSetValue[i]);
409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
410c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
411c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioSetValue;
412c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 4;
413c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
414c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
415c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
416c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
417c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
419c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
420c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
421c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             goto clean_and_return;
422c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
423c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
425c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
426c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
427c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
428c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
429c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
430c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
431c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
432c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
433c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
4340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
4350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
4360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
4370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Return the Handle of the SecureElement */
4380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
4390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
4410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
442c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         LOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
4430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
4470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
448c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("phLibNfc_SE_GetSecureElementList(): Error");
4490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return 0;
4550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
4610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
4620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
467ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
468c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    InParam;
469c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    OutParam;
470c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          Output_Buff[10];
471c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioGetValue[3] = {0x00, 0xF8, 0x2B};
472c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioSetValue[4];
473c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          gpioValue;
474ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
475ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
476ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
477ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
478ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
479ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
4800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
481c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Close Secure element function ");
482c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
4830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
4840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
485c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
4860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
4870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
4880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
4890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
490ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas                                          (void *)&cb_data);
4910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
4920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
4930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
497c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
500ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
501ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
502ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
503ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
504c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
506ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
5070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
5080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas     LOGE("\n> Disconnect SE ERROR \n" );
5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
511c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_UNLOCK();
512c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
513c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Get GPIO information */
514c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_LOCK();
515c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioGetValue;
516c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
517c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
518c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
519c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
520c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
521c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
522c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
523c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
524c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
525c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
526c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
527c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
540c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
541c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue = Ox%02x",gpioValue);
543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Set GPIO information */
545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[0] = 0x00;
546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[1] = 0xF8;
547c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[2] = 0x2B;
548c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[3] = (gpioValue & 0xBF);
549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   for(i=0;i<4;i++)
553c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
554c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       TRACE("0x%02x",GpioSetValue[i]);
555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioSetValue;
558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 4;
559c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
560c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
561c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
562c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
563c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
564c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
565c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
566c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
567c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
568c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
569c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
570c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
571c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
572c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
573c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
574c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
575c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
576c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
577c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
578c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
579c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
580c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
581c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
582c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
5840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
5860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
5870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
5880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
5910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
5920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
5930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
5940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
5950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
5960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
5970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
5980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
5990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
602ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
603ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
604ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
605ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
606ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
607ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
608ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
610c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Exchange APDU function ");
6110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
6130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
614c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Secure Element tech: %d\n", tech);
6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
6180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
6200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
6210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
6230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
6240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
6250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
6270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
6290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
6330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
6340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
6350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
642c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
645ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas		   com_android_nfc_jni_transceive_callback, (void *)&cb_data);
6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
6480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
652c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
655ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
656ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
657c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("TRANSCEIVE semaphore error");
658ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
659ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
661ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
6620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
663c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("TRANSCEIVE error");
6640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
6680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
6690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
6700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
6730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
6740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
6780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
6800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
6860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
692c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element UID function ");
6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
6960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
6980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
710c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element Type function ");
7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      techList = e->NewIntArray(1);
7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
7160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return techList;
7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
7260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
7270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
7280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
7290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doOpenSecureElementConnection", "()I",
7310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
7320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doDisconnect", "(I)Z",
7330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
7340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
7350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
7360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
7370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
7380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
7390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
7400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
7410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
7430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
74581c476dd93f059d4082c15369894d5d16fbea05dJeff Hamilton      "com/android/nfc/nxp/NativeNfcSecureElement",
7460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
7470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
750