com_android_nfc_NativeNfcSecureElement.cpp revision 0412f53e664083dc5307bbcf18c0002b26180203
10bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
20bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Copyright (C) 2010 The Android Open Source Project
30bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
40bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Licensed under the Apache License, Version 2.0 (the "License");
50bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * you may not use this file except in compliance with the License.
60bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * You may obtain a copy of the License at
70bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
80bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *      http://www.apache.org/licenses/LICENSE-2.0
90bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas *
100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Unless required by applicable law or agreed to in writing, software
110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * distributed under the License is distributed on an "AS IS" BASIS,
120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * See the License for the specific language governing permissions and
140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * limitations under the License.
150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include <semaphore.h>
180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include "com_android_nfc.h"
200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_transceive_buffer;
220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_ioctl_buffer;
230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sRemoteDevInformation_t* SecureElementInfo;
240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int secureElementHandle;
250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasextern void                 *gHWRef;
260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int SecureElementTech;
270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasnamespace android {
290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
30a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomasextern void nfc_jni_reset_timeout_values();
31a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas
32ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomasstatic void com_android_nfc_jni_ioctl_callback ( void*            pContext,
330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phNfc_sData_t*   Outparam_Cb,
340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            NFCSTATUS        status)
350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
36ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
37ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if (status == NFCSTATUS_SUCCESS )
390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
40c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL successful",status);
410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
44c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("> IOCTL error",status);
450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
47ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   com_android_nfc_jni_ioctl_buffer = Outparam_Cb;
48ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
49ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_transceive_callback(void *pContext,
530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
55ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
56ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status);
580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   com_android_nfc_jni_transceive_buffer = pResBuffer;
60ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
61ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_connect_callback(void *pContext,
660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_Handle hRemoteDev,
670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                            phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
69ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
71ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   LOG_CALLBACK("com_android_nfc_jni_connect_callback", status);
720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
73ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
74ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_disconnect_callback(void *pContext,
780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               phLibNfc_Handle hRemoteDev,
790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                               NFCSTATUS status)
800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
81ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
82ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status);
840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
85ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
86ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* Set Secure Element mode callback*/
900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_smartMX_setModeCb (void*            pContext,
910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas							                                phLibNfc_Handle  hSecureElement,
920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                              NFCSTATUS        status)
930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
94ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
95ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	if(status==NFCSTATUS_SUCCESS)
970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
98c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is Successful",status);
99c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    TRACE("SE Handle: %lu", hSecureElement);
1000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	}
1010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	else
1020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas	{
103c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas	    LOG_CALLBACK("SE Set Mode is failed\n ",status);
1040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
1050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
106ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
107ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext,
1110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     phLibNfc_RemoteDevList_t *psRemoteDevList,
1120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     uint8_t uNofRemoteDev,
1130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                                                     NFCSTATUS status)
1140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
115ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int i;
1180412f53e664083dc5307bbcf18c0002b26180203Nick Pelly   JNIEnv *e = nfc_get_env();
1190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status == NFCSTATUS_DESELECTED)
1210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status);
1230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
1250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
1260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status);
127c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("Discovered %d tags", uNofRemoteDev);
1280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
131c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Multiple Protocol supported\n");
1320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
133c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Secure Element Handle: 0x%08x",psRemoteDevList[1].hTargetDev);
1340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         secureElementHandle = psRemoteDevList[1].hTargetDev;
1350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set type name */
1374f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen         jintArray techList;
1384f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen         jintArray handleList;
1390a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen         jintArray typeList;
1400412f53e664083dc5307bbcf18c0002b26180203Nick Pelly
1410412f53e664083dc5307bbcf18c0002b26180203Nick Pelly         nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList,
1420a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                 &handleList, &typeList);
1436d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         // TODO: Should use the "connected" technology, for now use the first
1440412f53e664083dc5307bbcf18c0002b26180203Nick Pelly         if (e->GetArrayLength(techList) > 0) {
1450412f53e664083dc5307bbcf18c0002b26180203Nick Pelly             jint* technologies = e->GetIntArrayElements(techList, 0);
1466d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             SecureElementTech = technologies[0];
147c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("Store Secure Element Info\n");
1486d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
1496d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen
150c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("Discovered secure element: tech=%d", SecureElementTech);
1516d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         }
1526d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         else {
1536d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             LOGE("Discovered secure element, but could not resolve tech");
1546d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             status = NFCSTATUS_FAILED;
1556d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         }
1560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
1590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
160c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Secure Element Handle: 0x%08x",psRemoteDevList->hTargetDev);
1610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         secureElementHandle = psRemoteDevList->hTargetDev;
1620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set type name */
1644f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen         jintArray techList;
1654f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen         jintArray handleList;
1660a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen         jintArray typeList;
1670412f53e664083dc5307bbcf18c0002b26180203Nick Pelly         nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList,
1680a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                 &handleList, &typeList);
1694f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen
1706d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         // TODO: Should use the "connected" technology, for now use the first
1710412f53e664083dc5307bbcf18c0002b26180203Nick Pelly         if ((techList != NULL) && e->GetArrayLength(techList) > 0) {
1720412f53e664083dc5307bbcf18c0002b26180203Nick Pelly             jint* technologies = e->GetIntArrayElements(techList, 0);
1736d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             SecureElementTech = technologies[0];
174c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("Store Secure Element Info\n");
1756d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
1766d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen
177c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("Discovered secure element: tech=%d", SecureElementTech);
1786d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         }
1796d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         else {
1806d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             LOGE("Discovered secure element, but could not resolve tech");
1816d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen             status = NFCSTATUS_FAILED;
1826d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen         }
1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
1850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
186ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   pContextData->status = status;
187ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   sem_post(&pContextData->sem);
1880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
1890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o)
1920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
1930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS ret;
1940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int semResult;
1950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
1960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
1970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
1980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sADD_Cfg_t discovery_cfg;
1990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_Registry_Info_t registry_info;
200c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        InParam;
201c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t        OutParam;
2020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              ExternalRFDetected[3] = {0x00, 0xFC, 0x01};
203c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioGetValue[3] = {0x00, 0xF8, 0x2B};
204c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              GpioSetValue[4];
205c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              gpioValue;
206c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t              Output_Buff[10];
2070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              reg_value;
2080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t              mask_value;
209ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
210c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
211ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
212ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
213ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
214ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
215ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
216ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Registery */
2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareUL = TRUE;
2190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.MifareStd = TRUE;
2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4A = TRUE;
2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.ISO14443_4B = TRUE;
2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Jewel = TRUE;
2230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.Felica = TRUE;
2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   registry_info.NFC = FALSE;
2250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
2270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
228c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Open Secure Element");
2290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Test if External RF field is detected */
231c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = ExternalRFDetected;
232c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
233c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
234c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()");
235c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
236ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
237c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
2380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(ret!=NFCSTATUS_PENDING)
239c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
2400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL status error");
241c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
242ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
243ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Wait for callback response */
244ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
2450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("IOCTL semaphore error");
2470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
2490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
250ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("READ MEM ERROR");
2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
255c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Check the value */
2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0];
2580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   mask_value = reg_value & 0x40;
2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(mask_value == 0x40)
2610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
262c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("External RF Field detected");
2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
265c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Get Secure Element List */
267c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_SE_GetSecureElementList()");
2680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE);
2690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (ret == NFCSTATUS_SUCCESS)
2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
271c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      TRACE("\n> Number of Secure Element(s) : %d\n", No_SE);
2720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      /* Display Secure Element information */
2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      for (i = 0; i<No_SE; i++)
2740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX)
2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
277c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> SMX detected");
278c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas           TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement);
2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           /* save SMARTMX index */
2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_detected = 1;
2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas           SmartMX_index = i;
2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
2830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
284c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      if(SmartMX_detected)
2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
288c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_NtfRegister()");
289ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_NtfRegister(&registry_info, com_android_nfc_jni_open_secure_element_notification_callback, (void *)&cb_data);
2900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_SUCCESS)
2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
293c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Register Notification error");
2940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
2950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
296c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
2970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Set wired mode */
2980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
299c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_SE_SetMode: Wired mode");
3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement,
301c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     phLibNfc_SE_ActModeWired,
302c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     com_android_nfc_jni_smartMX_setModeCb,
303c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas                                     (void *)&cb_data);
3040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if (ret != NFCSTATUS_PENDING )
3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
307c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("\n> SE Set SmartMX mode ERROR \n" );
3080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
310c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
311ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
312ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
314c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
317c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
318ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE set mode failed");
3210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
323c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
324c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("Waiting for notification");
325ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         /* Wait for callback response */
326ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
3270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
328c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element opening error");
3290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
331c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
332ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_MULTIPLE_PROTOCOLS)
3330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("SE detection failed");
3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
336ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
3370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
338c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Tag */
3400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_LOCK();
341c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX)");
3420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_LOCK();
343ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data);
3440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         REENTRANCE_UNLOCK();
3450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         if(ret != NFCSTATUS_PENDING)
3460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
3470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            LOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
3480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
350c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
351c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Wait for callback response */
353ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(sem_wait(&cb_data.sem))
354ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         {
355c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("CONNECT semaphore error");
356ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas             goto clean_and_return;
357ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         }
358c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
3590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Connect Status */
360ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
3610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         {
362c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("Secure Element connect error");
363c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
364c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
365c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
366c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_UNLOCK();
367c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
368c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Get GPIO information */
369c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         CONCURRENCY_LOCK();
370c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioGetValue;
371c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 3;
372c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
388c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
389c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
394c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
395c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue = Ox%02x",gpioValue);
397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Set GPIO information */
399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[0] = 0x00;
400c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[1] = 0xF8;
401c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[2] = 0x2B;
402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         GpioSetValue[3] = (gpioValue | 0x40);
403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         for(i=0;i<4;i++)
407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             TRACE("0x%02x",GpioSetValue[i]);
409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
410c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
411c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.buffer = GpioSetValue;
412c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         InParam.length = 4;
413c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         OutParam.buffer = Output_Buff;
414c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
415c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_LOCK();
416c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
417c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         REENTRANCE_UNLOCK();
418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(ret!=NFCSTATUS_PENDING)
419c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
420c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             LOGE("IOCTL status error");
421c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas             goto clean_and_return;
422c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
423c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         /* Wait for callback response */
425c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(sem_wait(&cb_data.sem))
426c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
427c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("IOCTL semaphore error");
428c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            goto clean_and_return;
429c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         }
430c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
431c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         if(cb_data.status != NFCSTATUS_SUCCESS)
432c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         {
433c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas            LOGE("READ MEM ERROR");
4340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas            goto clean_and_return;
4350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         }
4360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         CONCURRENCY_UNLOCK();
437a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas
438a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas         TRACE("Set Transceive Timeout to 0x1E");
439a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas         phLibNfc_SetIsoXchgTimeout(30);
440a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas
4410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         /* Return the Handle of the SecureElement */
4420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         return secureElementHandle;
4430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      else
4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      {
446c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas         LOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected");
4470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         goto clean_and_return;
4480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      }
4490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  else
4510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  {
452c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("phLibNfc_SE_GetSecureElementList(): Error");
4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas  }
4550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return 0;
4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
4620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle)
4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jclass cls;
4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jfieldID f;
4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
4670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jboolean result = JNI_FALSE;
4680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
4690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t SmartMX_Handle;
471ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
472c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    InParam;
473c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   phNfc_sData_t    OutParam;
474c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          Output_Buff[10];
475c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioGetValue[3] = {0x00, 0xF8, 0x2B};
476c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          GpioSetValue[4];
477c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   uint8_t          gpioValue;
478ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
479ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
480ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
481ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
482ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
483ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
4840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
485c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Close Secure element function ");
486c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
4870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
4880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect */
489c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Disconnecting from SMX (handle = 0x%x)", handle);
4900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
4910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Disconnect(handle,
4920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          NFC_SMARTMX_RELEASE,
4930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas                                          com_android_nfc_jni_disconnect_callback,
494ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas                                          (void *)&cb_data);
4950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
4960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
4970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
4980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
4990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
501c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
5020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
504ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
505ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
506ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
507ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
508c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Disconnect Status */
510ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
5110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
5120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas     LOGE("\n> Disconnect SE ERROR \n" );
5130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
5140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
515c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_UNLOCK();
516c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
517c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Get GPIO information */
518c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   CONCURRENCY_LOCK();
519c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioGetValue;
520c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 3;
521c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
522c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value");
523c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
524c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
525c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
526c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
527c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
540c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
541c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0];
546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue = Ox%02x",gpioValue);
547c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
548c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Set GPIO information */
549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[0] = 0x00;
550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[1] = 0xF8;
551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[2] = 0x2B;
552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   GpioSetValue[3] = (gpioValue & 0xBF);
553c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
554c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]);
555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   for(i=0;i<4;i++)
557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       TRACE("0x%02x",GpioSetValue[i]);
559c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
560c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
561c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.buffer = GpioSetValue;
562c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   InParam.length = 4;
563c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   OutParam.buffer = Output_Buff;
564c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value");
565c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_LOCK();
566c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data);
567c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   REENTRANCE_UNLOCK();
568c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(status!=NFCSTATUS_PENDING)
569c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
570c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("IOCTL status error");
571c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       goto clean_and_return;
572c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
573c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
574c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   /* Wait for callback response */
575c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(sem_wait(&cb_data.sem))
576c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
577c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("IOCTL semaphore error");
578c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
579c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
580c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
581c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
582c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   {
583c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("READ MEM ERROR");
584c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      goto clean_and_return;
585c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   }
586c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas
5870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = JNI_TRUE;
5880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
590a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas   TRACE("Reset Transceive timeout to 0x1A");
591a31e9dde6f6fb1b0bb369a9545ddb83604bee396daniel_tomas   nfc_jni_reset_timeout_values();
5920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
5930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
5940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e,
5970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jobject o,jint handle, jbyteArray data)
5980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
5990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t offset = 0;
6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint8_t *buf;
6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   uint32_t buflen;
6020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   phLibNfc_sTransceiveInfo_t transceive_info;
6030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray result = NULL;
6040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int res;
6050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   int tech = SecureElementTech;
6070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   NFCSTATUS status;
608ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   struct nfc_jni_callback_data cb_data;
609ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas
610ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   /* Create the local semaphore */
611ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if (!nfc_cb_data_init(&cb_data, NULL))
612ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
613ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas      goto clean_and_return;
614ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
616c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Exchange APDU function ");
6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_LOCK();
6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
620c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Secure Element tech: %d\n", tech);
6210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
6230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   buflen = (uint32_t)e->GetArrayLength(data);
6240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Prepare transceive info structure */
6260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL)
6270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      offset = 2;
6290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = (uint8_t)buf[1];
6310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else if(tech == TARGET_TYPE_ISO14443_4)
6330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
6350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      transceive_info.addr = 0;
6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.buffer = buf + offset;
6390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sSendData.length = buflen - offset;
6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   transceive_info.sRecvData.length = 1024;
6420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer == NULL)
6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
648c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX)");
6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_LOCK();
6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
651ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas		   com_android_nfc_jni_transceive_callback, (void *)&cb_data);
6520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   REENTRANCE_UNLOCK();
6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(status != NFCSTATUS_PENDING)
6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      LOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
658c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
6590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Wait for callback response */
661ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(sem_wait(&cb_data.sem))
662ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   {
663c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas       LOGE("TRANSCEIVE semaphore error");
664ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas       goto clean_and_return;
665ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   }
6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
667ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas   if(cb_data.status != NFCSTATUS_SUCCESS)
6680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
669c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas      LOGE("TRANSCEIVE error");
6700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      goto clean_and_return;
6710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   /* Copy results back to Java */
6740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length);
6750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(result != NULL)
6760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(result, 0,
6780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas    		  com_android_nfc_jni_transceive_buffer->length,
6790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas         (jbyte *)com_android_nfc_jni_transceive_buffer->buffer);
6800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return:
6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(transceive_info.sRecvData.buffer != NULL)
6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      free(transceive_info.sRecvData.buffer);
6860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   e->ReleaseByteArrayElements(data,
6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   CONCURRENCY_UNLOCK();
6920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return result;
6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
6950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
6960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle)
6970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
698c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element UID function ");
6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jbyteArray SecureElementUid;
7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength);
7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid);
7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return SecureElementUid;
7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle)
7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   jintArray techList;
716c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas   TRACE("Get Secure element Type function ");
7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if(handle == secureElementHandle)
7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      techList = e->NewIntArray(1);
7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech);
7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return techList;
7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   else
7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {
7260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return NULL;
7270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
7280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
7320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration.
7330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
7340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] =
7350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doOpenSecureElementConnection", "()I",
7370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection},
7380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doDisconnect", "(I)Z",
7390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect},
7400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doTransceive", "(I[B)[B",
7410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doTransceive},
7420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetUid", "(I)[B",
7430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetUid},
7440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   {"doGetTechList", "(I)[I",
7450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList},
7460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas};
7470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
7490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
7500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   return jniRegisterNativeMethods(e,
7510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      "com/android/nfc/NativeNfcSecureElement",
7520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      gMethods, NELEM(gMethods));
7530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
7540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
7550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android
756