| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /****************************************************************************** |
| * |
| * The original Work has been changed by NXP Semiconductors. |
| * |
| * Copyright (C) 2015 NXP Semiconductors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ******************************************************************************/ |
| #include "OverrideLog.h" |
| #include "SecureElement.h" |
| #include "JavaClassConstants.h" |
| #include "PowerSwitch.h" |
| #include "NfcTag.h" |
| #include "RoutingManager.h" |
| #include <ScopedPrimitiveArray.h> |
| #include "phNxpConfig.h" |
| |
| extern bool hold_the_transceive; |
| extern int dual_mode_current_state; |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION == TRUE)) |
| extern bool ceTransactionPending; |
| #endif |
| namespace android |
| { |
| |
| extern void startRfDiscovery (bool isStart); |
| extern bool isDiscoveryStarted(); |
| extern bool isp2pActivated(); |
| extern void com_android_nfc_NfcManager_disableDiscovery (JNIEnv* e, jobject o); |
| extern void com_android_nfc_NfcManager_enableDiscovery (JNIEnv* e, jobject o, jint mode); |
| #if (NXP_EXTNS == TRUE) |
| extern int gMaxEERecoveryTimeout; |
| #endif |
| static SyncEvent sNfaVSCResponseEvent; |
| //static bool sRfEnabled; /*commented to eliminate warning defined but not used*/ |
| |
| static void nfaVSCCallback(UINT8 event, UINT16 param_len, UINT8 *p_param); |
| |
| inline static void nfaVSCCallback(UINT8 event, UINT16 param_len, UINT8 *p_param) /*defined as inline to eliminate warning defined but not used*/ |
| { |
| (void)event; |
| (void)param_len; |
| (void)p_param; |
| SyncEventGuard guard (sNfaVSCResponseEvent); |
| sNfaVSCResponseEvent.notifyOne (); |
| } |
| |
| // These must match the EE_ERROR_ types in NfcService.java |
| static const int EE_ERROR_IO = -1; |
| static const int EE_ERROR_INIT = -3; |
| static const int EE_ERROR_LISTEN_MODE = -4; |
| static const int EE_ERROR_EXT_FIELD = -5; |
| |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doOpenSecureElementConnection |
| ** |
| ** Description: Connect to the secure element. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Handle of secure element. values < 0 represent failure. |
| ** |
| *******************************************************************************/ |
| #if (NXP_EXTNS == TRUE) |
| static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject,jint seId) |
| #else |
| static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject) |
| #endif |
| { |
| ALOGD("%s: enter", __FUNCTION__); |
| bool stat = false; |
| jint secElemHandle = EE_ERROR_INIT; |
| long ret_val = -1; |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| p61_access_state_t p61_current_state = P61_STATE_INVALID; |
| se_apdu_gate_info gateInfo = NO_APDU_GATE; |
| #endif |
| SecureElement &se = SecureElement::getInstance(); |
| #if ((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| #if(NXP_ESE_WIRED_MODE_PRIO != TRUE) |
| if(se.isBusy()) { |
| goto TheEnd; |
| } |
| #endif |
| se.mIsExclusiveWiredMode = false; // to ctlr exclusive wired mode |
| if(seId == 0xF4) |
| { |
| if(se.mIsWiredModeOpen) |
| { |
| goto TheEnd; |
| } |
| #if (NXP_ESE_UICC_EXCLUSIVE_WIRED_MODE == true) |
| se.mIsExclusiveWiredMode = true; |
| #endif |
| stat = se.checkForWiredModeAccess(); |
| if(stat == false) |
| { |
| ALOGD("Denying SE open due to SE listen mode active"); |
| secElemHandle = EE_ERROR_LISTEN_MODE; |
| goto TheEnd; |
| } |
| |
| ALOGD("%s: Activating UICC Wired Mode=0x%X", __FUNCTION__, seId); |
| stat = se.activate(seId); |
| ALOGD("%s: Check UICC activation status stat=%X", __FUNCTION__, stat); |
| if (stat) |
| { |
| //establish a pipe to UICC |
| ALOGD("%s: Creatting a pipe to UICC!", __FUNCTION__); |
| stat = se.connectEE(); |
| if (stat) |
| { |
| secElemHandle = se.mActiveEeHandle; |
| } |
| else |
| { |
| se.deactivate (0); |
| } |
| } |
| if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))) |
| { |
| PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); |
| } |
| se.mIsWiredModeOpen = true; |
| #if(NXP_ESE_UICC_EXCLUSIVE_WIRED_MODE == TRUE) |
| if (isDiscoveryStarted()) |
| { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery (false); |
| status = NFA_DisableListening(); |
| if(status == NFCSTATUS_OK) |
| { |
| startRfDiscovery (true); |
| } |
| } |
| else |
| { |
| status = NFA_DisableListening(); |
| } |
| se.mlistenDisabled = true; |
| #endif |
| goto TheEnd; |
| } |
| #if(NXP_ESE_WIRED_MODE_PRIO == TRUE) |
| if((se.mIsWiredModeOpen)&&(se.mActiveEeHandle == 0x402)) |
| { |
| stat = SecureElement::getInstance().disconnectEE (se.mActiveEeHandle); |
| se.mActiveEeHandle = NFA_HANDLE_INVALID; |
| se.mIsWiredModeOpen = false; |
| } |
| #endif |
| |
| #if(NFC_NXP_CHIP_TYPE != PN547C2) |
| #if (NXP_NFCEE_REMOVED_NTF_RECOVERY == TRUE) |
| if((RoutingManager::getInstance().is_ee_recovery_ongoing())) |
| { |
| SyncEventGuard guard (se.mEEdatapacketEvent); |
| if(se.mEEdatapacketEvent.wait(android::gMaxEERecoveryTimeout) == false) |
| { |
| goto TheEnd; |
| } |
| } |
| #endif |
| #if(NXP_ESE_DUAL_MODE_PRIO_SCHEME == NXP_ESE_EXCLUSIVE_WIRED_MODE) |
| se.mIsExclusiveWiredMode = true; |
| #endif |
| stat = se.checkForWiredModeAccess(); |
| if(stat == false) |
| { |
| ALOGD("Denying SE open due to SE listen mode active"); |
| secElemHandle = EE_ERROR_LISTEN_MODE; |
| goto TheEnd; |
| } |
| #else |
| if (se.isActivatedInListenMode()) { |
| ALOGD("Denying SE open due to SE listen mode active"); |
| secElemHandle = EE_ERROR_LISTEN_MODE; |
| goto TheEnd; |
| } |
| |
| if (se.isRfFieldOn()) { |
| ALOGD("Denying SE open due to SE in active RF field"); |
| secElemHandle = EE_ERROR_EXT_FIELD; |
| goto TheEnd; |
| } |
| #endif |
| |
| ret_val = NFC_GetP61Status ((void *)&p61_current_state); |
| if (ret_val < 0) |
| { |
| ALOGD("NFC_GetP61Status failed"); |
| goto TheEnd; |
| } |
| ALOGD("P61 Status is: %x", p61_current_state); |
| |
| #if (NXP_ESE_JCOP_DWNLD_PROTECTION == TRUE && NXP_EXTNS == TRUE) |
| if(p61_current_state & P61_STATE_JCP_DWNLD) |
| { |
| ALOGD("Denying SE open due to JCOP OS Download is in progress"); |
| secElemHandle = EE_ERROR_IO; |
| goto TheEnd; |
| } |
| #endif |
| |
| #if(NFC_NXP_ESE_VER == JCOP_VER_3_1) |
| if (!(p61_current_state & P61_STATE_SPI) && !(p61_current_state & P61_STATE_SPI_PRIO)) |
| { |
| #endif |
| if(p61_current_state & (P61_STATE_SPI)||(p61_current_state & (P61_STATE_SPI_PRIO))) |
| { |
| dual_mode_current_state |= SPI_ON; |
| } |
| if(p61_current_state & (P61_STATE_SPI_PRIO)) |
| { |
| hold_the_transceive = true; |
| } |
| |
| secElemHandle = NFC_ReqWiredAccess ((void *)&status); |
| if (secElemHandle < 0) |
| { |
| ALOGD("Denying SE open due to NFC_ReqWiredAccess failed"); |
| goto TheEnd; |
| } |
| else |
| { |
| if (status != NFCSTATUS_SUCCESS) |
| { |
| ALOGD("Denying SE open due to SE is being used by SPI"); |
| secElemHandle = EE_ERROR_IO; |
| goto TheEnd; |
| } |
| else |
| { |
| ALOGD("SE Access granted"); |
| #if(NXP_ESE_DUAL_MODE_PRIO_SCHEME == NXP_ESE_EXCLUSIVE_WIRED_MODE) |
| if (isDiscoveryStarted()) |
| { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery (false); |
| status = NFA_DisableListening(); |
| if(status == NFCSTATUS_OK) |
| { |
| startRfDiscovery (true); |
| } |
| } |
| else |
| { |
| status = NFA_DisableListening(); |
| } |
| se.mlistenDisabled = true; |
| #endif |
| } |
| } |
| #if(NFC_NXP_ESE_VER == JCOP_VER_3_1) |
| } |
| else |
| { |
| ALOGD("Denying SE open because SPI is already open"); |
| goto TheEnd; |
| |
| } |
| #endif |
| #endif |
| /* Tell the controller to power up to get ready for sec elem operations */ |
| PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER); |
| PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED); |
| /* If controller is not routing AND there is no pipe connected, |
| then turn on the sec elem */ |
| #if(NXP_EXTNS == TRUE) && (NFC_NXP_ESE == TRUE) |
| if((!(p61_current_state & (P61_STATE_SPI | P61_STATE_SPI_PRIO))) && (!(dual_mode_current_state & CL_ACTIVE))) |
| stat = se.SecEle_Modeset(0x01); //Workaround |
| usleep(150000); /*provide enough delay if NFCC enter in recovery*/ |
| #endif |
| stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle. |
| |
| if (stat) |
| { |
| //establish a pipe to sec elem |
| stat = se.connectEE(); |
| if (stat) |
| { |
| secElemHandle = se.mActiveEeHandle; |
| } |
| else |
| { |
| se.deactivate (0); |
| } |
| } |
| #if((NXP_EXTNS == TRUE) && (NFC_NXP_ESE == TRUE)) |
| if(stat) |
| { |
| status = NFA_STATUS_OK; |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION == TRUE)) |
| if(!(se.isActivatedInListenMode() || isp2pActivated() || NfcTag::getInstance ().isActivated ())) |
| { |
| se.enablePassiveListen(0x00); |
| } |
| se.meseUiccConcurrentAccess = true; |
| #endif |
| #if (NXP_WIRED_MODE_STANDBY == TRUE) |
| if(se.mNfccPowerMode == 1) |
| { |
| status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON); |
| if(status != NFA_STATUS_OK) |
| { |
| ALOGD("%s: power link command failed", __FUNCTION__); |
| } |
| else |
| { |
| se.SecEle_Modeset(0x01); |
| } |
| } |
| #endif |
| if((status == NFA_STATUS_OK) && (se.mIsIntfRstEnabled)) |
| { |
| gateInfo = se.getApduGateInfo(); |
| if(gateInfo == ETSI_12_APDU_GATE) |
| { |
| se.NfccStandByOperation(STANDBY_TIMER_STOP); |
| status = se.SecElem_sendEvt_Abort(); |
| if(status != NFA_STATUS_OK) |
| { |
| ALOGD("%s: EVT_ABORT failed", __FUNCTION__); |
| se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER); |
| } |
| } |
| } |
| if(status != NFA_STATUS_OK) |
| { |
| #if (NXP_WIRED_MODE_STANDBY == TRUE) |
| if(se.mNfccPowerMode == 1) |
| se.setNfccPwrConfig(se.NFCC_DECIDES); |
| #endif |
| se.disconnectEE (secElemHandle); |
| secElemHandle = EE_ERROR_INIT; |
| |
| ret_val = NFC_RelWiredAccess((void*)&status); |
| if(ret_val < 0) |
| ALOGD("Denying SE release due to NFC_RelWiredAccess failure"); |
| else if(status != NFCSTATUS_SUCCESS) |
| ALOGD("Denying SE close, since SE is not released by PN54xx driver"); |
| } |
| else |
| { |
| se.mIsWiredModeOpen = true; |
| } |
| } |
| #endif |
| //if code fails to connect to the secure element, and nothing is active, then |
| //tell the controller to power down |
| if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))) |
| { |
| PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); |
| } |
| |
| TheEnd: |
| ALOGD("%s: exit; return handle=0x%X", __FUNCTION__, secElemHandle); |
| return secElemHandle; |
| } |
| |
| |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection |
| ** |
| ** Description: Disconnect from the secure element. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Handle of secure element. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle) |
| { |
| ALOGD("%s: enter; handle=0x%04x", __FUNCTION__, handle); |
| bool stat = false; |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| long ret_val = -1; |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| |
| SecureElement &se = SecureElement::getInstance(); |
| se.NfccStandByOperation(STANDBY_TIMER_STOP); |
| #endif |
| |
| #if(NXP_EXTNS == TRUE) |
| if(handle == 0x402) |
| { |
| stat = SecureElement::getInstance().disconnectEE (handle); |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| se.mIsWiredModeOpen = false; |
| #endif |
| #if( (NXP_ESE_UICC_EXCLUSIVE_WIRED_MODE == TRUE) && (NFC_NXP_ESE == TRUE) && (NXP_EXTNS == TRUE) ) |
| se.mIsExclusiveWiredMode = false; |
| if(se.mlistenDisabled) |
| { |
| if (isDiscoveryStarted()) |
| { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery (false); |
| status = NFA_EnableListening(); |
| startRfDiscovery (true); |
| } |
| else |
| { |
| status = NFA_EnableListening(); |
| } |
| se.mlistenDisabled = false; |
| } |
| #endif |
| goto TheEnd; |
| } |
| #endif |
| |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| //Send the EVT_END_OF_APDU_TRANSFER event at the end of wired mode session. |
| se.NfccStandByOperation(STANDBY_MODE_ON); |
| #endif |
| |
| stat = SecureElement::getInstance().disconnectEE (handle); |
| |
| /* if nothing is active after this, then tell the controller to power down */ |
| if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)) |
| PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| ret_val = NFC_RelWiredAccess ((void *)&status); |
| if (ret_val < 0) |
| { |
| ALOGD("Denying SE Release due to NFC_RelWiredAccess failed"); |
| goto TheEnd; |
| } |
| else |
| { |
| if (status != NFCSTATUS_SUCCESS) |
| { |
| ALOGD("Denying SE close due to SE is not being released by Pn54x driver"); |
| stat = false; |
| } |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION == TRUE)) |
| se.enablePassiveListen(0x01); |
| SecureElement::getInstance().mPassiveListenTimer.kill(); |
| se.meseUiccConcurrentAccess = false; |
| #endif |
| se.mIsWiredModeOpen = false; |
| #if(NXP_ESE_DUAL_MODE_PRIO_SCHEME == NXP_ESE_EXCLUSIVE_WIRED_MODE) |
| if(se.mlistenDisabled) |
| { |
| if (isDiscoveryStarted()) |
| { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery (false); |
| status = NFA_EnableListening(); |
| startRfDiscovery (true); |
| } |
| else |
| { |
| status = NFA_EnableListening(); |
| } |
| se.mlistenDisabled = false; |
| } |
| #endif |
| } |
| #endif |
| TheEnd: |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| ALOGD("%s: exit stat = %d", __FUNCTION__, stat); |
| #else |
| ALOGD("%s: exit", __FUNCTION__); |
| #endif |
| return stat ? JNI_TRUE : JNI_FALSE; |
| } |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_EXTNS == TRUE)) |
| static int checkP61Status(void) |
| { |
| jint ret_val = -1; |
| p61_access_state_t p61_current_state = P61_STATE_INVALID; |
| ret_val = NFC_GetP61Status ((void *)&p61_current_state); |
| if (ret_val < 0) |
| { |
| ALOGD("NFC_GetP61Status failed"); |
| return -1; |
| } |
| if(p61_current_state & (P61_STATE_SPI)||(p61_current_state & (P61_STATE_SPI_PRIO))) |
| { |
| ALOGD("No gpio change"); |
| ret_val = 0; |
| } |
| else |
| { |
| ret_val = -1; |
| } |
| return ret_val; |
| } |
| #endif |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doResetSecureElement |
| ** |
| ** Description: Reset the secure element. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Handle of secure element. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nativeNfcSecureElement_doResetSecureElement (JNIEnv*, jobject, jint handle) |
| { |
| bool stat = false; |
| #if (NFC_NXP_ESE == TRUE) |
| #if (NXP_WIRED_MODE_STANDBY == TRUE) |
| tNFA_STATUS nfaStat = NFA_STATUS_FAILED; |
| #endif |
| SecureElement &se = SecureElement::getInstance(); |
| |
| ALOGD("%s: enter; handle=0x%04x", __FUNCTION__, handle); |
| if(!se.mIsWiredModeOpen) |
| { |
| ALOGD("wired mode is not open"); |
| return stat; |
| } |
| #if ((NXP_ESE_DWP_SPI_SYNC_ENABLE == TRUE) && (NXP_WIRED_MODE_STANDBY == TRUE)) |
| if(!checkP61Status()) |
| { |
| ALOGD("Reset is not allowed while SPI ON"); |
| return stat; |
| } |
| #endif |
| #if (NXP_WIRED_MODE_STANDBY == TRUE) |
| if(se.mNfccPowerMode == 1) |
| { |
| nfaStat = se.setNfccPwrConfig(se.NFCC_DECIDES); |
| ALOGD ("%s Power Mode is Legacy", __FUNCTION__); |
| } |
| #endif |
| { |
| stat = se.SecEle_Modeset(0x00); |
| if (handle == 0x4C0) |
| { |
| if(checkP61Status()) |
| se.NfccStandByOperation(STANDBY_GPIO_LOW); |
| } |
| usleep(100 * 1000); |
| if (handle == 0x4C0) |
| { |
| if(checkP61Status() && (se.mIsWiredModeOpen == true)) |
| se.NfccStandByOperation(STANDBY_GPIO_HIGH); |
| } |
| stat = se.SecEle_Modeset(0x01); |
| usleep(2000 * 1000); |
| |
| #if (NXP_WIRED_MODE_STANDBY == TRUE) |
| if(se.mNfccPowerMode == 1) |
| { |
| nfaStat = se.setNfccPwrConfig(se.POWER_ALWAYS_ON); |
| ALOGD ("%s Power Mode is Legacy", __FUNCTION__); |
| } |
| #endif |
| } |
| #endif |
| ALOGD("%s: exit", __FUNCTION__); |
| return stat ? JNI_TRUE : JNI_FALSE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doeSEChipResetSecureElement |
| ** |
| ** Description: Reset the secure element. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Handle of secure element. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nativeNfcSecureElement_doeSEChipResetSecureElement (JNIEnv*, jobject) |
| { |
| bool stat = false; |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| unsigned long num = 0x01; |
| #if ((NFC_NXP_ESE == TRUE) && (NXP_EXTNS == TRUE)) |
| SecureElement &se = SecureElement::getInstance(); |
| if (GetNxpNumValue("NXP_ESE_POWER_DH_CONTROL", &num, sizeof(num))) |
| { |
| ALOGD("Power schemes enabled in config file is %ld", num); |
| } |
| if(num == 0x02) |
| { |
| status = se.eSE_Chip_Reset(); |
| if(status == NFCSTATUS_SUCCESS) |
| { |
| stat = true; |
| } |
| } |
| #endif |
| return stat ? JNI_TRUE : JNI_FALSE; |
| } |
| |
| |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doGetAtr |
| ** |
| ** Description: GetAtr from the connected eSE. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Handle of secure element. |
| ** |
| ** Returns: Buffer of received data. |
| ** |
| *******************************************************************************/ |
| static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle) |
| { |
| bool stat = false; |
| const INT32 recvBufferMaxSize = 1024; |
| UINT8 recvBuffer [recvBufferMaxSize]; |
| INT32 recvBufferActualSize = 0; |
| #if (NFC_NXP_ESE == TRUE) |
| ALOGD("%s: enter; handle=0x%04x", __FUNCTION__, handle); |
| |
| stat = SecureElement::getInstance().getAtr(handle, recvBuffer, &recvBufferActualSize); |
| |
| //copy results back to java |
| #endif |
| jbyteArray result = e->NewByteArray(recvBufferActualSize); |
| if (result != NULL) { |
| e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer); |
| } |
| |
| ALOGD("%s: exit: recv len=%ld", __FUNCTION__, recvBufferActualSize); |
| |
| return result; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nativeNfcSecureElement_doTransceive |
| ** |
| ** Description: Send data to the secure element; retrieve response. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Secure element's handle. |
| ** data: Data to send. |
| ** |
| ** Returns: Buffer of received data. |
| ** |
| *******************************************************************************/ |
| static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data) |
| { |
| const INT32 recvBufferMaxSize = 0x8800;//1024; 34k |
| UINT8 recvBuffer [recvBufferMaxSize]; |
| INT32 recvBufferActualSize = 0; |
| |
| ScopedByteArrayRW bytes(e, data); |
| #if(NXP_EXTNS == TRUE) |
| ALOGD("%s: enter; handle=0x%X; buf len=%zu", __FUNCTION__, handle, bytes.size()); |
| SecureElement::getInstance().transceive(reinterpret_cast<UINT8*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, WIRED_MODE_TRANSCEIVE_TIMEOUT); |
| |
| //copy results back to java |
| jbyteArray result = e->NewByteArray(recvBufferActualSize); |
| if (result != NULL) |
| { |
| e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer); |
| } |
| #if((NFC_NXP_ESE == TRUE)&&(NXP_NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION == TRUE)) |
| if (SecureElement::getInstance().mIsWiredModeBlocked == true) |
| { |
| ALOGD ("APDU Transceive CE wait"); |
| SecureElement::getInstance().startThread(0x01); |
| } |
| #endif |
| ALOGD("%s: exit: recv len=%ld", __FUNCTION__, recvBufferActualSize); |
| return result; |
| #else |
| jbyteArray result = e->NewByteArray(0); |
| return result; |
| #endif |
| } |
| |
| /***************************************************************************** |
| ** |
| ** Description: JNI functions |
| ** |
| *****************************************************************************/ |
| static JNINativeMethod gMethods[] = |
| { |
| #if(NXP_EXTNS == TRUE) |
| {"doNativeOpenSecureElementConnection", "(I)I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection}, |
| #else |
| {"doNativeOpenSecureElementConnection", "()I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection}, |
| #endif |
| {"doNativeDisconnectSecureElementConnection", "(I)Z", (void *) nativeNfcSecureElement_doDisconnectSecureElementConnection}, |
| {"doNativeResetSecureElement", "(I)Z", (void *) nativeNfcSecureElement_doResetSecureElement}, |
| {"doNativeeSEChipResetSecureElement", "()Z", (void *) nativeNfcSecureElement_doeSEChipResetSecureElement}, |
| {"doTransceive", "(I[B)[B", (void *) nativeNfcSecureElement_doTransceive}, |
| {"doNativeGetAtr", "(I)[B", (void *) nativeNfcSecureElement_doGetAtr}, |
| }; |
| |
| |
| /******************************************************************************* |
| ** |
| ** Function: register_com_android_nfc_NativeNfcSecureElement |
| ** |
| ** Description: Regisgter JNI functions with Java Virtual Machine. |
| ** e: Environment of JVM. |
| ** |
| ** Returns: Status of registration. |
| ** |
| *******************************************************************************/ |
| int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) |
| { |
| return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName, |
| gMethods, NELEM(gMethods)); |
| } |
| |
| |
| } // namespace android |