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 */
1552534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes      ScopedLocalRef<jintArray> techList(e, NULL);
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
1592534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes      if ((techList.get() != NULL) && e->GetArrayLength(techList.get()) > 0) {
1602534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes         e->GetIntArrayRegion(techList.get(), 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      }
1700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
171a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly
172a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pellyclean_and_return:
173ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
174ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
1790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int semResult;
182c3981b9a0b39faed474480bc3dbd3e33bbd50b99Martijn Coenen   jint errorCode = EE_ERROR_INIT;
1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
1850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
1860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sADD_Cfg_t discovery_cfg;
1870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Registry_Info_t registry_info;
188c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        InParam;
189c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        OutParam;
1900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
191c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioGetValue[3] = {0x00, 0xF8, 0x2B};
192c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioSetValue[4];
193c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              gpioValue;
194c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              Output_Buff[10];
1950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              reg_value;
1960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              mask_value;
197ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
1988e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   struct nfc_jni_callback_data cb_data_SE_Notification;
199c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
200ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
201ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
202ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
203ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
204ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
205ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
2068e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   /* Create the local semaphore */
2078e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL))
2088e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   {
2098e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas      goto clean_and_return;
2108e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   }
2118e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
2120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
2130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
2140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
2150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
2190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
223c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Open Secure Element");
2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
22504a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   /* Check if NFC device is already connected to a tag or P2P peer */
22604a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   if (device_connected_flag == 1)
22704a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   {
228c3981b9a0b39faed474480bc3dbd3e33bbd50b99Martijn Coenen       ALOGE("Unable to open SE connection, device already connected to a P2P peer or a Tag");
229c3981b9a0b39faed474480bc3dbd3e33bbd50b99Martijn Coenen       errorCode = EE_ERROR_LISTEN_MODE;
23004a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas       goto clean_and_return;
23104a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas   }
23204a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas
2330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
234c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = ExternalRFDetected;
235c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
236c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
237c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()");
238c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
239ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
240c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
2410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
242c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
243afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL status error");
24404a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas      goto clean_and_return;
245c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
246ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
247ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Wait for callback response */
248ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
2490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
250afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
254ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
256afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
259c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
266275376f9e469a9e014d82978ba3b8d57fe4a7739Jeff Hamilton      // There is an external RF field present, fail the open request
2677d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Unable to open SE connection, external RF Field detected");
268c3981b9a0b39faed474480bc3dbd3e33bbd50b99Martijn Coenen      errorCode = EE_ERROR_EXT_FIELD;
2690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
271c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
273c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_SE_GetSecureElementList()");
2740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
277c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
2780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
283c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> SMX detected");
284c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
290c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
294c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_NtfRegister()");
2958e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info,
2968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 com_android_nfc_jni_open_secure_element_notification_callback,
2978e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 (void *)&cb_data_SE_Notification);
2980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
301afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Register Notification error");
3020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
304c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
307c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_SE_SetMode: Wired mode");
3080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
309c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     phLibNfc_SE_ActModeWired,
310c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     com_android_nfc_jni_smartMX_setModeCb,
311c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     (void *)&cb_data);
3120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
3140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
315afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("\n> SE Set SmartMX mode ERROR \n" );
3160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
318c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
319ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
320ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
322afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element opening error");
3230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
325c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
326ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
328afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("SE set mode failed");
3290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
331c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
332c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Waiting for notification");
333ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
3348e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         if(sem_wait(&cb_data_SE_Notification.sem))
3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
336afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element opening error");
3370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
339c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3408e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS &&
3418e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas                 cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
3420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
343afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("SE detection failed");
3440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
345ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
3460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
347c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
350c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX)");
3510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
352ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
3530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
356afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
359c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
360c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
362ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
363ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         {
364afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("CONNECT semaphore error");
365ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas             goto clean_and_return;
366ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
367c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
369ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
371afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("Secure Element connect error");
372c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_UNLOCK();
376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Get GPIO information */
378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_LOCK();
379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioGetValue;
380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 3;
381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
388afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("IOCTL status error");
389c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
394afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("IOCTL semaphore error");
395c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
400afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("READ MEM ERROR");
401c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue = Ox%02x",gpioValue);
406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Set GPIO information */
408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[0] = 0x00;
409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[1] = 0xF8;
410c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[2] = 0x2B;
411c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[3] = (gpioValue | 0x40);
412c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
413c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
414c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
415c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         for(i=0;i<4;i++)
416c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
417c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("0x%02x",GpioSetValue[i]);
418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
419c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
420c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioSetValue;
421c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 4;
422c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
423c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
425c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
426c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
427c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
428c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
429afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block             ALOGE("IOCTL status error");
430c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             goto clean_and_return;
431c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
432c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
433c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
434c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
435c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
436afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("IOCTL semaphore error");
437c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
438c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
439c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
440c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
441c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
442afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block            ALOGE("READ MEM ERROR");
4430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
4468e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4478e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         nfc_cb_data_deinit(&cb_data);
4488e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         nfc_cb_data_deinit(&cb_data_SE_Notification);
4498e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4508e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas         /* Return the Handle of the SecureElement */
4510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
4520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
455afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
4560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
461afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_SE_GetSecureElementList(): Error");
4620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4668e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
4678e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data_SE_Notification);
4688e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
4690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
470c3981b9a0b39faed474480bc3dbd3e33bbd50b99Martijn Coenen   return errorCode;
4710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
4750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
4770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
4780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
4790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
4800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
4810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
4820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
483ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
484c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    InParam;
485c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    OutParam;
486c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          Output_Buff[10];
487c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioGetValue[3] = {0x00, 0xF8, 0x2B};
488c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioSetValue[4];
489c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          gpioValue;
490ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
491ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
492ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
493ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
494ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
495ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
4960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
497c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Close Secure element function ");
498c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
4990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
5000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
501c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
5020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
5030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
5040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
5050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
506ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas                                          (void *)&cb_data);
5070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
5080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
510afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
5110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
513c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
5140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
516ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
517ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
518ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
519ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
520c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
522ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
5230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
524afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block     ALOGE("\n> Disconnect SE ERROR \n" );
5250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
527c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_UNLOCK();
528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Get GPIO information */
530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_LOCK();
531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioGetValue;
532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
540afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("IOCTL status error");
541c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
547afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
548c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
553afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
554c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue = Ox%02x",gpioValue);
559c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
560c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Set GPIO information */
561c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[0] = 0x00;
562c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[1] = 0xF8;
563c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[2] = 0x2B;
564c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[3] = (gpioValue & 0xBF);
565c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
566c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
567c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
568c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   for(i=0;i<4;i++)
569c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
570c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       TRACE("0x%02x",GpioSetValue[i]);
571c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
572c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
573c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioSetValue;
574c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 4;
575c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
576c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
577c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
578c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
579c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
580c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
581c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
582afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("IOCTL status error");
583c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
584c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
585c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
586c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
587c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
588c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
589afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("IOCTL semaphore error");
590c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
591c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
592c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
593c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
594c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
595afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("READ MEM ERROR");
596c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
597c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
598c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6028e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
6038e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
6040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
6050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
6060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
6090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
6100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
6110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
6120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
6130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
6140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
6160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
620ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
621ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
622ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
623ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
624ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
625ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
626ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
628c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Exchange APDU function ");
6290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
6310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
632c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Secure Element tech: %d\n", tech);
6330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
6350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
6390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
6420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
6450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
6480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
6510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
6520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
660c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
6610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
6620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
663ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas		   com_android_nfc_jni_transceive_callback, (void *)&cb_data);
6640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
6650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
667afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
670c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
673ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
674ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
675afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block       ALOGE("TRANSCEIVE semaphore error");
676ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
677ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
679ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
6800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
681afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("TRANSCEIVE error");
6820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
6860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
6920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6958e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas   nfc_cb_data_deinit(&cb_data);
6968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas
6970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
6980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
712c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element UID function ");
7130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
7280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
730c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element Type function ");
7310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7322534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   if (handle != secureElementHandle) {
7330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7352534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jintArray result = e->NewIntArray(1);
7362534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   e->SetIntArrayRegion(result, 0, 1, &SecureElementTech);
7372534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   return result;
7380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
7420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
7430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
7440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
7450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
74637058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi   {"doNativeOpenSecureElementConnection", "()I",
7470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
74837058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi   {"doNativeDisconnectSecureElementConnection", "(I)Z",
7490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
7500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
7510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
7520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
7530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
7540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
7550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
7560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
7570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
7590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
761642ab20c81425ba93e206d2a30602cd67ae8bd38Martijn Coenen      "com/android/nfc/dhimpl/NativeNfcSecureElement",
7620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
7630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
766