10bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* 20bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Copyright (C) 2010 The Android Open Source Project 30bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * 40bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Licensed under the Apache License, Version 2.0 (the "License"); 50bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * you may not use this file except in compliance with the License. 60bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * You may obtain a copy of the License at 70bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * 80bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * http://www.apache.org/licenses/LICENSE-2.0 90bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * 100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * Unless required by applicable law or agreed to in writing, software 110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * distributed under the License is distributed on an "AS IS" BASIS, 120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * See the License for the specific language governing permissions and 140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * limitations under the License. 150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */ 160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include <semaphore.h> 180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas#include "com_android_nfc.h" 200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_transceive_buffer; 220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sData_t *com_android_nfc_jni_ioctl_buffer; 230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic phNfc_sRemoteDevInformation_t* SecureElementInfo; 240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int secureElementHandle; 250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasextern void *gHWRef; 260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic int SecureElementTech; 2704a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomasextern uint8_t device_connected_flag; 280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasnamespace android { 300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 31ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomasstatic void com_android_nfc_jni_ioctl_callback ( void* pContext, 320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phNfc_sData_t* Outparam_Cb, 330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status) 340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 35ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 36ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (status == NFCSTATUS_SUCCESS ) 380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 39c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas LOG_CALLBACK("> IOCTL successful",status); 400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 43c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas LOG_CALLBACK("> IOCTL error",status); 440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 46ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas com_android_nfc_jni_ioctl_buffer = Outparam_Cb; 47ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 48ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_transceive_callback(void *pContext, 520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) 530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 54ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 55ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status); 570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas com_android_nfc_jni_transceive_buffer = pResBuffer; 59ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 60ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_connect_callback(void *pContext, 650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_Handle hRemoteDev, 660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) 670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 68ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 70ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas LOG_CALLBACK("com_android_nfc_jni_connect_callback", status); 710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 72ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 73ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_disconnect_callback(void *pContext, 770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_Handle hRemoteDev, 780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status) 790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 80ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 81ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status); 830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 84ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 85ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* Set Secure Element mode callback*/ 890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_smartMX_setModeCb (void* pContext, 900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_Handle hSecureElement, 910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status) 920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 93ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 94ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(status==NFCSTATUS_SUCCESS) 960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 97c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas LOG_CALLBACK("SE Set Mode is Successful",status); 98c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("SE Handle: %lu", hSecureElement); 990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 1010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 102c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas LOG_CALLBACK("SE Set Mode is failed\n ",status); 1030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 105ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 106ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 1070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 1080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext, 1100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_RemoteDevList_t *psRemoteDevList, 1110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t uNofRemoteDev, 1120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status) 1130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 114ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; 1150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS ret; 1160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int i; 1170412f53e664083dc5307bbcf18c0002b26180203Nick Pelly JNIEnv *e = nfc_get_env(); 1180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(status == NFCSTATUS_DESELECTED) 1200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 1210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status); 1220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 1240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 1250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status); 126a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton TRACE("Discovered %d secure elements", uNofRemoteDev); 1270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 1290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 130a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly bool foundHandle = false; 131c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Multiple Protocol supported\n"); 132a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly for (i=0; i<uNofRemoteDev; i++) { 133a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly // Always open the phNfc_eISO14443_A_PICC protocol 134a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly TRACE("Protocol %d handle=%x type=%d", i, psRemoteDevList[i].hTargetDev, 135a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly psRemoteDevList[i].psRemoteDevInfo->RemDevType); 136a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly if (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC) { 137a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly secureElementHandle = psRemoteDevList[i].hTargetDev; 138a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly foundHandle = true; 139a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly } 140a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly } 141a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly if (!foundHandle) { 142afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Could not find ISO-DEP secure element"); 143a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly status = NFCSTATUS_FAILED; 144a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly goto clean_and_return; 145a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly } 1460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 1480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 149a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton secureElementHandle = psRemoteDevList->hTargetDev; 1500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 151a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton 152a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton TRACE("Secure Element Handle: 0x%08x", secureElementHandle); 153a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton 154a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton /* Set type name */ 155a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton jintArray techList; 1566a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, NULL, NULL); 157a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton 158a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton // TODO: Should use the "connected" technology, for now use the first 159a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton if ((techList != NULL) && e->GetArrayLength(techList) > 0) { 16084f234a73bb3e149ce8c7ff768bd467fdeac27bfJeff Hamilton e->GetIntArrayRegion(techList, 0, 1, &SecureElementTech); 161a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton TRACE("Store Secure Element Info\n"); 162a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton SecureElementInfo = psRemoteDevList->psRemoteDevInfo; 163a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton 164a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton TRACE("Discovered secure element: tech=%d", SecureElementTech); 165a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton } 166a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton else { 167afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Discovered secure element, but could not resolve tech"); 168a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton status = NFCSTATUS_FAILED; 169a8d8c1fa5058573c0d9d1305549c4326737db0b8Jeff Hamilton } 1706a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton 1716a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton // This thread may not return to the virtual machine for a long time 1726a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton // so make sure to delete the local refernce to the tech list. 17384f234a73bb3e149ce8c7ff768bd467fdeac27bfJeff Hamilton e->DeleteLocalRef(techList); 1740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 175a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pelly 176a6a719dc0be38ea516008b5691e48d6e14dd7d7eNick Pellyclean_and_return: 177ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas pContextData->status = status; 178ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas sem_post(&pContextData->sem); 1790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 1800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o) 1830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 1840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS ret; 1850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int semResult; 1860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; 1880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; 1890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_sADD_Cfg_t discovery_cfg; 1900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_Registry_Info_t registry_info; 191c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas phNfc_sData_t InParam; 192c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas phNfc_sData_t OutParam; 1930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t ExternalRFDetected[3] = {0x00, 0xFC, 0x01}; 194c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; 195c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t GpioSetValue[4]; 196c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t gpioValue; 197c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t Output_Buff[10]; 1980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t reg_value; 1990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t mask_value; 200ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data cb_data; 2018e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas struct nfc_jni_callback_data cb_data_SE_Notification; 202c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 203ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Create the local semaphore */ 204ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if (!nfc_cb_data_init(&cb_data, NULL)) 205ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 206ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 207ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 208ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 2098e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas /* Create the local semaphore */ 2108e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL)) 2118e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas { 2128e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas goto clean_and_return; 2138e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas } 2148e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 2150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Registery */ 2160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.MifareUL = TRUE; 2170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.MifareStd = TRUE; 2180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.ISO14443_4A = TRUE; 2190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.ISO14443_4B = TRUE; 2200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.Jewel = TRUE; 2210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.Felica = TRUE; 2220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas registry_info.NFC = FALSE; 2230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_LOCK(); 2250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 226c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Open Secure Element"); 2270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 22804a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas /* Check if NFC device is already connected to a tag or P2P peer */ 22904a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas if (device_connected_flag == 1) 23004a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas { 2317d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag"); 23204a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas goto clean_and_return; 23304a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas } 23404a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas 2350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Test if External RF field is detected */ 236c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.buffer = ExternalRFDetected; 237c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.length = 3; 238c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas OutParam.buffer = Output_Buff; 239c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_Mgt_IoCtl()"); 240c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_LOCK(); 241ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 242c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_UNLOCK(); 2430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(ret!=NFCSTATUS_PENDING) 244c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 245afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL status error"); 24604a29c85c9bdbf0b25171332013934c3436ab0ecDaniel Tomas goto clean_and_return; 247c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 248ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 249ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Wait for callback response */ 250ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(sem_wait(&cb_data.sem)) 2510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 252afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL semaphore error"); 2530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 2540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 256ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 2570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 258afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("READ MEM ERROR"); 2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 2600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 261c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 2620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Check the value */ 2630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0]; 2640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mask_value = reg_value & 0x40; 2650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(mask_value == 0x40) 2670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 268275376f9e469a9e014d82978ba3b8d57fe4a7739Jeff Hamilton // There is an external RF field present, fail the open request 2697d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block ALOGD("Unable to open SE connection, external RF Field detected"); 2700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 2710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 272c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 2730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Get Secure Element List */ 274c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_SE_GetSecureElementList()"); 2750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE); 2760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (ret == NFCSTATUS_SUCCESS) 2770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 278c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("\n> Number of Secure Element(s) : %d\n", No_SE); 2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Display Secure Element information */ 2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas for (i = 0; i<No_SE; i++) 2810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 2820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) 2830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 284c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("> SMX detected"); 285c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement); 2860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* save SMARTMX index */ 2870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas SmartMX_detected = 1; 2880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas SmartMX_index = i; 2890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 2900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 291c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 2920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(SmartMX_detected) 2930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 2940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_LOCK(); 295c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_NtfRegister()"); 2968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas ret = phLibNfc_RemoteDev_NtfRegister(®istry_info, 2978e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas com_android_nfc_jni_open_secure_element_notification_callback, 2988e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas (void *)&cb_data_SE_Notification); 2990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_UNLOCK(); 3000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(ret != NFCSTATUS_SUCCESS) 3010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 302afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Register Notification error"); 3030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 305c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 3060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Set wired mode */ 3070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_LOCK(); 308c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_SE_SetMode: Wired mode"); 3090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement, 310c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas phLibNfc_SE_ActModeWired, 311c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas com_android_nfc_jni_smartMX_setModeCb, 312c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas (void *)&cb_data); 3130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_UNLOCK(); 3140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (ret != NFCSTATUS_PENDING ) 3150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 316afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("\n> SE Set SmartMX mode ERROR \n" ); 3170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 319c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 320ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Wait for callback response */ 321ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(sem_wait(&cb_data.sem)) 3220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 323afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Secure Element opening error"); 3240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 326c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 327ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 3280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 329afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("SE set mode failed"); 3300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 332c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 333c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Waiting for notification"); 334ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Wait for callback response */ 3358e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas if(sem_wait(&cb_data_SE_Notification.sem)) 3360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 337afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Secure Element opening error"); 3380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 340c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 3418e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS && 3428e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS) 3430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 344afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("SE detection failed"); 3450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 346ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 3470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_UNLOCK(); 348c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 3490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Connect Tag */ 3500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_LOCK(); 351c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_Connect(SMX)"); 3520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_LOCK(); 353ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data); 3540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_UNLOCK(); 3550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(ret != NFCSTATUS_PENDING) 3560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 357afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 3580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 3590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 360c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); 361c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 3620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Wait for callback response */ 363ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(sem_wait(&cb_data.sem)) 364ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 365afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("CONNECT semaphore error"); 366ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 367ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 368c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 3690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Connect Status */ 370ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 3710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 372afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("Secure Element connect error"); 373c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 374c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 375c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 376c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas CONCURRENCY_UNLOCK(); 377c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 378c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Get GPIO information */ 379c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas CONCURRENCY_LOCK(); 380c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.buffer = GpioGetValue; 381c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.length = 3; 382c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas OutParam.buffer = Output_Buff; 383c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); 384c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_LOCK(); 385c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 386c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_UNLOCK(); 387c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(ret!=NFCSTATUS_PENDING) 388c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 389afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL status error"); 390c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 391c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 392c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Wait for callback response */ 393c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(sem_wait(&cb_data.sem)) 394c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 395afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL semaphore error"); 396c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 397c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 398c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 399c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 400c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 401afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("READ MEM ERROR"); 402c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 403c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 404c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 405c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; 406c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("GpioValue = Ox%02x",gpioValue); 407c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 408c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Set GPIO information */ 409c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[0] = 0x00; 410c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[1] = 0xF8; 411c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[2] = 0x2B; 412c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[3] = (gpioValue | 0x40); 413c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 414c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); 415c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 416c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas for(i=0;i<4;i++) 417c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 418c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("0x%02x",GpioSetValue[i]); 419c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 420c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 421c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.buffer = GpioSetValue; 422c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.length = 4; 423c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas OutParam.buffer = Output_Buff; 424c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); 425c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_LOCK(); 426c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 427c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_UNLOCK(); 428c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(ret!=NFCSTATUS_PENDING) 429c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 430afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL status error"); 431c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 432c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 433c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 434c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Wait for callback response */ 435c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(sem_wait(&cb_data.sem)) 436c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 437afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL semaphore error"); 438c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 439c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 440c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 441c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 442c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 443afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("READ MEM ERROR"); 4440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 4450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 4460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_UNLOCK(); 4478e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 4488e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data); 4498e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data_SE_Notification); 4508e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 4518e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas /* Return the Handle of the SecureElement */ 4520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return secureElementHandle; 4530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 4540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 4550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 456afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected"); 4570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 4580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 4590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 4600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 4610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 462afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_SE_GetSecureElementList(): Error"); 4630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 4650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return: 4678e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data); 4688e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data_SE_Notification); 4698e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_UNLOCK(); 4710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return 0; 4720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 4730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 4740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 4750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle) 4760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 4770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jclass cls; 4780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jfieldID f; 4790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status; 4800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jboolean result = JNI_FALSE; 4810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; 4820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; 4830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint32_t SmartMX_Handle; 484ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data cb_data; 485c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas phNfc_sData_t InParam; 486c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas phNfc_sData_t OutParam; 487c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t Output_Buff[10]; 488c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; 489c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t GpioSetValue[4]; 490c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas uint8_t gpioValue; 491ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 492ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Create the local semaphore */ 493ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if (!nfc_cb_data_init(&cb_data, NULL)) 494ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 495ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 496ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 4970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 498c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Close Secure element function "); 499c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 5000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_LOCK(); 5010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Disconnect */ 502c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Disconnecting from SMX (handle = 0x%x)", handle); 5030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_LOCK(); 5040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas status = phLibNfc_RemoteDev_Disconnect(handle, 5050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFC_SMARTMX_RELEASE, 5060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas com_android_nfc_jni_disconnect_callback, 507ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas (void *)&cb_data); 5080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_UNLOCK(); 5090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(status != NFCSTATUS_PENDING) 5100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 511afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 5120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 5130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 514c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 5150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 5160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Wait for callback response */ 517ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(sem_wait(&cb_data.sem)) 518ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 519ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 520ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 521c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 5220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Disconnect Status */ 523ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 5240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 525afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("\n> Disconnect SE ERROR \n" ); 5260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 5270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 528c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas CONCURRENCY_UNLOCK(); 529c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 530c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Get GPIO information */ 531c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas CONCURRENCY_LOCK(); 532c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.buffer = GpioGetValue; 533c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.length = 3; 534c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas OutParam.buffer = Output_Buff; 535c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); 536c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_LOCK(); 537c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 538c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_UNLOCK(); 539c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(status!=NFCSTATUS_PENDING) 540c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 541afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL status error"); 542c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 543c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 544c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 545c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Wait for callback response */ 546c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(sem_wait(&cb_data.sem)) 547c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 548afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL semaphore error"); 549c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 550c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 551c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 552c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 553c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 554afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("READ MEM ERROR"); 555c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 556c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 557c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 558c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; 559c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("GpioValue = Ox%02x",gpioValue); 560c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 561c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Set GPIO information */ 562c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[0] = 0x00; 563c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[1] = 0xF8; 564c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[2] = 0x2B; 565c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas GpioSetValue[3] = (gpioValue & 0xBF); 566c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 567c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); 568c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 569c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas for(i=0;i<4;i++) 570c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 571c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("0x%02x",GpioSetValue[i]); 572c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 573c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 574c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.buffer = GpioSetValue; 575c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas InParam.length = 4; 576c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas OutParam.buffer = Output_Buff; 577c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); 578c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_LOCK(); 579c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); 580c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas REENTRANCE_UNLOCK(); 581c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(status!=NFCSTATUS_PENDING) 582c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 583afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL status error"); 584c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 585c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 586c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 587c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas /* Wait for callback response */ 588c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(sem_wait(&cb_data.sem)) 589c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 590afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("IOCTL semaphore error"); 591c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 592c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 593c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 594c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 595c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas { 596afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("READ MEM ERROR"); 597c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas goto clean_and_return; 598c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas } 599c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas 6000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas result = JNI_TRUE; 6010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return: 6038e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data); 6048e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 6050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_UNLOCK(); 6060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return result; 6070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 6080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e, 6100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jobject o,jint handle, jbyteArray data) 6110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 6120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t offset = 0; 6130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint8_t *buf; 6140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uint32_t buflen; 6150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas phLibNfc_sTransceiveInfo_t transceive_info; 6160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jbyteArray result = NULL; 6170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int res; 6180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int tech = SecureElementTech; 6200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas NFCSTATUS status; 621ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas struct nfc_jni_callback_data cb_data; 622ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas 623ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas /* Create the local semaphore */ 624ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if (!nfc_cb_data_init(&cb_data, NULL)) 625ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 626ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 627ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 6280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 629c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Exchange APDU function "); 6300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_LOCK(); 6320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 633c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Secure Element tech: %d\n", tech); 6340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas buf = (uint8_t *)e->GetByteArrayElements(data, NULL); 6360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas buflen = (uint32_t)e->GetArrayLength(data); 6370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Prepare transceive info structure */ 6390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL) 6400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 6410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas offset = 2; 6420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; 6430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.addr = (uint8_t)buf[1]; 6440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else if(tech == TARGET_TYPE_ISO14443_4) 6460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 6470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; 6480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.addr = 0; 6490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.sSendData.buffer = buf + offset; 6520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.sSendData.length = buflen - offset; 6530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); 6540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas transceive_info.sRecvData.length = 1024; 6550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(transceive_info.sRecvData.buffer == NULL) 6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 6580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 6590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 661c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_Transceive(SMX)"); 6620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_LOCK(); 6630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, 664ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas com_android_nfc_jni_transceive_callback, (void *)&cb_data); 6650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas REENTRANCE_UNLOCK(); 6660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(status != NFCSTATUS_PENDING) 6670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 668afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 6690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 6700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 671c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); 6720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Wait for callback response */ 674ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(sem_wait(&cb_data.sem)) 675ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas { 676afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("TRANSCEIVE semaphore error"); 677ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas goto clean_and_return; 678ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas } 6790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 680ff4f1e0caeecc70cd767e1f2e391e28f6c4d4c64daniel_tomas if(cb_data.status != NFCSTATUS_SUCCESS) 6810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 682afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block ALOGE("TRANSCEIVE error"); 6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas goto clean_and_return; 6840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Copy results back to Java */ 6870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length); 6880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(result != NULL) 6890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 6900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas e->SetByteArrayRegion(result, 0, 6910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas com_android_nfc_jni_transceive_buffer->length, 6920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (jbyte *)com_android_nfc_jni_transceive_buffer->buffer); 6930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 6950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasclean_and_return: 6968e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas nfc_cb_data_deinit(&cb_data); 6978e4780adce2f977ac79d9c03a20cd4423e23df70danieltomas 6980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(transceive_info.sRecvData.buffer != NULL) 6990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 7000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas free(transceive_info.sRecvData.buffer); 7010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 7020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas e->ReleaseByteArrayElements(data, 7040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); 7050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas CONCURRENCY_UNLOCK(); 7070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return result; 7090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 7100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle) 7120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 713c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Get Secure element UID function "); 7140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jbyteArray SecureElementUid; 7150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(handle == secureElementHandle) 7170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 7180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength); 7190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid); 7200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return SecureElementUid; 7210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 7220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 7230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 7240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return NULL; 7250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 7260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 7270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle) 7290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 7300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas jintArray techList; 731c16b76ce7fa78afe221c83d2c6cddf2719f397eedaniel_tomas TRACE("Get Secure element Type function "); 7320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if(handle == secureElementHandle) 7340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 7350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas techList = e->NewIntArray(1); 7360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech); 7370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return techList; 7380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 7390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas else 7400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 7410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return NULL; 7420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 7430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 7440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* 7470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas * JNI registration. 7480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */ 7490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasstatic JNINativeMethod gMethods[] = 7500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 75137058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi {"doNativeOpenSecureElementConnection", "()I", 7520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection}, 75337058bf7b59def2f9a565ae5b16aae54e80e9e95Sunil Jogi {"doNativeDisconnectSecureElementConnection", "(I)Z", 7540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect}, 7550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas {"doTransceive", "(I[B)[B", 7560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (void *)com_android_nfc_NativeNfcSecureElement_doTransceive}, 7570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas {"doGetUid", "(I)[B", 7580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (void *)com_android_nfc_NativeNfcSecureElement_doGetUid}, 7590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas {"doGetTechList", "(I)[I", 7600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList}, 7610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}; 7620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasint register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) 7640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 7650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return jniRegisterNativeMethods(e, 766642ab20c81425ba93e206d2a30602cd67ae8bd38Martijn Coenen "com/android/nfc/dhimpl/NativeNfcSecureElement", 7670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas gMethods, NELEM(gMethods)); 7680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 7690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 7700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} // namespace android 771