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) {
142afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("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 {
167afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("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;
2018e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   struct nfc_jni_callback_data cb_data_SE_Notification;
202c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
203ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
204ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
205ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
206ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
207ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
208ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
2098e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   /* Create the local semaphore */
2108e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL))
2118e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   {
2128e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas      goto clean_and_return;
2138e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   }
2148e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
2150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
2190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
2230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
2250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
226c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Open Secure Element");
2270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
22804a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   /* Check if NFC device is already connected to a tag or P2P peer */
22904a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   if (device_connected_flag == 1)
23004a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   {
2317d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block       ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag");
23204a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas       goto clean_and_return;
23304a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   }
23404a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas
2350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
236c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = ExternalRFDetected;
237c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
238c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
239c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()");
240c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
241ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
242c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
2430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
244c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
245afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL status error");
24604a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas      goto clean_and_return;
247c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
248ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
249ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Wait for callback response */
250ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
252afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
256ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
258afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
261c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
268275376f9e469a9e014d82978ba3b8d57fe4a7739Jeff Hamilton      // There is an external RF field present, fail the open request
2697d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Unable to open SE connection, external RF Field detected");
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
272c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
274c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_SE_GetSecureElementList()");
2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
278c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
284c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> SMX detected");
285c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
291c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
295c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_NtfRegister()");
2968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info,
2978e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 com_android_nfc_jni_open_secure_element_notification_callback,
2988e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 (void *)&cb_data_SE_Notification);
2990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
3010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
302afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Register Notification error");
3030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
305c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
3070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
308c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_SE_SetMode: Wired mode");
3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
310c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     phLibNfc_SE_ActModeWired,
311c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     com_android_nfc_jni_smartMX_setModeCb,
312c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     (void *)&cb_data);
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
316afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("\n> SE Set SmartMX mode ERROR \n" );
3170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
319c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
320ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
321ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
323afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element opening error");
3240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
326c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
327ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
329afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("SE set mode failed");
3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
332c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
333c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Waiting for notification");
334ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
3358e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         if(sem_wait(&cb_data_SE_Notification.sem))
3360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
337afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element opening error");
3380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
340c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3418e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS &&
3428e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
3430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
344afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("SE detection failed");
3450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
346ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
3470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
348c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
3500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
351c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX)");
3520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
353ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
3540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
357afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
360c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
361c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
363ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
364ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         {
365afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("CONNECT semaphore error");
366ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas             goto clean_and_return;
367ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
368c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
370ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
372afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element connect error");
373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_UNLOCK();
377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Get GPIO information */
379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_LOCK();
380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioGetValue;
381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 3;
382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
388c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
389afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("IOCTL status error");
390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
394c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
395afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("IOCTL semaphore error");
396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
400c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
401afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("READ MEM ERROR");
402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue = Ox%02x",gpioValue);
407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Set GPIO information */
409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[0] = 0x00;
410c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[1] = 0xF8;
411c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[2] = 0x2B;
412c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[3] = (gpioValue | 0x40);
413c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
414c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
415c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
416c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         for(i=0;i<4;i++)
417c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("0x%02x",GpioSetValue[i]);
419c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
420c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
421c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioSetValue;
422c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 4;
423c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
425c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
426c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
427c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
428c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
429c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
430afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("IOCTL status error");
431c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             goto clean_and_return;
432c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
433c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
434c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
435c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
436c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
437afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("IOCTL semaphore error");
438c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
439c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
440c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
441c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
442c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
443afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("READ MEM ERROR");
4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
4460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
4478e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4488e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         nfc_cb_data_deinit(&cb_data);
4498e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         nfc_cb_data_deinit(&cb_data_SE_Notification);
4508e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4518e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         /* Return the Handle of the SecureElement */
4520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
4550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
456afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
4610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
462afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_SE_GetSecureElementList(): Error");
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4678e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
4688e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data_SE_Notification);
4698e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
4710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return 0;
4720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
4760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
4780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
4790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
4800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
4810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
4820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
4830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
484ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
485c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    InParam;
486c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    OutParam;
487c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          Output_Buff[10];
488c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioGetValue[3] = {0x00, 0xF8, 0x2B};
489c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioSetValue[4];
490c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          gpioValue;
491ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
492ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
493ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
494ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
495ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
496ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
4970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
498c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Close Secure element function ");
499c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
5010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
502c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
5030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
5040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
5050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
5060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
507ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas                                          (void *)&cb_data);
5080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
5100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
511afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
5120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
514c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
5150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
517ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
518ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
519ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
520ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
521c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
523ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
5240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
525afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block     ALOGE("\n> Disconnect SE ERROR \n" );
5260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_UNLOCK();
529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Get GPIO information */
531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_LOCK();
532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioGetValue;
533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
540c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
541afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("IOCTL status error");
542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
547c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
548afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
553c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
554afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
559c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue = Ox%02x",gpioValue);
560c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
561c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Set GPIO information */
562c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[0] = 0x00;
563c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[1] = 0xF8;
564c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[2] = 0x2B;
565c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[3] = (gpioValue & 0xBF);
566c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
567c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
568c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
569c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   for(i=0;i<4;i++)
570c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
571c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       TRACE("0x%02x",GpioSetValue[i]);
572c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
573c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
574c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioSetValue;
575c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 4;
576c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
577c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
578c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
579c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
580c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
581c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
582c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
583afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("IOCTL status error");
584c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
585c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
586c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
587c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
588c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
589c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
590afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
591c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
592c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
593c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
594c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
595c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
596afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
597c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
598c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
599c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6038e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
6048e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
6050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
6060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
6070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
6100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
6110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
6120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
6130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
6140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
6160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
6180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
6200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
621ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
622ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
623ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
624ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
625ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
626ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
627ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
629c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Exchange APDU function ");
6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
6320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
633c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Secure Element tech: %d\n", tech);
6340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
6370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
6390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
6420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
6480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
6520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
6550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
661c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
6620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
6630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
664ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas		   com_android_nfc_jni_transceive_callback, (void *)&cb_data);
6650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
6670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
668afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
671c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
674ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
675ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
676afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("TRANSCEIVE semaphore error");
677ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
678ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
680ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
6810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
682afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("TRANSCEIVE error");
6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
6920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
6978e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
6980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
7120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
713c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element UID function ");
7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
7290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
731c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element Type function ");
7320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      techList = e->NewIntArray(1);
7360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
7370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return techList;
7380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
7470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
7480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
7490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
7500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
75137058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi   {"doNativeOpenSecureElementConnection", "()I",
7520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
75337058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi   {"doNativeDisconnectSecureElementConnection", "(I)Z",
7540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
7550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
7560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
7570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
7580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
7590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
7600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
7610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
7620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
7640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
766642ab20c81425ba93e206d2a30602cd67ae8bd38Martijn Coenen      "com/android/nfc/dhimpl/NativeNfcSecureElement",
7670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
7680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
771