| /* |
| * 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-2018 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 <android-base/stringprintf.h> |
| #include <base/logging.h> |
| #include <errno.h> |
| #include <nativehelper/ScopedLocalRef.h> |
| #include <nativehelper/ScopedPrimitiveArray.h> |
| #include <nativehelper/ScopedUtfChars.h> |
| #include <pthread.h> |
| #include <semaphore.h> |
| #include <sys/time.h> |
| #include "HciRFParams.h" |
| #include "JavaClassConstants.h" |
| #include "NfcAdaptation.h" |
| #include "NfcJniUtil.h" |
| #include "NfcTag.h" |
| #include "PeerToPeer.h" |
| #include "Pn544Interop.h" |
| #include "PowerSwitch.h" |
| #include "RoutingManager.h" |
| #include "SecureElement.h" |
| #include "SyncEvent.h" |
| #include "_OverrideLog.h" |
| #include "config.h" |
| #if (NXP_EXTNS == TRUE) |
| #include <cutils/properties.h> |
| #include <signal.h> |
| #include <sys/types.h> |
| #include "MposManager.h" |
| #endif |
| #include <fcntl.h> |
| #include "DwpChannel.h" |
| #include "JcopManager.h" |
| #include "TransactionController.h" |
| #include "ce_api.h" |
| #include "nfa_api.h" |
| #include "nfa_ee_api.h" |
| #include "nfa_p2p_api.h" |
| #include "nfc_api.h" |
| #include "nfc_brcm_defs.h" |
| #include "phNxpConfig.h" |
| #include "phNxpExtns.h" |
| #include "rw_api.h" |
| |
| #define SAK_VALUE_AT 17 |
| extern const uint8_t nfca_version_string[]; |
| extern const uint8_t nfa_version_string[]; |
| extern tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg; |
| bool sHCEEnabled = true; |
| |
| #if (NXP_EXTNS == TRUE) |
| #define RETRY_COUNT 0x10 |
| #define DEFAULT_COUNT 0x03 |
| #define ENABLE_DISCOVERY 0x01 |
| #define DISABLE_DISCOVERY 0x02 |
| #define ENABLE_P2P 0x04 |
| #define T3T_CONFIGURE 0x08 |
| #define RE_ROUTING 0x10 |
| #define CLEAR_ENABLE_DISABLE_PARAM 0xFC |
| /* Delay to wait for SE intialization */ |
| #define SE_INIT_DELAY 50 * 1000 |
| #define NFCEE_DISC_TIMEOUT_SEC 2 |
| #define JCOP_INFO_PATH "/data/vendor/nfc/jcop_info.txt" |
| #define OSU_NOT_STARTED 00 |
| #define OSU_COMPLETE 03 |
| #define NFC_PIPE_STATUS_OFFSET 4 |
| #define MAX_JCOP_TIMEOUT_VALUE 60000 /*Maximum Jcop OSU timeout value*/ |
| #define MAX_WAIT_TIME_FOR_RETRY 8 /*Maximum wait for retry in usec*/ |
| #define IS_ESE_RF_CE_PARAM_FETCHED() \ |
| (pEvtData->get_config.param_tlvs[1] == 0xA0 && \ |
| pEvtData->get_config.param_tlvs[2] == 0xF0) |
| #define IS_ESE_CE_MODE_DISABLED() \ |
| (pEvtData->get_config.param_tlvs[5] == 0xFF || \ |
| pEvtData->get_config.param_tlvs[43] == 0xFF) |
| |
| extern nfcee_disc_state sNfcee_disc_state; |
| extern bool recovery; |
| extern uint8_t swp_getconfig_status; |
| extern int gUICCVirtualWiredProtectMask; |
| extern int gEseVirtualWiredProtectMask; |
| extern bool IsEseCeDisabled; |
| static int32_t gNfcInitTimeout; |
| int32_t gdisc_timeout; |
| int32_t gSeDiscoverycount = 0; |
| int32_t gActualSeCount = 0; |
| uint16_t sCurrentSelectedUICCSlot = 1; |
| SyncEvent gNfceeDiscCbEvent; |
| uint8_t sSelectedUicc = 0; |
| static bool sIsLowRamDevice = false; |
| bool nfcManager_getTransanctionRequest(int t3thandle, bool registerRequest); |
| extern bool createSPIEvtHandlerThread(); |
| extern void releaseSPIEvtHandlerThread(); |
| #endif |
| namespace android { |
| extern bool gIsTagDeactivating; |
| extern bool gIsSelectingRfInterface; |
| extern void nativeNfcTag_doTransceiveStatus(tNFA_STATUS status, uint8_t* buf, |
| uint32_t buflen); |
| extern void nativeNfcTag_notifyRfTimeout(); |
| extern void nativeNfcTag_doConnectStatus(jboolean is_connect_ok); |
| extern void nativeNfcTag_doDeactivateStatus(int status); |
| extern void nativeNfcTag_doWriteStatus(jboolean is_write_ok); |
| extern void nativeNfcTag_doCheckNdefResult(tNFA_STATUS status, |
| uint32_t max_size, |
| uint32_t current_size, |
| uint8_t flags); |
| extern void nativeNfcTag_doMakeReadonlyResult(tNFA_STATUS status); |
| extern void nativeNfcTag_doPresenceCheckResult(tNFA_STATUS status); |
| extern void nativeNfcTag_formatStatus(bool is_ok); |
| extern void nativeNfcTag_resetPresenceCheck(); |
| extern void nativeNfcTag_doReadCompleted(tNFA_STATUS status); |
| extern void nativeNfcTag_setRfInterface(tNFA_INTF_TYPE rfInterface); |
| extern void nativeNfcTag_abortWaits(); |
| extern void doDwpChannel_ForceExit(); |
| extern void nativeLlcpConnectionlessSocket_abortWait(); |
| extern tNFA_STATUS EmvCo_dosetPoll(jboolean enable); |
| extern void nativeNfcTag_registerNdefTypeHandler(); |
| extern void nativeLlcpConnectionlessSocket_receiveData(uint8_t* data, |
| uint32_t len, |
| uint32_t remote_sap); |
| extern tNFA_STATUS SetScreenState(int state); |
| extern tNFA_STATUS SendAutonomousMode(int state, uint8_t num); |
| // Factory Test Code --start |
| extern tNFA_STATUS Nxp_SelfTest(uint8_t testcase, uint8_t* param); |
| extern void SetCbStatus(tNFA_STATUS status); |
| extern tNFA_STATUS GetCbStatus(void); |
| static void nfaNxpSelfTestNtfTimerCb(union sigval); |
| extern tNFA_STATUS ResetEseSession(); |
| // Factory Test Code --end |
| extern bool getReconnectState(void); |
| extern tNFA_STATUS SetVenConfigValue(jint nfcMode); |
| extern tNFA_STATUS SetHfoConfigValue(void); |
| extern tNFA_STATUS SetUICC_SWPBitRate(bool); |
| extern tNFA_STATUS GetNumNFCEEConfigured(void); |
| extern void nativeNfcTag_acquireRfInterfaceMutexLock(); |
| extern void nativeNfcTag_releaseRfInterfaceMutexLock(); |
| extern tNFA_STATUS NxpNfc_Write_Cmd_Common(uint8_t retlen, uint8_t* buffer); |
| #if (NXP_EXTNS == TRUE) |
| extern bool gIsWaiting4Deact2SleepNtf; |
| extern bool gGotDeact2IdleNtf; |
| bool nfcManager_isTransanctionOnGoing(bool isInstallRequest); |
| bool nfcManager_isRequestPending(void); |
| extern tNFA_STATUS enableSWPInterface(); |
| extern tNFA_STATUS NxpNfc_Send_CoreResetInit_Cmd(void); |
| jmethodID gCachedNfcManagerNotifyFwDwnldRequested; |
| extern tNFA_STATUS SendAGCDebugCommand(); |
| extern tNFA_STATUS Set_EERegisterValue(uint16_t RegAddr, uint8_t bitVal); |
| extern void nativeNfcTag_cacheNonNciCardDetection(); |
| extern void nativeNfcTag_handleNonNciCardDetection( |
| tNFA_CONN_EVT_DATA* eventData); |
| extern void nativeNfcTag_handleNonNciMultiCardDetection( |
| uint8_t connEvent, tNFA_CONN_EVT_DATA* eventData); |
| extern tNFA_STATUS NxpNfcUpdateEeprom(uint8_t* param, uint8_t len, |
| uint8_t* val); |
| extern uint8_t checkTagNtf; |
| extern uint8_t checkCmdSent; |
| #endif |
| } // namespace android |
| |
| /***************************************************************************** |
| ** |
| ** public variables and functions |
| ** |
| *****************************************************************************/ |
| bool gActivated = false; |
| SyncEvent gDeactivatedEvent; |
| |
| namespace android { |
| int gGeneralPowershutDown = 0; |
| jmethodID gCachedNfcManagerNotifyNdefMessageListeners; |
| jmethodID gCachedNfcManagerNotifyTransactionListeners; |
| jmethodID gCachedNfcManagerNotifyConnectivityListeners; |
| jmethodID gCachedNfcManagerNotifyEmvcoMultiCardDetectedListeners; |
| jmethodID gCachedNfcManagerNotifyLlcpLinkActivation; |
| jmethodID gCachedNfcManagerNotifyLlcpLinkDeactivated; |
| jmethodID gCachedNfcManagerNotifyLlcpFirstPacketReceived; |
| jmethodID gCachedNfcManagerNotifySeFieldActivated; |
| jmethodID gCachedNfcManagerNotifySeFieldDeactivated; |
| jmethodID gCachedNfcManagerNotifySeListenActivated; |
| jmethodID gCachedNfcManagerNotifySeListenDeactivated; |
| jmethodID gCachedNfcManagerNotifyHostEmuActivated; |
| jmethodID gCachedNfcManagerNotifyHostEmuData; |
| jmethodID gCachedNfcManagerNotifyHostEmuDeactivated; |
| jmethodID gCachedNfcManagerNotifyRfFieldActivated; |
| jmethodID gCachedNfcManagerNotifyRfFieldDeactivated; |
| jmethodID gCachedNfcManagerNotifyAidRoutingTableFull; |
| #if (NXP_EXTNS == TRUE) |
| int gMaxEERecoveryTimeout = MAX_EE_RECOVERY_TIMEOUT; |
| jmethodID gCachedNfcManagerNotifyUiccStatusEvent; |
| jmethodID gCachedNfcManagerNotifyT3tConfigure; |
| jmethodID gCachedNfcManagerNotifyJcosDownloadInProgress; |
| jmethodID gCachedNfcManagerNotifyReRoutingEntry; |
| #endif |
| const char* gNativeP2pDeviceClassName = |
| "com/android/nfc/dhimpl/NativeP2pDevice"; |
| const char* gNativeLlcpServiceSocketClassName = |
| "com/android/nfc/dhimpl/NativeLlcpServiceSocket"; |
| const char* gNativeLlcpConnectionlessSocketClassName = |
| "com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket"; |
| const char* gNativeLlcpSocketClassName = |
| "com/android/nfc/dhimpl/NativeLlcpSocket"; |
| const char* gNativeNfcTagClassName = "com/android/nfc/dhimpl/NativeNfcTag"; |
| const char* gNativeNfcManagerClassName = |
| "com/android/nfc/dhimpl/NativeNfcManager"; |
| const char* gNativeNfcSecureElementClassName = |
| "com/android/nfc/dhimpl/NativeNfcSecureElement"; |
| const char* gNativeNfcAlaClassName = "com/android/nfc/dhimpl/NativeNfcAla"; |
| const char* gNativeNfcMposManagerClassName = |
| "com/android/nfc/dhimpl/NativeNfcMposManager"; |
| void doStartupConfig(); |
| void startStopPolling(bool isStartPolling); |
| void startRfDiscovery(bool isStart); |
| void setUiccIdleTimeout(bool enable); |
| bool isDiscoveryStarted(); |
| void requestFwDownload(); |
| #if (NXP_EXTNS == TRUE) |
| void enableRfDiscovery(); |
| void disableRfDiscovery(); |
| void storeLastDiscoveryParams(int technologies_mask, bool enable_lptd, |
| bool reader_mode, bool enable_p2p, bool restart); |
| #endif |
| } // namespace android |
| |
| /***************************************************************************** |
| ** |
| ** private variables and functions |
| ** |
| *****************************************************************************/ |
| namespace android { |
| static jint sLastError = ERROR_BUFFER_TOO_SMALL; |
| static jmethodID sCachedNfcManagerNotifySeApduReceived; |
| static jmethodID sCachedNfcManagerNotifySeMifareAccess; |
| static jmethodID sCachedNfcManagerNotifySeEmvCardRemoval; |
| static jmethodID sCachedNfcManagerNotifyTargetDeselected; |
| static SyncEvent sNfaEnableEvent; // event for NFA_Enable() |
| static SyncEvent sNfaDisableEvent; // event for NFA_Disable() |
| SyncEvent sNfaEnableDisablePollingEvent; // event for NFA_EnablePolling(), |
| // NFA_DisablePolling() |
| SyncEvent sNfaSetConfigEvent; // event for Set_Config.... |
| SyncEvent sNfaGetConfigEvent; // event for Get_Config.... |
| |
| static bool sIsNfaEnabled = false; |
| static bool sDiscoveryEnabled = false; // is polling or listening |
| static bool sPollingEnabled = false; // is polling for tag? |
| static bool sIsDisabling = false; |
| static bool sRfEnabled = false; // whether RF discovery is enabled |
| static bool sSeRfActive = false; // whether RF with SE is likely active |
| static bool sReaderModeEnabled = |
| false; // whether we're only reading tags, not allowing P2p/card emu |
| static bool sP2pEnabled = false; |
| static bool sP2pActive = false; // whether p2p was last active |
| static bool sAbortConnlessWait = false; |
| static jint sLfT3tMax = 0; |
| |
| static uint8_t sIsSecElemSelected = 0; // has NFC service selected a sec elem |
| static uint8_t sIsSecElemDetected = 0; // has NFC service deselected a sec elem |
| static bool sDiscCmdwhleNfcOff = false; |
| static uint8_t sAutonomousSet = 0; |
| |
| #define CONFIG_UPDATE_TECH_MASK (1 << 1) |
| #define TRANSACTION_TIMER_VALUE 50 |
| #define DEFAULT_TECH_MASK \ |
| (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F | \ |
| NFA_TECHNOLOGY_MASK_V | NFA_TECHNOLOGY_MASK_B_PRIME | \ |
| NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE | \ |
| NFA_TECHNOLOGY_MASK_KOVIO) |
| #define DEFAULT_DISCOVERY_DURATION 500 |
| #define READER_MODE_DISCOVERY_DURATION 200 |
| #if (NXP_EXTNS == TRUE) |
| static bool gsNfaPartialEnabled = false; |
| static uint16_t sEnableStatus = false; |
| SyncEvent sNfaGetRoutingEvent; // event for Get_Routing.... |
| static bool sProvisionMode = false; |
| SyncEvent sNfceeHciCbEnableEvent; |
| SyncEvent sNfceeHciCbDisableEvent; |
| #define DUAL_UICC_FEATURE_NOT_AVAILABLE 0xED; |
| #define STATUS_UNKNOWN_ERROR 0xEF; |
| |
| enum { UICC_CONFIGURED, UICC_NOT_CONFIGURED }; |
| typedef enum dual_uicc_error_states { |
| DUAL_UICC_ERROR_NFCC_BUSY = 0x02, |
| DUAL_UICC_ERROR_SELECT_FAILED, |
| DUAL_UICC_ERROR_NFC_TURNING_OFF, |
| DUAL_UICC_ERROR_INVALID_SLOT, |
| DUAL_UICC_ERROR_STATUS_UNKNOWN |
| } dual_uicc_error_state_t; |
| static tNFA_STATUS nfcManagerEnableNfc(NfcAdaptation& theInstance); |
| #endif |
| |
| static int screenstate = NFA_SCREEN_STATE_OFF_LOCKED; |
| static bool pendingScreenState = false; |
| static void nfcManager_doSetScreenState(JNIEnv* e, jobject o, |
| jint screen_state_mask); |
| static jint nfcManager_doGetNciVersion(JNIEnv*, jobject); |
| static int NFA_SCREEN_POLLING_TAG_MASK = 0x10; |
| static void nfcManager_doSetScreenOrPowerState(JNIEnv* e, jobject o, |
| jint state); |
| static void StoreScreenState(int state); |
| int getScreenState(); |
| static void nfaConnectionCallback(uint8_t event, tNFA_CONN_EVT_DATA* eventData); |
| static void nfaDeviceManagementCallback(uint8_t event, |
| tNFA_DM_CBACK_DATA* eventData); |
| static bool isPeerToPeer(tNFA_ACTIVATED& activated); |
| static bool isListenMode(tNFA_ACTIVATED& activated); |
| static tNFA_STATUS stopPolling_rfDiscoveryDisabled(); |
| static tNFA_STATUS startPolling_rfDiscoveryDisabled( |
| tNFA_TECHNOLOGY_MASK tech_mask); |
| |
| static int nfcManager_getChipVer(JNIEnv* e, jobject o); |
| static jbyteArray nfcManager_getFwFileName(JNIEnv* e, jobject o); |
| static int nfcManager_getNfcInitTimeout(JNIEnv* e, jobject o); |
| static int nfcManager_doJcosDownload(JNIEnv* e, jobject o); |
| static void nfcManager_doCommitRouting(JNIEnv* e, jobject o); |
| static jint nfcManager_getSecureElementTechList(JNIEnv* e, jobject o); |
| static void nfcManager_setSecureElementListenTechMask(JNIEnv* e, jobject o, |
| jint tech_mask); |
| static void notifyPollingEventwhileNfcOff(); |
| |
| static uint8_t getJCOPOS_UpdaterState(); |
| void DWPChannel_init(IChannel_t* DWP); |
| IChannel_t Dwp; |
| static uint16_t sCurrentConfigLen; |
| static uint8_t sConfig[256]; |
| static int prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED; |
| #if (NXP_EXTNS == TRUE) |
| static uint8_t sNfcState = NFC_OFF; |
| bool isp2pActivated(); |
| static void nfcManager_doSetNfcMode(JNIEnv* e, jobject o, jint nfcMode); |
| typedef struct { |
| uint8_t sUicc1Cntx[256]; |
| uint16_t sUicc1CntxLen; |
| uint8_t sUicc2Cntx[256]; |
| uint16_t sUicc2CntxLen; |
| uint8_t sUicc1TechCapblty[12]; |
| uint8_t sUicc2TechCapblty[12]; |
| uint8_t sUicc1SessionId[8]; |
| uint8_t sUicc2SessionId[8]; |
| uint8_t sUicc1SessionIdLen; |
| uint8_t sUicc2SessionIdLen; |
| uint8_t uiccActivStat = 0; |
| uint8_t uiccConfigStat = 0; |
| unsigned long dualUiccEnable = 0; |
| } dual_uicc_info_t; |
| dual_uicc_info_t dualUiccInfo; |
| typedef enum { |
| UICC_CONNECTED_0, |
| UICC_CONNECTED_1, |
| UICC_CONNECTED_2 |
| } uicc_enumeration_t; |
| |
| #endif |
| static uint8_t sLongGuardTime[] = {0x00, 0x20}; |
| static uint8_t sDefaultGuardTime[] = {0x00, 0x11}; |
| #if (NXP_EXTNS == TRUE) |
| Mutex gTransactionMutex; |
| const char* cur_transaction_handle = NULL; |
| /*Proprietary cmd sent to HAL to send reader mode flag |
| * Last byte of sProprietaryCmdBuf contains ReaderMode flag */ |
| #define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE |
| static uint8_t sProprietaryCmdBuf[] = {0xFE, 0xFE, 0xFE, 0x00}; |
| uint8_t felicaReader_Disc_id; |
| static void NxpResponsePropCmd_Cb(uint8_t event, uint16_t param_len, |
| uint8_t* p_param); |
| static int sTechMask = 0; // Copy of Tech Mask used in doEnableReaderMode |
| static SyncEvent sRespCbEvent; |
| bool rfActivation = false; |
| static void* pollT3TThread(void* arg); |
| static bool switchP2PToT3TRead(uint8_t disc_id); |
| static bool isActivatedTypeF(tNFA_ACTIVATED& activated); |
| typedef enum felicaReaderMode_state { |
| STATE_IDLE = 0x00, |
| STATE_NFCDEP_ACTIVATED_NFCDEP_INTF, |
| STATE_DEACTIVATED_TO_SLEEP, |
| STATE_FRAMERF_INTF_SELECTED, |
| } eFelicaReaderModeState_t; |
| static eFelicaReaderModeState_t gFelicaReaderState = STATE_IDLE; |
| |
| uint16_t sRoutingBuffLen; |
| static uint8_t sRoutingBuff[MAX_GET_ROUTING_BUFFER_SIZE]; |
| static uint8_t sNfceeConfigured; |
| static uint8_t sCheckNfceeFlag; |
| void checkforNfceeBuffer(); |
| static uint32_t eSEPhyIntfInResponsive(tNFA_DM_CBACK_DATA* pEvtData); |
| static void recoverEseConnectivity(); |
| void checkforNfceeConfig(uint8_t type); |
| static void performHCIInitialization(JNIEnv* e, jobject o); |
| void performNfceeETSI12Config(); |
| tNFA_STATUS getUICC_RF_Param_SetSWPBitRate(); |
| // self test start |
| static IntervalTimer |
| nfaNxpSelfTestNtfTimer; // notification timer for swp self test |
| static IntervalTimer uiccEventTimer; // notification timer for uicc select |
| static void notifyUiccEvent(union sigval); |
| static SyncEvent sNfaNxpNtfEvent; |
| static SyncEvent sNfaSetPowerSubState; // event for power substate |
| static void nfaNxpSelfTestNtfTimerCb(union sigval); |
| static int nfcManager_setPreferredSimSlot(JNIEnv* e, jobject o, jint uiccSlot); |
| static void nfcManager_doSetEEPROM(JNIEnv* e, jobject o, jbyteArray val); |
| static jint nfcManager_getFwVersion(JNIEnv* e, jobject o); |
| static jint nfcManager_SWPSelfTest(JNIEnv* e, jobject o, jint ch); |
| static void nfcManager_doPrbsOff(JNIEnv* e, jobject o); |
| static void nfcManager_doPrbsOn(JNIEnv* e, jobject o, jint prbs, jint hw_prbs, |
| jint tech, jint rate); |
| static void nfcManager_Enablep2p(JNIEnv* e, jobject o, jboolean p2pFlag); |
| // self test end |
| static void nfcManager_setProvisionMode(JNIEnv* e, jobject o, |
| jboolean provisionMode); |
| static bool nfcManager_doPartialDeInitialize(); |
| static int nfcManager_doSelectUicc(JNIEnv* e, jobject o, jint uiccSlot); |
| static int nfcManager_doGetSelectedUicc(JNIEnv* e, jobject o); |
| static void getUiccContext(int uiccSlot); |
| static void update_uicc_context_info(); |
| static int getUiccSession(); |
| static void read_uicc_context(uint8_t* uiccContext, uint16_t uiccContextLen, |
| uint8_t* uiccTechCap, uint16_t uiccTechCapLen, |
| uint8_t block, uint8_t slotnum); |
| static void write_uicc_context(uint8_t* uiccContext, uint16_t uiccContextLen, |
| uint8_t* uiccTechCap, uint16_t uiccTechCapLen, |
| uint8_t block, uint8_t slotnum); |
| static uint16_t calc_crc16(uint8_t* pBuff, uint16_t wLen); |
| |
| static int nfcManager_staticDualUicc_Precondition(int uiccSlot); |
| void checkforESERemoval(); |
| bool nfcManager_sendEmptyDataMsg(); |
| bool gIsEmptyRspSentByHceFApk = false; |
| |
| static int nfcManager_doGetSeInterface(JNIEnv* e, jobject o, jint type); |
| |
| extern bool scoreGenericNtf; |
| tNFC_FW_VERSION get_fw_version(); |
| bool isNfcInitializationDone(); |
| static uint16_t discDuration = 0x00; |
| uint16_t getrfDiscoveryDuration(); |
| typedef struct enableAGC_debug { |
| long enableAGC; // config param |
| bool AGCdebugstarted; // flag to indicate agc ongoing |
| bool AGCdebugrunning; // flag to indicate agc running or stopped. |
| } enableAGC_debug_t; |
| static enableAGC_debug_t menableAGC_debug_t; |
| void* enableAGCThread(void* arg); |
| static void nfcManagerEnableAGCDebug(uint8_t connEvent); |
| void set_AGC_process_state(bool state); |
| bool get_AGC_process_state(); |
| |
| void checkforTranscation(uint8_t connEvent, void* eventData); |
| void sig_handler(int signo); |
| void cleanup_timer(); |
| tNFA_STATUS updateEeprom(uint8_t* param, uint8_t len, uint8_t* val); |
| /* Transaction Events in order */ |
| static IntervalTimer scleanupTimerProc_rffield; |
| typedef enum transcation_events { |
| NFA_TRANS_DEFAULT = 0x00, |
| NFA_TRANS_ACTIVATED_EVT, |
| NFA_TRANS_EE_ACTION_EVT, |
| NFA_TRANS_DM_RF_FIELD_EVT, |
| NFA_TRANS_DM_RF_FIELD_EVT_ON, |
| NFA_TRANS_DM_RF_TRANS_START, |
| NFA_TRANS_DM_RF_FIELD_EVT_OFF, |
| NFA_TRANS_DM_RF_TRANS_PROGRESS, |
| NFA_TRANS_DM_RF_TRANS_END, |
| NFA_TRANS_MIFARE_ACT_EVT, |
| NFA_TRANS_CE_ACTIVATED = 0x18, |
| NFA_TRANS_CE_DEACTIVATED = 0x19, |
| } eTranscation_events_t; |
| |
| typedef enum se_client { |
| DEFAULT = 0x00, |
| LDR_SRVCE, |
| JCOP_SRVCE, |
| LTSM_SRVCE |
| } seClient_t; |
| |
| /*Structure to store discovery parameters*/ |
| typedef struct discovery_Parameters { |
| int technologies_mask; |
| bool enable_lptd; |
| bool reader_mode; |
| bool enable_p2p; |
| bool restart; |
| } discovery_Parameters_t; |
| |
| discovery_Parameters_t mDiscParams; |
| /*Structure to store transcation result*/ |
| typedef struct Transcation_Check { |
| bool trans_in_progress; |
| char last_request; |
| struct nfc_jni_native_data* transaction_nat; |
| eScreenState_t last_screen_state_request; |
| eTranscation_events_t current_transcation_state; |
| discovery_Parameters_t discovery_params; |
| int t3thandle; |
| bool isInstallRequest; |
| #endif |
| } // namespace android |
| Transcation_Check_t; |
| static struct nfc_jni_native_data* gNativeData = NULL; |
| #if (NXP_EXTNS == TRUE) |
| static bool sRfFieldOff = true; |
| static bool gsRouteUpdated = false; |
| /***P2P-Prio Logic for Multiprotocol***/ |
| static uint8_t multiprotocol_flag = 1; |
| static uint8_t multiprotocol_detected = 0; |
| void* p2p_prio_logic_multiprotocol(void* arg); |
| static IntervalTimer multiprotocol_timer; |
| pthread_t multiprotocol_thread; |
| void reconfigure_poll_cb(union sigval); |
| void clear_multiprotocol(); |
| void multiprotocol_clear_flag(union sigval); |
| bool update_transaction_stat(const char* req_handle, |
| transaction_state_t req_state); |
| bool isLowRamDevice(); |
| #endif |
| extern tNFA_INTF_TYPE sCurrentRfInterface; |
| static Transcation_Check_t transaction_data; |
| static void nfcManager_enableDiscovery(JNIEnv* e, jobject o, |
| jint technologies_mask, |
| jboolean enable_lptd, |
| jboolean reader_mode, |
| jboolean enable_p2p, jboolean restart); |
| void nfcManager_disableDiscovery(JNIEnv*, jobject); |
| static char get_last_request(void); |
| static void set_last_request(char status, struct nfc_jni_native_data* nat); |
| static eScreenState_t get_lastScreenStateRequest(void); |
| static void set_lastScreenStateRequest(eScreenState_t status); |
| void* enableThread(void* arg); |
| static IntervalTimer scleanupTimerProc_transaction; |
| static bool gIsDtaEnabled = false; |
| |
| static void nfcManager_getFeatureList(); |
| static void register_signal_handler(); |
| ///////////////////////////////////////////////////////////// |
| ///////////////////////////////////////////////////////////// |
| |
| /******************************************************************************* |
| ** |
| ** Function: getNative |
| ** |
| ** Description: Get native data |
| ** |
| ** Returns: Native data structure. |
| ** |
| *******************************************************************************/ |
| nfc_jni_native_data* getNative(JNIEnv* e, jobject o) { |
| static struct nfc_jni_native_data* sCachedNat = NULL; |
| if (e) { |
| sCachedNat = nfc_jni_get_nat(e, o); |
| } |
| return sCachedNat; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: handleRfDiscoveryEvent |
| ** |
| ** Description: Handle RF-discovery events from the stack. |
| ** discoveredDevice: Discovered device. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void handleRfDiscoveryEvent(tNFC_RESULT_DEVT* discoveredDevice) { |
| int thread_ret; |
| |
| if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) { |
| // there is more discovery notification coming |
| NfcTag::getInstance().mNumDiscNtf++; |
| return; |
| } |
| |
| NfcTag::getInstance().mNumDiscNtf++; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Total Notifications - %d ", __FUNCTION__, |
| NfcTag::getInstance().mNumDiscNtf); |
| |
| if (NfcTag::getInstance().mNumDiscNtf > 1) { |
| NfcTag::getInstance().mIsMultiProtocolTag = true; |
| } |
| |
| bool isP2p = NfcTag::getInstance().isP2pDiscovered(); |
| |
| if (!sReaderModeEnabled && isP2p) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Select peer device", __FUNCTION__); |
| #if (NXP_EXTNS == TRUE) |
| if (multiprotocol_detected == 1) { |
| multiprotocol_timer.kill(); |
| } |
| #endif |
| NfcTag::getInstance().selectP2p(); |
| } |
| #if (NXP_EXTNS == TRUE) |
| else if (!sReaderModeEnabled && multiprotocol_flag) { |
| NfcTag::getInstance().mNumDiscNtf = 0x00; |
| multiprotocol_flag = 0; |
| multiprotocol_detected = 1; |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: starting p2p prio logic for multiprotocol tags", __FUNCTION__); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| thread_ret = pthread_create(&multiprotocol_thread, &attr, |
| p2p_prio_logic_multiprotocol, NULL); |
| if (thread_ret != 0) |
| LOG(ERROR) << StringPrintf("%s: unable to create the thread", |
| __FUNCTION__); |
| pthread_attr_destroy(&attr); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: starting timer for reconfigure default polling callback", |
| __FUNCTION__); |
| multiprotocol_timer.set(300, reconfigure_poll_cb); |
| } |
| #endif |
| else { |
| multiprotocol_flag = 1; |
| #if (NXP_EXTNS == TRUE) |
| NfcTag::getInstance().mNumDiscNtf--; |
| #endif |
| NfcTag::getInstance().selectFirstTag(); |
| } |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| void* p2p_prio_logic_multiprotocol(void* arg) { |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| tNFA_TECHNOLOGY_MASK tech_mask = 0x00; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __FUNCTION__); |
| /* Do not need if it is already in screen off state */ |
| if (!(getScreenState() & |
| (NFA_SCREEN_STATE_OFF_LOCKED | NFA_SCREEN_STATE_OFF_UNLOCKED))) { |
| /* Stop polling */ |
| if (sRfEnabled) { |
| startRfDiscovery(false); |
| } |
| |
| { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| status = NFA_DisablePolling(); |
| if (status == NFA_STATUS_OK) { |
| sNfaEnableDisablePollingEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("%s: Failed to disable polling; error=0x%X", |
| __FUNCTION__, status); |
| } |
| |
| if (multiprotocol_detected) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: configure polling to tech F only", __FUNCTION__); |
| tech_mask = NFA_TECHNOLOGY_MASK_F; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: re-configure polling to default", __FUNCTION__); |
| unsigned long num = 0; |
| if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num))) |
| tech_mask = num; |
| else |
| tech_mask = DEFAULT_TECH_MASK; |
| } |
| |
| { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| status = NFA_EnablePolling(tech_mask); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for enable event", __FUNCTION__); |
| sNfaEnableDisablePollingEvent.wait(); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", |
| __FUNCTION__, status); |
| } |
| } |
| |
| /* start polling */ |
| if (!sRfEnabled) { |
| startRfDiscovery(true); |
| } |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __FUNCTION__); |
| return NULL; |
| } |
| |
| void reconfigure_poll_cb(union sigval) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Prio_Logic_multiprotocol timer expire"); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("CallBack Reconfiguring the POLL to Default"); |
| clear_multiprotocol(); |
| multiprotocol_timer.set(300, multiprotocol_clear_flag); |
| } |
| |
| void clear_multiprotocol() { |
| int thread_ret; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("clear_multiprotocol"); |
| multiprotocol_detected = 0; |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| thread_ret = pthread_create(&multiprotocol_thread, &attr, |
| p2p_prio_logic_multiprotocol, NULL); |
| if (thread_ret != 0) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("unable to create the thread"); |
| pthread_attr_destroy(&attr); |
| } |
| |
| void multiprotocol_clear_flag(union sigval) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("multiprotocol_clear_flag"); |
| multiprotocol_flag = 1; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfaConnectionCallback |
| ** |
| ** Description: Receive connection-related events from stack. |
| ** connEvent: Event code. |
| ** eventData: Event data. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfaConnectionCallback(uint8_t connEvent, |
| tNFA_CONN_EVT_DATA* eventData) { |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| static uint8_t prev_more_val = 0x00; |
| uint8_t cur_more_val = 0x00; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Connection Event = %u", __func__, connEvent); |
| |
| switch (connEvent) { |
| case NFA_POLL_ENABLED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_POLL_ENABLED_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } break; |
| |
| case NFA_POLL_DISABLED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_POLL_DISABLED_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } break; |
| |
| case NFA_RF_DISCOVERY_STARTED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_RF_DISCOVERY_STARTED_EVT: status = 0x%0X", |
| __func__, eventData->status); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } break; |
| |
| case NFA_RF_DISCOVERY_STOPPED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = 0x%0X", |
| __func__, eventData->status); |
| notifyPollingEventwhileNfcOff(); |
| if (getReconnectState() == true) { |
| eventData->deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP; |
| NfcTag::getInstance().setDeactivationState(eventData->deactivated); |
| if (gIsTagDeactivating) { |
| NfcTag::getInstance().setActive(false); |
| nativeNfcTag_doDeactivateStatus(0); |
| } |
| } |
| /* sNfaEnableDisablePollingEvent shall be notified in all cases |
| * otherwise RF stop activity will block wait */ |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } break; |
| |
| case NFA_DISC_RESULT_EVT: { |
| status = eventData->disc_result.status; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_DISC_RESULT_EVT: status = 0x%0X", __func__, status); |
| cur_more_val = eventData->disc_result.discovery_ntf.more; |
| if ((cur_more_val == 0x01) && (prev_more_val != 0x02)) { |
| LOG(ERROR) << StringPrintf("%s: NFA_DISC_RESULT_EVT: Failed", __func__); |
| status = NFA_STATUS_FAILED; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DISC_RESULT_EVT: Success", __func__); |
| status = NFA_STATUS_OK; |
| prev_more_val = cur_more_val; |
| } |
| #if (NXP_EXTNS == TRUE) |
| #if (NFC_NXP_NON_STD_CARD == TRUE) |
| if (gIsSelectingRfInterface) { |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_DISC_RESULT_EVT: reSelect function didn't save the " |
| "modification", |
| __func__); |
| if (cur_more_val == 0x00) { |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_DISC_RESULT_EVT: error, select any one tag", __func__); |
| multiprotocol_flag = 0; |
| } |
| } |
| #endif |
| #endif |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_DISC_RESULT_EVT: error, status = 0x%0X", __func__, status); |
| NfcTag::getInstance().mNumDiscNtf = 0; |
| } else { |
| NfcTag::getInstance().connectionEventHandler(connEvent, eventData); |
| handleRfDiscoveryEvent(&eventData->disc_result.discovery_ntf); |
| } |
| } break; |
| |
| case NFA_SELECT_RESULT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_SELECT_RESULT_EVT: status = 0x%0X, gIsSelectingRfInterface " |
| "= %d, sIsDisabling = %d", |
| __func__, eventData->status, gIsSelectingRfInterface, sIsDisabling); |
| |
| if (sIsDisabling) break; |
| |
| if (eventData->status != NFA_STATUS_OK) { |
| if (gIsSelectingRfInterface) { |
| #if (NXP_EXTNS == TRUE) |
| #if (NFC_NXP_NON_STD_CARD == TRUE) |
| nativeNfcTag_cacheNonNciCardDetection(); |
| #endif |
| #endif |
| nativeNfcTag_doConnectStatus(false); |
| } |
| #if (NXP_EXTNS == TRUE) |
| NfcTag::getInstance().selectCompleteStatus(false); |
| NfcTag::getInstance().mNumDiscNtf = 0x00; |
| #endif |
| NfcTag::getInstance().mTechListIndex = 0; |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_SELECT_RESULT_EVT: error, status = 0x%0X", __func__, |
| eventData->status); |
| NFA_Deactivate(false); |
| } |
| #if (NXP_EXTNS == TRUE) |
| else if (sReaderModeEnabled && |
| (gFelicaReaderState == STATE_DEACTIVATED_TO_SLEEP)) { |
| SyncEventGuard g(sRespCbEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Sending Sem Post for Select Event", __func__); |
| sRespCbEvent.notifyOne(); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_SELECT_RESULT_EVT: Frame RF Interface Selected", __func__); |
| gFelicaReaderState = STATE_FRAMERF_INTF_SELECTED; |
| } |
| #endif |
| } break; |
| |
| case NFA_DEACTIVATE_FAIL_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DEACTIVATE_FAIL_EVT: status = 0x%0X", |
| __func__, eventData->status); |
| { |
| SyncEventGuard guard(gDeactivatedEvent); |
| gActivated = false; |
| gDeactivatedEvent.notifyOne(); |
| } |
| { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } |
| } break; |
| |
| case NFA_ACTIVATED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d", |
| __func__, gIsSelectingRfInterface, sIsDisabling); |
| #if (NXP_EXTNS == TRUE) |
| rfActivation = true; |
| |
| checkforTranscation(NFA_ACTIVATED_EVT, (void*)eventData); |
| |
| NfcTag::getInstance().selectCompleteStatus(true); |
| |
| /***P2P-Prio Logic for Multiprotocol***/ |
| if ((eventData->activated.activate_ntf.protocol == |
| NFA_PROTOCOL_NFC_DEP) && |
| (multiprotocol_detected == 1)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Prio_Logic_multiprotocol stop timer"); |
| multiprotocol_timer.kill(); |
| } |
| |
| if ((eventData->activated.activate_ntf.protocol == NFA_PROTOCOL_T3T) && |
| (multiprotocol_detected == 1)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Prio_Logic_multiprotocol stop timer"); |
| multiprotocol_timer.kill(); |
| clear_multiprotocol(); |
| } |
| #endif |
| if (nfcFL.nfcNxpEse) { |
| if (nfcFL.eseFL._ESE_ETSI_READER_ENABLE) { |
| /* |
| * Handle Reader over SWP START_READER_EVENT |
| * */ |
| if (eventData->activated.activate_ntf.intf_param.type == |
| NCI_INTERFACE_UICC_DIRECT_STAT || |
| eventData->activated.activate_ntf.intf_param.type == |
| NCI_INTERFACE_ESE_DIRECT_STAT) { |
| MposManager::getInstance().setEtsiReaederState( |
| STATE_SE_RDR_MODE_ACTIVATED); |
| MposManager::getInstance().notifyEEReaderEvent( |
| ETSI_READER_ACTIVATED); |
| break; |
| } |
| } |
| } |
| if ((eventData->activated.activate_ntf.protocol != |
| NFA_PROTOCOL_NFC_DEP) && |
| (!isListenMode(eventData->activated))) { |
| nativeNfcTag_setRfInterface( |
| (tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param.type); |
| } |
| |
| if (EXTNS_GetConnectFlag() == true) { |
| NfcTag::getInstance().setActivationState(); |
| nativeNfcTag_doConnectStatus(true); |
| break; |
| } |
| |
| NfcTag::getInstance().setActive(true); |
| |
| if (sIsDisabling || !sIsNfaEnabled) break; |
| |
| gActivated = true; |
| |
| NfcTag::getInstance().setActivationState(); |
| |
| if (gIsSelectingRfInterface) { |
| nativeNfcTag_doConnectStatus(true); |
| if (NfcTag::getInstance().isCashBeeActivated() == true || |
| NfcTag::getInstance().isEzLinkTagActivated() == true) { |
| NfcTag::getInstance().connectionEventHandler(NFA_ACTIVATED_UPDATE_EVT, |
| eventData); |
| } |
| break; |
| } |
| |
| nativeNfcTag_resetPresenceCheck(); |
| |
| if (isPeerToPeer(eventData->activated)) { |
| if (sReaderModeEnabled) { |
| #if (NXP_EXTNS == TRUE) |
| /* If last transaction is complete or prev state is idle |
| * then proceed to next state*/ |
| if (isActivatedTypeF(eventData->activated) && |
| (sTechMask & NFA_TECHNOLOGY_MASK_F) && |
| ((gFelicaReaderState == STATE_IDLE) || |
| (gFelicaReaderState == STATE_FRAMERF_INTF_SELECTED))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Activating Reader Mode in P2P ", __func__); |
| gFelicaReaderState = STATE_NFCDEP_ACTIVATED_NFCDEP_INTF; |
| switchP2PToT3TRead(eventData->activated.activate_ntf.rf_disc_id); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Invalid FelicaReaderState : %d ", |
| __func__, gFelicaReaderState); |
| gFelicaReaderState = STATE_IDLE; |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Ignoring P2P target in reader mode.", __func__); |
| NFA_Deactivate(false); |
| #if (NXP_EXTNS == TRUE) |
| } |
| #endif |
| break; |
| } |
| sP2pActive = true; |
| #if (NXP_EXTNS == FALSE) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_ACTIVATED_EVT; is p2p", __func__); |
| if (NFC_GetNCIVersion() == NCI_VERSION_1_0) { |
| // Disable RF field events in case of p2p |
| uint8_t nfa_disable_rf_events[] = {0x00}; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Disabling RF field events", __func__); |
| status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, |
| sizeof(nfa_disable_rf_events), |
| &nfa_disable_rf_events[0]); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Disabled RF field events", __func__); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Failed to disable RF field events", |
| __func__); |
| } |
| |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_ACTIVATED_EVT: P2P is activated", __func__); |
| if ((nfcFL.nfcNxpEse && |
| nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) && |
| (SecureElement::getInstance().mIsWiredModeOpen && |
| SecureElement::getInstance().mPassiveListenEnabled == true)) { |
| SecureElement::getInstance().mPassiveListenTimer.kill(); |
| } |
| |
| /* For Secure Element, consider the field to be on while P2P is active |
| */ |
| SecureElement::getInstance().notifyRfFieldEvent(true); |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfcNxpEse && (nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME != |
| nfcFL.eseFL._ESE_WIRED_MODE_RESUME)) { |
| SecureElement::getInstance().setDwpTranseiveState( |
| false, NFCC_ACTIVATED_NTF); |
| } |
| #endif |
| } else if (pn544InteropIsBusy() == false) { |
| #if (NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE) |
| nativeNfcTag_handleNonNciMultiCardDetection(connEvent, eventData); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: scoreGenericNtf = 0x%x", __func__, scoreGenericNtf); |
| if (scoreGenericNtf == true) { |
| if ((eventData->activated.activate_ntf.intf_param.type == |
| NFC_INTERFACE_ISO_DEP) && |
| (eventData->activated.activate_ntf.protocol == |
| NFC_PROTOCOL_ISO_DEP)) { |
| nativeNfcTag_handleNonNciCardDetection(eventData); |
| } |
| scoreGenericNtf = false; |
| } |
| #else |
| NfcTag::getInstance().connectionEventHandler(connEvent, eventData); |
| |
| if (NfcTag::getInstance().mNumDiscNtf) { |
| NFA_Deactivate(true); |
| } |
| #endif |
| /* We know it is not activating for P2P. If it activated in |
| * listen mode then it is likely for an SE transaction. |
| * Send the RF Event */ |
| if (isListenMode(eventData->activated)) { |
| sSeRfActive = true; |
| SecureElement::getInstance().notifyListenModeState(true); |
| #if (NXP_EXTNS == TRUE) |
| if ((nfcFL.nfcNxpEse && |
| nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) && |
| (SecureElement::getInstance().mIsWiredModeOpen && |
| SecureElement::getInstance().mPassiveListenEnabled == true)) { |
| SecureElement::getInstance().mPassiveListenTimer.kill(); |
| } |
| #endif |
| } |
| } |
| } |
| break; |
| |
| case NFA_DEACTIVATED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_DEACTIVATED_EVT: Type=%u, gIsTagDeactivating=%d", __func__, |
| eventData->deactivated.type, gIsTagDeactivating); |
| #if (NXP_EXTNS == TRUE) |
| rfActivation = false; |
| if ((nfcFL.chipType == pn547C2) && |
| (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE)) { |
| checkforTranscation(NFA_DEACTIVATED_EVT, (void*)eventData); |
| } |
| #if (NFC_NXP_NON_STD_CARD == TRUE) |
| if (checkCmdSent == 1 && eventData->deactivated.type == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_DEACTIVATED_EVT: Setting check flag to one", __func__); |
| checkTagNtf = 1; |
| } |
| #endif |
| #endif |
| |
| notifyPollingEventwhileNfcOff(); |
| |
| if (true == getReconnectState()) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Reconnect in progress : Do nothing"); |
| break; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /* P2P-priority logic for multiprotocol tags */ |
| if ((multiprotocol_detected == 1) && (sP2pActive == 1)) { |
| NfcTag::getInstance().mNumDiscNtf = 0; |
| clear_multiprotocol(); |
| multiprotocol_flag = 1; |
| } |
| if (gIsWaiting4Deact2SleepNtf) { |
| if (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE) { |
| gGotDeact2IdleNtf = true; |
| } else if (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP) { |
| gIsWaiting4Deact2SleepNtf = false; |
| } |
| } |
| #endif |
| NfcTag::getInstance().setDeactivationState(eventData->deactivated); |
| |
| if (NfcTag::getInstance().mNumDiscNtf) { |
| NfcTag::getInstance().mNumDiscNtf--; |
| NfcTag::getInstance().selectNextTag(); |
| } |
| |
| if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP) { |
| { |
| SyncEventGuard guard(gDeactivatedEvent); |
| gActivated = false; |
| gDeactivatedEvent.notifyOne(); |
| } |
| #if (NXP_EXTNS == TRUE) |
| if ((nfcFL.nfcNxpEse && |
| nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) && |
| (SecureElement::getInstance().mIsWiredModeOpen && |
| SecureElement::getInstance().mPassiveListenEnabled)) { |
| SecureElement::getInstance().startThread(0x00); |
| } |
| #endif |
| NfcTag::getInstance().mNumDiscNtf = 0; |
| NfcTag::getInstance().mTechListIndex = 0; |
| nativeNfcTag_resetPresenceCheck(); |
| NfcTag::getInstance().connectionEventHandler(connEvent, eventData); |
| nativeNfcTag_abortWaits(); |
| NfcTag::getInstance().abort(); |
| NfcTag::getInstance().mIsMultiProtocolTag = false; |
| } else if (gIsTagDeactivating) { |
| NfcTag::getInstance().setActive(false); |
| nativeNfcTag_doDeactivateStatus(0); |
| } else if (EXTNS_GetDeactivateFlag() == true) { |
| NfcTag::getInstance().setActive(false); |
| nativeNfcTag_doDeactivateStatus(0); |
| } |
| |
| /* If RF is activated for what we think is a Secure Element transaction |
| * and it is deactivated to either IDLE or DISCOVERY mode, notify wait |
| * event */ |
| if ((eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE) || |
| (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_DISCOVERY)) { |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY && |
| RoutingManager::getInstance().is_ee_recovery_ongoing()) { |
| recovery = false; |
| SyncEventGuard guard( |
| SecureElement::getInstance().mEEdatapacketEvent); |
| SecureElement::getInstance().mEEdatapacketEvent.notifyOne(); |
| } |
| #endif |
| if (sSeRfActive) { |
| sSeRfActive = false; |
| if (!sIsDisabling && sIsNfaEnabled) |
| SecureElement::getInstance().notifyListenModeState(false); |
| } else if (sP2pActive) { |
| sP2pActive = false; |
| #if (NXP_EXTNS == FALSE) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DEACTIVATED_EVT; is p2p", __func__); |
| if (NFC_GetNCIVersion() == NCI_VERSION_1_0) { |
| // Disable RF field events in case of p2p |
| uint8_t nfa_enable_rf_events[] = {0x01}; |
| |
| if (!sIsDisabling && sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Enabling RF field events", __func__); |
| status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, |
| sizeof(nfa_enable_rf_events), |
| &nfa_enable_rf_events[0]); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Enabled RF field events", __func__); |
| } else { |
| LOG(ERROR) << StringPrintf( |
| "%s: Failed to enable RF field events", __func__); |
| } |
| } |
| } |
| #endif |
| SecureElement::getInstance().notifyRfFieldEvent(false); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DEACTIVATED_EVT: is p2p", __func__); |
| } |
| } |
| #if (NXP_EXTNS == TRUE) |
| if (sReaderModeEnabled && |
| (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP)) { |
| if (gFelicaReaderState == STATE_NFCDEP_ACTIVATED_NFCDEP_INTF) { |
| SyncEventGuard g(sRespCbEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Sending Sem Post for Deactivated", __func__); |
| sRespCbEvent.notifyOne(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Switching to T3T\n"); |
| gFelicaReaderState = STATE_DEACTIVATED_TO_SLEEP; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: FelicaReaderState Invalid", __func__); |
| gFelicaReaderState = STATE_IDLE; |
| } |
| } |
| #endif |
| } break; |
| |
| case NFA_TLV_DETECT_EVT: { |
| status = eventData->tlv_detect.status; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_TLV_DETECT_EVT status = 0x%0X, protocol = %d, num_tlvs = " |
| "%d, num_bytes = %d", |
| __func__, status, eventData->tlv_detect.protocol, |
| eventData->tlv_detect.num_tlvs, eventData->tlv_detect.num_bytes); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_TLV_DETECT_EVT error: status = 0x%0X", __func__, status); |
| } |
| } break; |
| |
| case NFA_NDEF_DETECT_EVT: { |
| /* NDEF Detection procedure is completed, |
| * if status is failure, it means the tag does not contain any or valid |
| * NDEF data |
| * pass the failure status to the NFC Service */ |
| status = eventData->ndef_detect.status; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_NDEF_DETECT_EVT status = 0x%0X, protocol = %u, " |
| "max_size = %u, cur_size = %u, flags = 0x%X", |
| __func__, status, eventData->ndef_detect.protocol, |
| eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size, |
| eventData->ndef_detect.flags); |
| NfcTag::getInstance().connectionEventHandler(connEvent, eventData); |
| nativeNfcTag_doCheckNdefResult(status, eventData->ndef_detect.max_size, |
| eventData->ndef_detect.cur_size, |
| eventData->ndef_detect.flags); |
| } break; |
| |
| case NFA_DATA_EVT: { |
| /* Data message received (for non-NDEF reads) */ |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DATA_EVT: status = 0x%X, len = %d", |
| __func__, eventData->status, eventData->data.len); |
| nativeNfcTag_doTransceiveStatus( |
| eventData->status, eventData->data.p_data, eventData->data.len); |
| } break; |
| |
| case NFA_RW_INTF_ERROR_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_RW_INTF_ERROR_EVT", __func__); |
| nativeNfcTag_notifyRfTimeout(); |
| nativeNfcTag_doReadCompleted(NFA_STATUS_TIMEOUT); |
| } break; |
| |
| case NFA_SELECT_CPLT_EVT: { |
| status = eventData->status; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_SELECT_CPLT_EVT: status = 0x%0X", __func__, status); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_SELECT_CPLT_EVT error: status = 0x%0X", __func__, |
| status); |
| } |
| } break; |
| |
| case NFA_READ_CPLT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_READ_CPLT_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| nativeNfcTag_doReadCompleted(eventData->status); |
| NfcTag::getInstance().connectionEventHandler(connEvent, eventData); |
| } break; |
| |
| case NFA_WRITE_CPLT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_WRITE_CPLT_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| nativeNfcTag_doWriteStatus(eventData->status == NFA_STATUS_OK); |
| } break; |
| |
| case NFA_SET_TAG_RO_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_SET_TAG_RO_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| nativeNfcTag_doMakeReadonlyResult(eventData->status); |
| } break; |
| |
| case NFA_CE_NDEF_WRITE_START_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_CE_NDEF_WRITE_START_EVT: status: 0x%0X", |
| __func__, eventData->status); |
| if (eventData->status != NFA_STATUS_OK) |
| LOG(ERROR) << StringPrintf( |
| "%s: NFA_CE_NDEF_WRITE_START_EVT error: status = 0x%0X", __func__, |
| eventData->status); |
| } break; |
| |
| case NFA_CE_NDEF_WRITE_CPLT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_CE_NDEF_WRITE_CPLT_EVT: len = %u", |
| __func__, eventData->ndef_write_cplt.len); |
| } break; |
| |
| case NFA_LLCP_ACTIVATED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_LLCP_ACTIVATED_EVT: is_initiator: %d remote_wks: %d, " |
| "remote_lsc: %d, remote_link_miu: %d, local_link_miu: %d", |
| __func__, eventData->llcp_activated.is_initiator, |
| eventData->llcp_activated.remote_wks, |
| eventData->llcp_activated.remote_lsc, |
| eventData->llcp_activated.remote_link_miu, |
| eventData->llcp_activated.local_link_miu); |
| PeerToPeer::getInstance().llcpActivatedHandler( |
| getNative(0, 0), eventData->llcp_activated); |
| } break; |
| |
| case NFA_LLCP_DEACTIVATED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_LLCP_DEACTIVATED_EVT", __func__); |
| PeerToPeer::getInstance().llcpDeactivatedHandler( |
| getNative(0, 0), eventData->llcp_deactivated); |
| } break; |
| |
| case NFA_LLCP_FIRST_PACKET_RECEIVED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_LLCP_FIRST_PACKET_RECEIVED_EVT", __func__); |
| PeerToPeer::getInstance().llcpFirstPacketHandler(getNative(0, 0)); |
| } break; |
| |
| case NFA_PRESENCE_CHECK_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_PRESENCE_CHECK_EVT", __func__); |
| nativeNfcTag_doPresenceCheckResult(eventData->status); |
| } break; |
| |
| case NFA_FORMAT_CPLT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_FORMAT_CPLT_EVT: status = 0x%0X", __func__, |
| eventData->status); |
| nativeNfcTag_formatStatus(eventData->status == NFA_STATUS_OK); |
| } break; |
| |
| case NFA_I93_CMD_CPLT_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_I93_CMD_CPLT_EVT: status = 0x%0X", |
| __func__, eventData->status); |
| } break; |
| |
| case NFA_CE_UICC_LISTEN_CONFIGURED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_CE_UICC_LISTEN_CONFIGURED_EVT : status = 0x%0X", __func__, |
| eventData->status); |
| SecureElement::getInstance().connectionEventHandler(connEvent, |
| eventData); |
| } break; |
| |
| case NFA_CE_ESE_LISTEN_CONFIGURED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_CE_ESE_LISTEN_CONFIGURED_EVT : status = 0x%0X", __func__, |
| eventData->status); |
| SecureElement::getInstance().connectionEventHandler(connEvent, |
| eventData); |
| } break; |
| |
| case NFA_SET_P2P_LISTEN_TECH_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_SET_P2P_LISTEN_TECH_EVT", __func__); |
| PeerToPeer::getInstance().connectionEventHandler(connEvent, eventData); |
| } break; |
| |
| case NFA_CE_LOCAL_TAG_CONFIGURED_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_CE_LOCAL_TAG_CONFIGURED_EVT", __func__); |
| } break; |
| #if (NXP_EXTNS == TRUE) |
| case NFA_RECOVERY_EVT: { |
| if (nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_RECOVERY_EVT: Discovery Started in lower layer:Updating " |
| "status in JNI", |
| __func__); |
| if (MposManager::getInstance().getEtsiReaederState() == |
| STATE_SE_RDR_MODE_STOP_IN_PROGRESS) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Reset the ETSI Reader State to STATE_SE_RDR_MODE_STOPPED", |
| __func__); |
| MposManager::getInstance().setEtsiReaederState( |
| STATE_SE_RDR_MODE_STOPPED); |
| } |
| } |
| } break; |
| #endif |
| #if (NXP_EXTNS == TRUE) |
| case NFA_PASSIVE_LISTEN_DISABLED_EVT: { |
| if (nfcFL.nfcNxpEse && |
| nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_PASSIVE_LISTEN_DISABLED_EVT", __func__); |
| SyncEventGuard g(SecureElement::getInstance().mPassiveListenEvt); |
| SecureElement::getInstance().mPassiveListenEvt.notifyOne(); |
| } |
| } break; |
| |
| case NFA_LISTEN_ENABLED_EVT: { |
| if (nfcFL.nfcNxpEse && |
| nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_LISTEN_ENABLED_EVT", __func__); |
| SyncEventGuard g(SecureElement::getInstance().mPassiveListenEvt); |
| SecureElement::getInstance().mPassiveListenEvt.notifyOne(); |
| } |
| } break; |
| #endif |
| default: |
| LOG(ERROR) << StringPrintf("%s: unknown event ????", __func__); |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_initNativeStruc |
| ** |
| ** Description: Initialize variables. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_initNativeStruc(JNIEnv * e, jobject o) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| #if (NXP_EXTNS == TRUE) |
| nfc_jni_native_data* nat = |
| (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); |
| /*JCOP OS Download protection case to be handled*/ |
| #else |
| nfc_jni_native_data* nat = |
| (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); |
| #endif |
| |
| if (nat == NULL) { |
| LOG(ERROR) << StringPrintf("%s: fail allocate native data", __func__); |
| return JNI_FALSE; |
| } |
| |
| memset(nat, 0, sizeof(*nat)); |
| e->GetJavaVM(&(nat->vm)); |
| nat->env_version = e->GetVersion(); |
| nat->manager = e->NewGlobalRef(o); |
| |
| ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o)); |
| jfieldID f = e->GetFieldID(cls.get(), "mNative", "J"); |
| e->SetLongField(o, f, (jlong)nat); |
| |
| MposManager::initMposNativeStruct(e, o); |
| /* Initialize native cached references */ |
| gCachedNfcManagerNotifyNdefMessageListeners = |
| e->GetMethodID(cls.get(), "notifyNdefMessageListeners", |
| "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); |
| gCachedNfcManagerNotifyTransactionListeners = |
| e->GetMethodID(cls.get(), "notifyTransactionListeners", "([B[BI)V"); |
| gCachedNfcManagerNotifyConnectivityListeners = |
| e->GetMethodID(cls.get(), "notifyConnectivityListeners", "(I)V"); |
| gCachedNfcManagerNotifyEmvcoMultiCardDetectedListeners = e->GetMethodID( |
| cls.get(), "notifyEmvcoMultiCardDetectedListeners", "()V"); |
| gCachedNfcManagerNotifyLlcpLinkActivation = |
| e->GetMethodID(cls.get(), "notifyLlcpLinkActivation", |
| "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); |
| gCachedNfcManagerNotifyLlcpLinkDeactivated = |
| e->GetMethodID(cls.get(), "notifyLlcpLinkDeactivated", |
| "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); |
| gCachedNfcManagerNotifyLlcpFirstPacketReceived = |
| e->GetMethodID(cls.get(), "notifyLlcpLinkFirstPacketReceived", |
| "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); |
| sCachedNfcManagerNotifyTargetDeselected = |
| e->GetMethodID(cls.get(), "notifyTargetDeselected", "()V"); |
| gCachedNfcManagerNotifySeFieldActivated = |
| e->GetMethodID(cls.get(), "notifySeFieldActivated", "()V"); |
| gCachedNfcManagerNotifySeFieldDeactivated = |
| e->GetMethodID(cls.get(), "notifySeFieldDeactivated", "()V"); |
| gCachedNfcManagerNotifySeListenActivated = |
| e->GetMethodID(cls.get(), "notifySeListenActivated", "()V"); |
| gCachedNfcManagerNotifySeListenDeactivated = |
| e->GetMethodID(cls.get(), "notifySeListenDeactivated", "()V"); |
| |
| gCachedNfcManagerNotifyHostEmuActivated = |
| e->GetMethodID(cls.get(), "notifyHostEmuActivated", "(I)V"); |
| |
| gCachedNfcManagerNotifyAidRoutingTableFull = |
| e->GetMethodID(cls.get(), "notifyAidRoutingTableFull", "()V"); |
| |
| gCachedNfcManagerNotifyHostEmuData = |
| e->GetMethodID(cls.get(), "notifyHostEmuData", "(I[B)V"); |
| |
| gCachedNfcManagerNotifyHostEmuDeactivated = |
| e->GetMethodID(cls.get(), "notifyHostEmuDeactivated", "(I)V"); |
| |
| gCachedNfcManagerNotifyRfFieldActivated = |
| e->GetMethodID(cls.get(), "notifyRfFieldActivated", "()V"); |
| gCachedNfcManagerNotifyRfFieldDeactivated = |
| e->GetMethodID(cls.get(), "notifyRfFieldDeactivated", "()V"); |
| |
| sCachedNfcManagerNotifySeApduReceived = |
| e->GetMethodID(cls.get(), "notifySeApduReceived", "([B)V"); |
| |
| sCachedNfcManagerNotifySeMifareAccess = |
| e->GetMethodID(cls.get(), "notifySeMifareAccess", "([B)V"); |
| |
| sCachedNfcManagerNotifySeEmvCardRemoval = |
| e->GetMethodID(cls.get(), "notifySeEmvCardRemoval", "()V"); |
| |
| #if (NXP_EXTNS == TRUE) |
| gCachedNfcManagerNotifyReRoutingEntry = |
| e->GetMethodID(cls.get(), "notifyReRoutingEntry", "()V"); |
| |
| gCachedNfcManagerNotifyUiccStatusEvent = |
| e->GetMethodID(cls.get(), "notifyUiccStatusEvent", "(I)V"); |
| |
| #if (NXP_NFCC_HCE_F == TRUE) |
| gCachedNfcManagerNotifyT3tConfigure = |
| e->GetMethodID(cls.get(), "notifyT3tConfigure", "()V"); |
| #endif |
| gCachedNfcManagerNotifyJcosDownloadInProgress = |
| e->GetMethodID(cls.get(), "notifyJcosDownloadInProgress", "(I)V"); |
| |
| gCachedNfcManagerNotifyFwDwnldRequested = |
| e->GetMethodID(cls.get(), "notifyFwDwnldRequested", "()V"); |
| |
| #endif |
| if (nfc_jni_cache_object(e, gNativeNfcTagClassName, |
| &(nat->cached_NfcTag)) == -1) { |
| LOG(ERROR) << StringPrintf("%s: fail cache NativeNfcTag", __func__); |
| return JNI_FALSE; |
| } |
| |
| if (nfc_jni_cache_object(e, gNativeP2pDeviceClassName, |
| &(nat->cached_P2pDevice)) == -1) { |
| LOG(ERROR) << StringPrintf("%s: fail cache NativeP2pDevice", __func__); |
| return JNI_FALSE; |
| } |
| |
| gNativeData = getNative(e, o); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return JNI_TRUE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfaDeviceManagementCallback |
| ** |
| ** Description: Receive device management events from stack. |
| ** dmEvent: Device-management event ID. |
| ** eventData: Data associated with event ID. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void nfaDeviceManagementCallback(uint8_t dmEvent, |
| tNFA_DM_CBACK_DATA * eventData) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent); |
| |
| switch (dmEvent) { |
| case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */ |
| { |
| SyncEventGuard guard(sNfaEnableEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__, eventData->status); |
| sIsNfaEnabled = eventData->status == NFA_STATUS_OK; |
| #if (NXP_EXTNS == TRUE) |
| sEnableStatus = eventData->status; |
| #endif |
| sIsDisabling = false; |
| sNfaEnableEvent.notifyOne(); |
| } break; |
| |
| case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */ |
| { |
| SyncEventGuard guard(sNfaDisableEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DM_DISABLE_EVT", __func__); |
| sIsNfaEnabled = false; |
| sIsDisabling = false; |
| sNfaDisableEvent.notifyOne(); |
| } break; |
| |
| case NFA_DM_SET_CONFIG_EVT: // result of NFA_SetConfig |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DM_SET_CONFIG_EVT", __func__); |
| { |
| SyncEventGuard guard(sNfaSetConfigEvent); |
| sNfaSetConfigEvent.notifyOne(); |
| } |
| break; |
| |
| case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */ |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DM_GET_CONFIG_EVT", __func__); |
| { |
| HciRFParams::getInstance().connectionEventHandler(dmEvent, eventData); |
| SyncEventGuard guard(sNfaGetConfigEvent); |
| if (eventData->status == NFA_STATUS_OK && |
| eventData->get_config.tlv_size <= sizeof(sConfig)) { |
| sCurrentConfigLen = eventData->get_config.tlv_size; |
| memcpy(sConfig, eventData->get_config.param_tlvs, |
| eventData->get_config.tlv_size); |
| |
| #if (NXP_EXTNS == TRUE) |
| if (sCheckNfceeFlag) checkforNfceeBuffer(); |
| |
| if (eSEPhyIntfInResponsive(eventData)) recoverEseConnectivity(); |
| #endif |
| } else { |
| LOG(ERROR) << StringPrintf("%s: NFA_DM_GET_CONFIG failed", |
| __func__); |
| sCurrentConfigLen = 0; |
| } |
| sNfaGetConfigEvent.notifyOne(); |
| } |
| break; |
| |
| case NFA_DM_RF_FIELD_EVT: |
| checkforTranscation(NFA_TRANS_DM_RF_FIELD_EVT, (void*)eventData); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __func__, |
| eventData->rf_field.status, eventData->rf_field.rf_field_status); |
| if (sIsDisabling || !sIsNfaEnabled) break; |
| |
| if (!sP2pActive && eventData->rf_field.status == NFA_STATUS_OK) { |
| SecureElement::getInstance().notifyRfFieldEvent( |
| eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON); |
| struct nfc_jni_native_data* nat = getNative(NULL, NULL); |
| JNIEnv* e = NULL; |
| ScopedAttach attach(nat->vm, &e); |
| if (e == NULL) { |
| LOG(ERROR) << StringPrintf("jni env is null"); |
| return; |
| } |
| if (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON) { |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT))) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: RF field on evnt Not allowing to set", __FUNCTION__); |
| } |
| sRfFieldOff = false; |
| e->CallVoidMethod(nat->manager, |
| android::gCachedNfcManagerNotifyRfFieldActivated); |
| } else { |
| /*In case of if Field On is not received before activation, consider |
| NFA_ACTIVATED_EVENT for |
| locking the transaction and use Field Off received while removing |
| the reader from proximity to end the lock*/ |
| if (pTransactionController->getCurTransactionRequestor() == |
| TRANSACTION_REQUESTOR(NFA_ACTIVATED_EVENT)) { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(NFA_ACTIVATED_EVENT)); |
| } else { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)); |
| } |
| sRfFieldOff = true; |
| e->CallVoidMethod( |
| nat->manager, |
| android::gCachedNfcManagerNotifyRfFieldDeactivated); |
| } |
| } |
| break; |
| |
| case NFA_DM_NFCC_TRANSPORT_ERR_EVT: |
| case NFA_DM_NFCC_TIMEOUT_EVT: { |
| if (dmEvent == NFA_DM_NFCC_TIMEOUT_EVT) |
| LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TIMEOUT_EVT; abort", |
| __func__); |
| else if (dmEvent == NFA_DM_NFCC_TRANSPORT_ERR_EVT) |
| LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TRANSPORT_ERR_EVT; abort", |
| __func__); |
| if (nfcFL.eseFL._JCOP_WA_ENABLE) { |
| NFA_HciW4eSETransaction_Complete(Wait); |
| } |
| nativeNfcTag_abortWaits(); |
| NfcTag::getInstance().abort(); |
| sAbortConnlessWait = true; |
| nativeLlcpConnectionlessSocket_abortWait(); |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: aborting sNfaEnableDisablePollingEvent", __func__); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: aborting sNfaEnableEvent", __func__); |
| SyncEventGuard guard(sNfaEnableEvent); |
| sNfaEnableEvent.notifyOne(); |
| } |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: aborting sNfaDisableEvent", __func__); |
| SyncEventGuard guard(sNfaDisableEvent); |
| sNfaDisableEvent.notifyOne(); |
| } |
| sDiscoveryEnabled = false; |
| sPollingEnabled = false; |
| PowerSwitch::getInstance().abort(); |
| |
| if (!sIsDisabling && sIsNfaEnabled) { |
| EXTNS_Close(); |
| NFA_Disable(false); |
| sIsDisabling = true; |
| } else { |
| sIsNfaEnabled = false; |
| sIsDisabling = false; |
| } |
| PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL); |
| #if (NXP_EXTNS == TRUE) |
| if (eventData->status == NFA_STATUS_FAILED) { |
| LOG(ERROR) << StringPrintf("%s: Disabling NFC service", __func__); |
| } else { |
| #endif |
| LOG(ERROR) << StringPrintf("%s: crash NFC service", __func__); |
| ////////////////////////////////////////////// |
| // crash the NFC service process so it can restart automatically |
| abort(); |
| ////////////////////////////////////////////// |
| #if (NXP_EXTNS == TRUE) |
| } |
| #endif |
| } break; |
| |
| case NFA_DM_PWR_MODE_CHANGE_EVT: |
| PowerSwitch::getInstance().deviceManagementCallback(dmEvent, eventData); |
| break; |
| |
| #if (NXP_EXTNS == TRUE) |
| case NFA_DM_SET_ROUTE_CONFIG_REVT: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DM_SET_ROUTE_CONFIG_REVT; status=0x%X", |
| __func__, eventData->status); |
| if (eventData->status != NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("AID Routing table configuration Failed!!!"); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("AID Routing Table configured."); |
| } |
| RoutingManager::getInstance().mLmrtEvent.notifyOne(); |
| break; |
| |
| case NFA_DM_GET_ROUTE_CONFIG_REVT: { |
| RoutingManager::getInstance().processGetRoutingRsp(eventData, |
| sRoutingBuff); |
| if (eventData->status == NFA_STATUS_OK) { |
| SyncEventGuard guard(sNfaGetRoutingEvent); |
| sNfaGetRoutingEvent.notifyOne(); |
| } |
| break; |
| } |
| case NFA_DM_EE_HCI_DISABLE: { |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFA_DM_EE_HCI_DISABLE wait releasing"); |
| SyncEventGuard guard(sNfceeHciCbDisableEvent); |
| sNfceeHciCbDisableEvent.notifyOne(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFA_DM_EE_HCI_DISABLE wait released"); |
| } |
| break; |
| } |
| case NFA_DM_EE_HCI_ENABLE: { |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFA_DM_EE_HCI_ENABLE wait releasing"); |
| SyncEventGuard guard(sNfceeHciCbEnableEvent); |
| sNfceeHciCbEnableEvent.notifyOne(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFA_DM_EE_HCI_ENABLE wait released"); |
| } |
| break; |
| } |
| #endif |
| case NFA_DM_SET_POWER_SUB_STATE_EVT: { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NFA_DM_SET_POWER_SUB_STATE_EVT; status=0x%X", |
| __FUNCTION__, eventData->power_sub_state.status); |
| SyncEventGuard guard(sNfaSetPowerSubState); |
| sNfaSetPowerSubState.notifyOne(); |
| } break; |
| case NFA_DM_EMVCO_PCD_COLLISION_EVT: |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "STATUS_EMVCO_PCD_COLLISION - Multiple card detected"); |
| SecureElement::getInstance().notifyEmvcoMultiCardDetectedListeners(); |
| break; |
| |
| default: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: unhandled event", __func__); |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_sendRawFrame |
| ** |
| ** Description: Send a raw frame. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_sendRawFrame(JNIEnv * e, jobject, |
| jbyteArray data) { |
| size_t bufLen = 0x00; |
| uint8_t* buf = NULL; |
| if (data != NULL) { |
| ScopedByteArrayRO bytes(e, data); |
| buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| bufLen = bytes.size(); |
| } |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET) { |
| RoutingManager::getInstance().mNfcFRspTimer.kill(); |
| if (bufLen == 0) { |
| gIsEmptyRspSentByHceFApk = true; |
| } |
| } |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("nfcManager_sendRawFrame(): bufLen:%lu", bufLen); |
| tNFA_STATUS status = NFA_SendRawFrame(buf, bufLen, 0); |
| return (status == NFA_STATUS_OK); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_routeAid |
| ** |
| ** Description: Route an AID to an EE |
| ** e: JVM environment. |
| ** aid: aid to be added to routing table. |
| ** route: aid route location. i.e. DH/eSE/UICC |
| ** power: power state |
| ** aidInfo: prefix or suffix aid. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_routeAid(JNIEnv * e, jobject, jbyteArray aid, |
| jint route, jint power, jint aidInfo) { |
| ScopedByteArrayRO bytes(e, aid); |
| uint8_t* buf = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| size_t bufLen = bytes.size(); |
| |
| #if (NXP_EXTNS == TRUE) |
| if ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) && |
| (route == 2 || route == 4)) { // UICC or UICC2 HANDLE |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "sCurrentSelectedUICCSlot: %d", sCurrentSelectedUICCSlot); |
| route = (sCurrentSelectedUICCSlot != 0x02) ? 0x02 : 0x04; |
| } |
| /*In case of 66T/67T field on is observed as last field event once reader |
| is removed from proximity, which will hold the transaction lock |
| unnecessarily |
| In such cases end the lock as it is not required*/ |
| if (((nfcFL.chipType == pn548C2) || (nfcFL.chipType == pn551)) && |
| pTransactionController->getCurTransactionRequestor() == |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)) { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)); |
| } |
| bool result = RoutingManager::getInstance().addAidRouting( |
| buf, bufLen, route, power, aidInfo); |
| #else |
| bool result = |
| RoutingManager::getInstance().addAidRouting(buf, bufLen, route, aidInfo); |
| |
| #endif |
| return result; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_unrouteAid |
| ** |
| ** Description: Remove a AID routing |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_unrouteAid(JNIEnv * e, jobject, jbyteArray aid) { |
| ScopedByteArrayRO bytes(e, aid); |
| uint8_t* buf = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| size_t bufLen = bytes.size(); |
| bool result = RoutingManager::getInstance().removeAidRouting(buf, bufLen); |
| return result; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_routeApduPattern |
| ** |
| ** Description: Route an APDU and APDU mask to an EE |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_routeApduPattern( |
| JNIEnv * e, jobject, jint route, jint powerState, jbyteArray apduData, |
| jbyteArray apduMask) { |
| ScopedByteArrayRO bytes(e, apduData); |
| uint8_t* apdu = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| size_t apduLen = bytes.size(); |
| ScopedByteArrayRO bytes2(e, apduMask); |
| uint8_t* mask = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes2[0])); |
| size_t maskLen = bytes2.size(); |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) { |
| if (route == 2 || route == 4) { // UICC or UICC2 HANDLE |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "sCurrentSelectedUICCSlot: %d", sCurrentSelectedUICCSlot); |
| route = (sCurrentSelectedUICCSlot != 0x02) ? 0x02 : 0x04; |
| } |
| } |
| if (nfcManager_isTransanctionOnGoing(true)) { |
| return false; |
| } |
| #endif |
| return RoutingManager::getInstance().addApduRouting(route, powerState, apdu, |
| apduLen, mask, maskLen); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_unrouteApduPattern |
| ** |
| ** Description: Remove a APDU and APDU mask routing |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_unrouteApduPattern(JNIEnv * e, jobject, |
| jbyteArray apduData) { |
| #if (NXP_EXTNS == TRUE) |
| if (nfcManager_isTransanctionOnGoing(true)) { |
| return false; |
| } |
| #endif |
| ScopedByteArrayRO bytes(e, apduData); |
| uint8_t* apdu = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| size_t apduLen = bytes.size(); |
| return RoutingManager::getInstance().removeApduRouting(apduLen, apdu); |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setRoutingEntry |
| ** |
| ** Description: Set the routing entry in routing table |
| ** e: JVM environment. |
| ** o: Java object. |
| ** type: technology or protocol routing |
| ** 0x01 - Technology |
| ** 0x02 - Protocol |
| ** value: technology /protocol value |
| ** route: routing destination |
| ** 0x00 : Device Host |
| ** 0x01 : ESE |
| ** 0x02 : UICC |
| ** power: power state for the routing entry |
| *******************************************************************************/ |
| |
| static jboolean nfcManager_setRoutingEntry( |
| JNIEnv*, jobject, jint type, jint value, jint route, jint power) { |
| jboolean result = false; |
| |
| result = RoutingManager::getInstance().setRoutingEntry(type, value, route, |
| power); |
| return result; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_clearRoutingEntry |
| ** |
| ** Description: Set the routing entry in routing table |
| ** e: JVM environment. |
| ** o: Java object. |
| ** type:technology/protocol/aid clear routing |
| ** |
| *******************************************************************************/ |
| |
| static jboolean nfcManager_clearRoutingEntry(JNIEnv*, jobject, jint type) { |
| jboolean result = false; |
| |
| result = RoutingManager::getInstance().clearRoutingEntry(type); |
| return result; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setDefaultRoute |
| ** |
| ** Description: Set the default route in routing table |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| *******************************************************************************/ |
| |
| static jboolean nfcManager_setDefaultRoute( |
| JNIEnv*, jobject, jint defaultRouteEntry, jint defaultProtoRouteEntry, |
| jint defaultTechRouteEntry) { |
| jboolean result = false; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : enter", __func__); |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(setDefaultRoute))) { |
| LOG(ERROR) << StringPrintf( |
| "%s : Transaction in progress, Store the request", __FUNCTION__); |
| set_last_request(RE_ROUTING, NULL); |
| return result; |
| } |
| #endif |
| if (sRfEnabled) { |
| // Stop RF discovery to reconfigure |
| startRfDiscovery(false); |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| result = RoutingManager::getInstance().setDefaultRoute( |
| defaultRouteEntry, defaultProtoRouteEntry, defaultTechRouteEntry); |
| if (result) |
| result = RoutingManager::getInstance().commitRouting(); |
| else |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s : Commit routing failed ", __func__); |
| gsRouteUpdated = true; |
| #else |
| result = RoutingManager::getInstance().setDefaultRouting(); |
| #endif |
| |
| startRfDiscovery(true); |
| #if (NXP_EXTNS == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(setDefaultRoute)); |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : exit", __func__); |
| return result; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getAidTableSize |
| ** Description: Get the maximum supported size for AID routing table. |
| ** |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getAidTableSize(JNIEnv*, jobject) { |
| return NFA_GetAidTableSize(); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getRemainingAidTableSize |
| ** Description: Get the remaining size of AID routing table. |
| ** |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getRemainingAidTableSize(JNIEnv*, jobject) { |
| return NFA_GetRemainingAidTableSize(); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_clearAidTable |
| ** |
| ** Description: Clean all AIDs in routing table |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| *******************************************************************************/ |
| static bool nfcManager_clearAidTable(JNIEnv*, jobject) { |
| #if (NXP_EXTNS == TRUE) |
| /*In case of 66T/67T field on is observed as last field event once reader |
| is removed from proximity, which will hold the transaction lock |
| unnecessarily |
| In such cases end the lock as it is not required*/ |
| if (((nfcFL.chipType == pn548C2) || (nfcFL.chipType == pn551)) && |
| pTransactionController->getCurTransactionRequestor() == |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)) { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)); |
| } |
| #endif |
| return RoutingManager::getInstance().clearAidTable(); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doRegisterT3tIdentifier |
| ** |
| ** Description: Registers LF_T3T_IDENTIFIER for NFC-F. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** t3tIdentifier: LF_T3T_IDENTIFIER value (10 or 18 bytes) |
| ** |
| ** Returns: Handle retrieve from RoutingManager. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_doRegisterT3tIdentifier(JNIEnv * e, jobject, |
| jbyteArray t3tIdentifier) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| ScopedByteArrayRO bytes(e, t3tIdentifier); |
| uint8_t* buf = |
| const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); |
| size_t bufLen = bytes.size(); |
| int handle = |
| RoutingManager::getInstance().registerT3tIdentifier(buf, bufLen); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return handle; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDeregisterT3tIdentifier |
| ** |
| ** Description: Deregisters LF_T3T_IDENTIFIER for NFC-F. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** handle: Handle retrieve from libnfc-nci. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doDeregisterT3tIdentifier(JNIEnv*, jobject, |
| jint handle) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| RoutingManager::getInstance().deregisterT3tIdentifier(handle); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getLfT3tMax |
| ** |
| ** Description: Returns LF_T3T_MAX value. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: LF_T3T_MAX value. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getLfT3tMax(JNIEnv*, jobject) { return sLfT3tMax; } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doInitialize |
| ** |
| ** Description: Turn on NFC. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_doInitialize(JNIEnv * e, jobject o) { |
| tNFA_MW_VERSION mwVer; |
| gSeDiscoverycount = 0; |
| gActualSeCount = 0; |
| |
| uint8_t switchToUiccSlot = 0; |
| #if (NXP_EXTNS == TRUE) |
| rfActivation = false; |
| tNFA_PMID ven_config_addr[] = {0xA0, 0x07}; |
| tNFA_PMID pollProfileAddr[] = {0xA0, 0x44}; |
| uint8_t pollProfileVal[] = {NFC_FORUM_POLL}; |
| char lowRamSysProp[50] = {'\0'}; |
| bool isSuccess = false; |
| sNfcee_disc_state = UICC_SESSION_NOT_INTIALIZED; |
| IsEseCeDisabled = false; |
| |
| /* NFC initialization in progress */ |
| if (NFC_OFF == sNfcState) sNfcState = NFC_INITIALIZING_IN_PROGRESS; |
| |
| if (!GetNxpStrValue(NAME_NXP_ESE_PWR_MGMT_PROP, (char*)lowRamSysProp, |
| sizeof(lowRamSysProp))) { |
| sIsLowRamDevice = false; |
| } else { |
| char propBuf[PROPERTY_VALUE_MAX] = {'\0'}; |
| property_get(lowRamSysProp, propBuf, ""); |
| sIsLowRamDevice = (propBuf[0] != '\0') |
| ? ((strcmp(propBuf, "true") == 0) ? true : false) |
| : true; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "isLowRamDevice %s", sIsLowRamDevice ? "true" : "false"); |
| } |
| NFA_SetLowRamDevice(sIsLowRamDevice); |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter; ver=%s nfa=%s NCI_VERSION=0x%02X", __func__, |
| nfca_version_string, nfa_version_string, NCI_VERSION); |
| mwVer = NFA_GetMwVersion(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: MW Version: NFC_NCIHALx_AR%X.%x.%x.%x", __func__, |
| mwVer.validation, mwVer.android_version, |
| mwVer.major_version, mwVer.minor_version); |
| |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| NfcTag::getInstance().mNfcDisableinProgress = false; |
| PowerSwitch& powerSwitch = PowerSwitch::getInstance(); |
| if (sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: already enabled", __func__); |
| goto TheEnd; |
| } |
| #if (NXP_EXTNS == TRUE) |
| if (gsNfaPartialEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: already partial enable calling deinitialize", __func__); |
| nfcManager_doPartialDeInitialize(); |
| } |
| #endif |
| powerSwitch.initialize(PowerSwitch::FULL_POWER); |
| register_signal_handler(); |
| { |
| unsigned long num = 0; |
| |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| theInstance.Initialize(); // start GKI, NCI task, NFC task |
| #if (NXP_EXTNS == TRUE) |
| int state = getJCOPOS_UpdaterState(); |
| if ((state != OSU_COMPLETE) && (state != OSU_NOT_STARTED)) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("JCOP is in OSU mode"); |
| NFA_SetBootMode(NFA_OSU_BOOT_MODE); |
| } else { |
| NFA_SetBootMode(NFA_NORMAL_BOOT_MODE); |
| } |
| #endif |
| stat = nfcManagerEnableNfc(theInstance); |
| nfcManager_getFeatureList(); |
| if (nfcFL.nfcNxpEse) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("ESE Present Loading p61-jcop-lib"); |
| pJcopMgr->JcopInitialize(); |
| } else |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("ESE Not Present"); |
| EXTNS_Init(nfaDeviceManagementCallback, nfaConnectionCallback); |
| |
| if (stat == NFA_STATUS_OK) { |
| // sIsNfaEnabled indicates whether stack started successfully |
| if (sIsNfaEnabled) { |
| SecureElement::getInstance().initialize(getNative(e, o)); |
| RoutingManager::getInstance().initialize(getNative(e, o)); |
| HciRFParams::getInstance().initialize(); |
| MposManager::getInstance().initialize(getNative(e, o)); |
| sIsSecElemSelected = |
| (SecureElement::getInstance().getActualNumEe() - 1); |
| sIsSecElemDetected = sIsSecElemSelected; |
| nativeNfcTag_registerNdefTypeHandler(); |
| NfcTag::getInstance().initialize(getNative(e, o)); |
| PeerToPeer::getInstance().initialize(); |
| PeerToPeer::getInstance().handleNfcOnOff(true); |
| #if (NXP_EXTNS == TRUE) |
| if (GetNxpNumValue(NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT, |
| (void*)&gdisc_timeout, |
| sizeof(gdisc_timeout)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT not found"); |
| gdisc_timeout = |
| NFCEE_DISC_TIMEOUT_SEC; /*Default nfcee discover timeout*/ |
| } |
| gdisc_timeout = gdisc_timeout * 1000; |
| if (NFA_STATUS_OK == GetNumNFCEEConfigured()) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf(" gSeDiscoverycount = %d gActualSeCount=%d", |
| gSeDiscoverycount, gActualSeCount); |
| if (gSeDiscoverycount < gActualSeCount) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Wait for ESE to discover, gdisc_timeout = %d", |
| gdisc_timeout); |
| SyncEventGuard g(gNfceeDiscCbEvent); |
| if (gNfceeDiscCbEvent.wait(gdisc_timeout) == false) { |
| LOG(ERROR) << StringPrintf( |
| "%s: timeout waiting for nfcee dis event", __func__); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("gSeDiscoverycount = %d gActualSeCount=%d", |
| gSeDiscoverycount, gActualSeCount); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("All ESE are discovered "); |
| } |
| } |
| // Create transaction controller |
| (void)transactionController::controller(); |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| checkforESERemoval(); |
| GetNxpNumValue(NAME_NXP_DUAL_UICC_ENABLE, |
| (void*)&dualUiccInfo.dualUiccEnable, |
| sizeof(dualUiccInfo.dualUiccEnable)); |
| if (dualUiccInfo.dualUiccEnable == 0x01) { |
| checkforNfceeConfig(UICC1 | UICC2 | ESE); |
| dualUiccInfo.uiccActivStat = 0x00; |
| if (SecureElement::getInstance().getEeStatus( |
| SecureElement::getInstance().EE_HANDLE_0xF4) != |
| NFC_NFCEE_STATUS_REMOVED) { |
| dualUiccInfo.uiccActivStat = (sSelectedUicc & 0x0F); |
| } |
| switchToUiccSlot = ((sSelectedUicc & 0x0F) == 0x01) ? 0x02 : 0x01; |
| nfcManager_doSelectUicc(e, o, switchToUiccSlot); |
| if (SecureElement::getInstance().getEeStatus( |
| SecureElement::getInstance().EE_HANDLE_0xF4) != |
| NFC_NFCEE_STATUS_REMOVED) { |
| dualUiccInfo.uiccActivStat |= (sSelectedUicc & 0x0F); |
| } |
| uiccEventTimer.set(1, notifyUiccEvent); |
| } |
| } else |
| SecureElement::getInstance().updateEEStatus(); |
| if (nfcFL.eseFL._JCOP_WA_ENABLE) { |
| RoutingManager::getInstance().handleSERemovedNtf(); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Discovered se count %d", gSeDiscoverycount); |
| /*Check for ETSI12 Configuration for SEs detected in the HCI Network*/ |
| performNfceeETSI12Config(); |
| if (nfcFL.eseFL._ESE_ETSI12_PROP_INIT && |
| (swp_getconfig_status & SWP2_ESE)) { |
| performHCIInitialization(e, o); |
| } |
| SecureElement::getInstance().getSETechnology( |
| SecureElement::EE_HANDLE_0xF3); |
| checkforNfceeConfig(UICC1 | UICC2 | ESE); |
| /*Pending clear all pipe handling*/ |
| if (sNfcee_disc_state == UICC_CLEAR_ALL_PIPE_NTF_RECEIVED) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Perform pending UICC clear all pipe handling"); |
| sNfcee_disc_state = UICC_SESSION_INTIALIZATION_DONE; |
| /*Handle UICC clear all pipe notification*/ |
| checkforNfceeConfig(UICC1 | UICC2); |
| } |
| sNfcee_disc_state = UICC_SESSION_INTIALIZATION_DONE; |
| #endif |
| if (nfcFL.eseFL._GP_CONTINOUS_PROCESSING) { |
| if (isNxpConfigModified()) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Set JCOP CP Timeout"); |
| SecureElement::getInstance().setCPTimeout(); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("No Need to set JCOP CP Timeout"); |
| } |
| } |
| ///////////////////////////////////////////////////////////////////////////////// |
| // Add extra configuration here (work-arounds, etc.) |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfcNxpEse) { |
| if (nfcFL.eseFL._ESE_SVDD_SYNC || |
| nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION || |
| nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC || |
| nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE) { |
| isSuccess = createSPIEvtHandlerThread(); |
| } |
| if (nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE && isSuccess) { |
| SecureElement::getInstance().enableDwp(); |
| } else if (!isSuccess) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Failed to start SPI Event Handler Thread"); |
| } |
| } |
| #endif |
| pendingScreenState = false; |
| { |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| stat = NFA_GetConfig(0x01, ven_config_addr); |
| if (stat == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| /*sCurrentConfigLen should be > 4 (num_tlv:1 + addr:2 + value:1) and |
| *pos 4 gives the current eeprom value*/ |
| if ((sCurrentConfigLen > 4) && (sConfig[4] == 0x03)) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: No need to update VEN_CONFIG. Already set to 0x%02x", |
| __func__, sConfig[4]); |
| } else { |
| SetVenConfigValue(NFC_MODE_ON); |
| if (stat != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: fail enable SetVenConfigValue; error=0x%X", __func__, |
| stat); |
| } |
| } |
| gGeneralPowershutDown = 0; |
| } |
| updateEeprom(pollProfileAddr, sizeof(pollProfileVal), pollProfileVal); |
| if (gIsDtaEnabled == true) { |
| uint8_t configData = 0; |
| configData = |
| 0x01; /**< Poll NFC-DEP : Highest Available Bit Rates */ |
| NFA_SetConfig(NCI_PARAM_ID_BITR_NFC_DEP, sizeof(uint8_t), |
| &configData); |
| configData = 0x0B; /**< Listen NFC-DEP : Waiting Time */ |
| NFA_SetConfig(NFC_PMID_WT, sizeof(uint8_t), &configData); |
| configData = |
| 0x0F; /**< Specific Parameters for NFC-DEP RF Interface */ |
| NFA_SetConfig(NCI_PARAM_ID_NFC_DEP_OP, sizeof(uint8_t), |
| &configData); |
| } |
| |
| struct nfc_jni_native_data* nat = getNative(e, o); |
| |
| if (nat) { |
| if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num))) |
| nat->tech_mask = num; |
| else |
| nat->tech_mask = DEFAULT_TECH_MASK; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: tag polling tech mask=0x%X", __func__, nat->tech_mask); |
| } |
| |
| // if this value exists, set polling interval. |
| if (GetNumValue(NAME_NFA_DM_DISC_DURATION_POLL, &num, sizeof(num))) |
| nat->discovery_duration = num; |
| else |
| nat->discovery_duration = DEFAULT_DISCOVERY_DURATION; |
| #if (NXP_EXTNS == TRUE) |
| discDuration = nat->discovery_duration; |
| #endif |
| NFA_SetRfDiscoveryDuration(nat->discovery_duration); |
| |
| // get LF_T3T_MAX |
| { |
| SyncEventGuard guard(sNfaGetConfigEvent); |
| tNFA_PMID configParam[1] = {NCI_PARAM_ID_LF_T3T_MAX}; |
| stat = NFA_GetConfig(1, configParam); |
| if (stat == NFA_STATUS_OK) { |
| sNfaGetConfigEvent.wait(); |
| if (sCurrentConfigLen >= 4 || |
| sConfig[1] == NCI_PARAM_ID_LF_T3T_MAX) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: lfT3tMax=%d", __func__, sConfig[3]); |
| sLfT3tMax = sConfig[3]; |
| } |
| } |
| } |
| if (GetNxpNumValue(NAME_NXP_CE_ROUTE_STRICT_DISABLE, (void*)&num, |
| sizeof(num)) == false) |
| num = 0x01; // default value |
| |
| // TODO: Check this in L_OSP_EXT[PN547C2] |
| // NFA_SetCEStrictDisable(num); |
| RoutingManager::getInstance().setCeRouteStrictDisable(num); |
| prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED; |
| #if (NXP_EXTNS != TRUE) |
| // Do custom NFCA startup configuration. |
| doStartupConfig(); |
| #else |
| if (HciRFParams::getInstance().isCeWithEseDisabled()) { |
| recoverEseConnectivity(); |
| } |
| #endif |
| goto TheEnd; |
| } |
| } |
| |
| LOG(ERROR) << StringPrintf("%s: fail nfa enable; error=0x%X", __func__, |
| stat); |
| |
| if (sIsNfaEnabled) { |
| EXTNS_Close(); |
| stat = NFA_Disable(false /* ungraceful */); |
| } |
| |
| theInstance.Finalize(); |
| } |
| |
| TheEnd: |
| if (sIsNfaEnabled) |
| PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| #if (NXP_EXTNS == TRUE) |
| if (isNxpConfigModified() || isNxpRFConfigModified()) { |
| updateNxpConfigTimestamp(); |
| } |
| #endif |
| return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doEnableDtaMode |
| ** |
| ** Description: Enable the DTA mode in NFC service. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doEnableDtaMode(JNIEnv * e, jobject o) { |
| gIsDtaEnabled = true; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManagerEnableNfc |
| ** |
| ** Description: Enables Nfc submodules in libnfc |
| ** |
| ** Returns: Status |
| ** |
| *******************************************************************************/ |
| static tNFA_STATUS nfcManagerEnableNfc(NfcAdaptation & theInstance) { |
| uint8_t retryCount = 0; |
| unsigned long num = 0; |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| do { |
| SyncEventGuard guard(sNfaEnableEvent); |
| tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs(); |
| NFA_Init(halFuncEntries); |
| stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback); |
| if (stat == NFA_STATUS_OK) { |
| num = initializeGlobalAppLogLevel(); |
| sNfaEnableEvent.wait(); // wait for NFA command to finish |
| } |
| retryCount++; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: sEnableStatus =0x%X", __func__, sEnableStatus); |
| } while ((sEnableStatus == NFA_STATUS_NOT_INITIALIZED) && (retryCount < 3)); |
| |
| return stat; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_checkNfcStateBusy() |
| ** |
| ** Description This function returns whether NFC process is busy or not. |
| ** |
| ** Returns if Nfc state busy return true otherwise false. |
| ** |
| *******************************************************************************/ |
| bool nfcManager_checkNfcStateBusy() { |
| bool status = false; |
| |
| if (NFA_checkNfcStateBusy() == true) status = true; |
| |
| return status; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: requestFwDownload |
| ** |
| ** Description This function is to complete the FW Dwnld to complete the |
| ** the pending request due to SPI session ongoing . |
| ** |
| ** Returns void. |
| ** |
| *******************************************************************************/ |
| void requestFwDownload() { |
| JNIEnv* e = NULL; |
| uint8_t fwDnldRequest = false; |
| int status = NFA_STATUS_OK; |
| |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| status = theInstance.HalGetFwDwnldFlag(&fwDnldRequest); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Enter: %s fwDnldRequest = %d", __func__, fwDnldRequest); |
| if (status == NFA_STATUS_OK) { |
| if (fwDnldRequest == true) { |
| ScopedAttach attach(RoutingManager::getInstance().mNativeData->vm, &e); |
| if (e == NULL) { |
| LOG(ERROR) << StringPrintf("Exit:%s jni env is null", __func__); |
| return; |
| } |
| if (nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC) { |
| e->CallVoidMethod(gNativeData->manager, |
| android::gCachedNfcManagerNotifyFwDwnldRequested); |
| } |
| if (e->ExceptionCheck()) { |
| e->ExceptionClear(); |
| LOG(ERROR) << StringPrintf("Exit:%s fail notify", __func__); |
| } |
| |
| } else { |
| LOG(ERROR) << StringPrintf("Exit:%s Firmware download request:%d ", |
| __func__, fwDnldRequest); |
| } |
| } else { |
| LOG(ERROR) << StringPrintf("Exit:%s HalGetFwDwnldFlag status:%d ", |
| __func__, status); |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: updateEeprom |
| ** |
| ** Description: Used to send the EXTENDED SET CONFIG command to update |
| ** the EEPROM values |
| ** *param Address of the eeprom |
| ** len of the eeprom address |
| ** val to be updated |
| ** |
| ** Returns: NFA_STATUS_OK/NFA_STATUS_FAILED |
| ** |
| *******************************************************************************/ |
| tNFA_STATUS updateEeprom(uint8_t * param, uint8_t len, uint8_t * val) { |
| tNFA_STATUS status = NFA_STATUS_OK; |
| uint8_t valOffset = 4; |
| SyncEventGuard guard(sNfaGetConfigEvent); |
| status = NFA_GetConfig(0x01, param); |
| if (status == NFA_STATUS_OK) { |
| status = sNfaGetConfigEvent.wait(2 * ONE_SECOND_MS) ? NFA_STATUS_OK |
| : NFA_STATUS_FAILED; |
| } |
| |
| if (status == NFA_STATUS_OK) { |
| /*sCurrentConfigLen should be > 4 (num_tlv:1 + addr:2 + value:1) and |
| *pos 4 gives the current eeprom value*/ |
| if ((sCurrentConfigLen > PROPSETCONFIGMINLEN) && |
| (sConfig[SETCONFIGLENPOS] == len)) { |
| if (memcmp(&sConfig[valOffset], val, len)) { |
| status = NxpNfcUpdateEeprom(param, len, val); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Already same"); |
| } |
| } else { |
| status = NFA_STATUS_FAILED; |
| } |
| } |
| return status; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDisableDtaMode |
| ** |
| ** Description: Disable the DTA mode in NFC service. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doDisableDtaMode(JNIEnv * e, jobject o) { |
| gIsDtaEnabled = false; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_Enablep2p |
| ** |
| ** Description: enable P2P |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| static void nfcManager_Enablep2p(JNIEnv * e, jobject o, jboolean p2pFlag) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Enter :%s p2pFlag = %d", __func__, p2pFlag); |
| /* if another transaction is already in progress, store this request */ |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(enablep2p))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Transaction in progress, Store the request"); |
| set_last_request(ENABLE_P2P, NULL); |
| transaction_data.discovery_params.enable_p2p = p2pFlag; |
| return; |
| } |
| if (sRfEnabled && p2pFlag) { |
| /* Stop discovery if already ON */ |
| startRfDiscovery(false); |
| } |
| |
| /* if already Polling, change to listen Mode */ |
| if (sPollingEnabled) { |
| if (p2pFlag && !sP2pEnabled) { |
| /* enable P2P listening, if we were not already listening */ |
| sP2pEnabled = true; |
| PeerToPeer::getInstance().enableP2pListening(true); |
| } |
| } |
| /* Beam ON - Discovery ON */ |
| if (p2pFlag) { |
| NFA_ResumeP2p(); |
| startRfDiscovery(p2pFlag); |
| } |
| pTransactionController->transactionEnd(TRANSACTION_REQUESTOR(enablep2p)); |
| } |
| |
| void enableRfDiscovery() { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __FUNCTION__); |
| nfcManager_enableDiscovery(NULL, NULL, mDiscParams.technologies_mask, |
| mDiscParams.enable_lptd, mDiscParams.reader_mode, |
| mDiscParams.enable_p2p, mDiscParams.restart); |
| } |
| |
| void disableRfDiscovery() { nfcManager_disableDiscovery(NULL, NULL); } |
| |
| void storeLastDiscoveryParams(int technologies_mask, bool enable_lptd, |
| bool reader_mode, bool enable_p2p, |
| bool restart) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __FUNCTION__); |
| mDiscParams.technologies_mask = technologies_mask; |
| mDiscParams.enable_lptd = enable_lptd; |
| mDiscParams.reader_mode = reader_mode; |
| mDiscParams.enable_p2p = enable_p2p; |
| mDiscParams.restart = restart; |
| } |
| #endif |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_enableDiscovery |
| ** |
| ** Description: Start polling and listening for devices. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** technologies_mask: the bitmask of technologies for which |
| *to enable discovery |
| ** enable_lptd: whether to enable low power polling (default: |
| *false) |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_enableDiscovery( |
| JNIEnv * e, jobject o, jint technologies_mask, jboolean enable_lptd, |
| jboolean reader_mode, jboolean enable_p2p, jboolean restart) { |
| tNFA_STATUS status = NFA_STATUS_OK; |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK; |
| unsigned long num = 0; |
| |
| tNFA_HANDLE handle = NFA_HANDLE_INVALID; |
| struct nfc_jni_native_data* nat = NULL; |
| |
| #if (NXP_EXTNS == TRUE) |
| tNFA_TECHNOLOGY_MASK etsi_tech_mask = 0; |
| p61_access_state_t p61_current_state = P61_STATE_INVALID; |
| long ret_val = -1; |
| #endif |
| if (e == NULL && o == NULL) { |
| nat = transaction_data.transaction_nat; |
| } else { |
| nat = getNative(e, o); |
| } |
| |
| storeLastDiscoveryParams(technologies_mask, enable_lptd, reader_mode, |
| enable_p2p, restart); |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(enableDiscovery))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Transaction is in progress store the request"); |
| set_last_request(ENABLE_DISCOVERY, nat); |
| transaction_data.discovery_params.technologies_mask = technologies_mask; |
| transaction_data.discovery_params.enable_lptd = enable_lptd; |
| transaction_data.discovery_params.reader_mode = reader_mode; |
| transaction_data.discovery_params.enable_p2p = enable_p2p; |
| transaction_data.discovery_params.restart = restart; |
| goto TheEnd; |
| } |
| #endif |
| |
| #if (NXP_EXTNS == TRUE) |
| if ((nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE) && |
| (MposManager::getInstance().getEtsiReaederState() == |
| STATE_SE_RDR_MODE_STARTED)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter STATE_SE_RDR_MODE_START_CONFIG", __func__); |
| Rdr_req_ntf_info_t mSwp_info = |
| MposManager::getInstance().getSwpRrdReqInfo(); |
| { |
| SyncEventGuard guard(android::sNfaEnableDisablePollingEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: disable polling", __func__); |
| status = NFA_DisablePolling(); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaEnableDisablePollingEvent |
| .wait(); // wait for NFA_POLL_DISABLED_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", |
| __func__, status); |
| } |
| } |
| |
| if (mSwp_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_A) |
| etsi_tech_mask |= NFA_TECHNOLOGY_MASK_A; |
| if (mSwp_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_B) |
| etsi_tech_mask |= NFA_TECHNOLOGY_MASK_B; |
| |
| { |
| SyncEventGuard guard(android::sNfaEnableDisablePollingEvent); |
| status = NFA_EnablePolling(etsi_tech_mask); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for enable event", __func__); |
| android::sNfaEnableDisablePollingEvent |
| .wait(); // wait for NFA_POLL_ENABLED_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", |
| __func__, status); |
| } |
| } |
| startRfDiscovery(true); |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(enableDiscovery)); |
| |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(etsiReader))) { |
| LOG(ERROR) << StringPrintf("%s: transaction attempt failed", |
| __FUNCTION__); |
| } |
| goto TheEnd; |
| } |
| #endif |
| |
| if (technologies_mask == -1 && nat) |
| tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask; |
| else if (technologies_mask != -1) |
| tech_mask = (tNFA_TECHNOLOGY_MASK)technologies_mask; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter; tech_mask = %02x", __func__, tech_mask); |
| |
| if (sDiscoveryEnabled && !restart) { |
| LOG(ERROR) << StringPrintf("%s: already discovering", __func__); |
| #if (NXP_EXTNS == TRUE) |
| goto TheEnd; |
| #else |
| return; |
| #endif |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: sIsSecElemSelected=%u", __func__, sIsSecElemSelected); |
| PowerSwitch::getInstance().setLevel(PowerSwitch::FULL_POWER); |
| |
| if (sRfEnabled) { |
| // Stop RF discovery to reconfigure |
| startRfDiscovery(false); |
| } |
| |
| if ((GetNumValue(NAME_UICC_LISTEN_TECH_MASK, &num, sizeof(num)))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s:UICC_LISTEN_MASK=0x0%lu;", __func__, num); |
| } |
| |
| // Check polling configuration |
| if (tech_mask != 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Disable p2pListening", __func__); |
| PeerToPeer::getInstance().enableP2pListening(false); |
| stopPolling_rfDiscoveryDisabled(); |
| startPolling_rfDiscoveryDisabled(tech_mask); |
| |
| // Start P2P listening if tag polling was enabled |
| if (sPollingEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Enable p2pListening", __func__); |
| |
| if (enable_p2p && !sP2pEnabled) { |
| sP2pEnabled = true; |
| PeerToPeer::getInstance().enableP2pListening(true); |
| NFA_ResumeP2p(); |
| } else if (!enable_p2p && sP2pEnabled) { |
| sP2pEnabled = false; |
| PeerToPeer::getInstance().enableP2pListening(false); |
| NFA_PauseP2p(); |
| } |
| |
| if (reader_mode && !sReaderModeEnabled) { |
| sReaderModeEnabled = true; |
| #if (NXP_EXTNS == TRUE) |
| NFA_SetReaderMode(true, 0); |
| /*Send the state of readmode flag to Hal using proprietary command*/ |
| sProprietaryCmdBuf[3] = 0x01; |
| status |= |
| NFA_SendRawVsCommand(sizeof(sProprietaryCmdBuf), |
| sProprietaryCmdBuf, NxpResponsePropCmd_Cb); |
| if (status == NFA_STATUS_OK) { |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.wait(500); // wait for callback |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Failed NFA_SendRawVsCommand", |
| __func__); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: FRM Enable", __func__); |
| #endif |
| NFA_DisableListening(); |
| #if (NXP_EXTNS == TRUE) |
| sTechMask = tech_mask; |
| |
| discDuration = READER_MODE_DISCOVERY_DURATION; |
| #endif |
| NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION); |
| } else if (!reader_mode && sReaderModeEnabled) { |
| struct nfc_jni_native_data* nat = getNative(e, o); |
| sReaderModeEnabled = false; |
| #if (NXP_EXTNS == TRUE) |
| NFA_SetReaderMode(false, 0); |
| gFelicaReaderState = STATE_IDLE; |
| /*Send the state of readmode flag to Hal using proprietary command*/ |
| sProprietaryCmdBuf[3] = 0x00; |
| status |= |
| NFA_SendRawVsCommand(sizeof(sProprietaryCmdBuf), |
| sProprietaryCmdBuf, NxpResponsePropCmd_Cb); |
| if (status == NFA_STATUS_OK) { |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.wait(500); // wait for callback |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Failed NFA_SendRawVsCommand", |
| __func__); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: FRM Disable", __func__); |
| #endif |
| if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME == |
| nfcFL.eseFL._ESE_EXCLUSIVE_WIRED_MODE) || |
| nfcFL.eseFL._ESE_UICC_EXCLUSIVE_WIRED_MODE) { |
| if (!SecureElement::getInstance().mlistenDisabled) { |
| NFA_EnableListening(); |
| } |
| } else { |
| NFA_EnableListening(); |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| discDuration = nat->discovery_duration; |
| #endif |
| NFA_SetRfDiscoveryDuration(nat->discovery_duration); |
| } else { |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: restart UICC listen mode (%02lX)", __func__, (num & 0xC7)); |
| handle = SecureElement::getInstance().getEseHandleFromGenericId( |
| SecureElement::UICC_ID); |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| stat = NFA_CeConfigureUiccListenTech(handle, 0x00); |
| if (stat == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to stop UICC listen"); |
| } |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| stat = NFA_CeConfigureUiccListenTech(handle, (num & 0xC7)); |
| if (stat == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to start UICC listen"); |
| } |
| } |
| } |
| NFC_SetNfcServicePid(); |
| } else { |
| // No technologies configured, stop polling |
| stopPolling_rfDiscoveryDisabled(); |
| } |
| |
| // Start P2P listening if tag polling was enabled or the mask was 0. |
| if (sDiscoveryEnabled || (tech_mask == 0)) { |
| handle = SecureElement::getInstance().getEseHandleFromGenericId( |
| SecureElement::UICC_ID); |
| |
| #if (NXP_EXTNS == TRUE) |
| if ((getScreenState() == (NFA_SCREEN_STATE_ON_UNLOCKED)) || |
| sProvisionMode) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Enable p2pListening", __func__); |
| PeerToPeer::getInstance().enableP2pListening(true); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Disable p2pListening", __func__); |
| PeerToPeer::getInstance().enableP2pListening(false); |
| } |
| #endif |
| |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| stat = NFA_CeConfigureUiccListenTech(handle, 0x00); |
| if (stat == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to start UICC listen"); |
| } |
| |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| stat = NFA_CeConfigureUiccListenTech(handle, (num & 0xC7)); |
| if (stat == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to start UICC listen"); |
| } |
| } |
| // Actually start discovery. |
| startRfDiscovery(true); |
| sDiscoveryEnabled = true; |
| |
| PowerSwitch::getInstance().setModeOn(PowerSwitch::DISCOVERY); |
| |
| #if (NXP_EXTNS == TRUE) |
| TheEnd: |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(enableDiscovery)); |
| /* Set this state only during initialization and in all the other cases |
| NfcState should remain at NFC_ON except during Nfc deinit */ |
| if (NFC_INITIALIZING_IN_PROGRESS == sNfcState) { |
| sNfcState = NFC_ON; |
| ret_val = NFC_GetP61Status((void*)&p61_current_state); |
| if (ret_val < 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC_GetP61Status failed"); |
| } |
| if (!(p61_current_state & (P61_STATE_SPI) && |
| !(p61_current_state & (P61_STATE_SPI_PRIO)))) { |
| SecureElement::getInstance().setNfccPwrConfig( |
| SecureElement::getInstance().NFCC_DECIDES); |
| } |
| NFC_SetNfcServicePid(); |
| } |
| |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_disableDiscovery |
| ** |
| ** Description: Stop polling and listening for devices. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void nfcManager_disableDiscovery(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| tNFA_STATUS status = NFA_STATUS_OK; |
| unsigned long num = 0; |
| unsigned long p2p_listen_mask = 0; |
| tNFA_HANDLE handle = NFA_HANDLE_INVALID; |
| #if (NXP_EXTNS == TRUE) |
| p61_access_state_t p61_current_state = P61_STATE_INVALID; |
| long ret_val = -1; |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter;", __func__); |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(disableDiscovery))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Transaction in progress, Store the request"); |
| set_last_request(DISABLE_DISCOVERY, NULL); |
| return; |
| } |
| #endif |
| pn544InteropAbortNow(); |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE) { |
| if (MposManager::getInstance().getEtsiReaederState() == |
| STATE_SE_RDR_MODE_START_IN_PROGRESS) { |
| Rdr_req_ntf_info_t mSwp_info = |
| MposManager::getInstance().getSwpRrdReqInfo(); |
| // if(android::isDiscoveryStarted() == true) |
| android::startRfDiscovery(false); |
| PeerToPeer::getInstance().enableP2pListening(false); |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| status = NFA_CeConfigureUiccListenTech(mSwp_info.swp_rd_req_info.src, |
| 0x00); |
| if (status == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else { |
| LOG(ERROR) << StringPrintf("fail to stop listen"); |
| } |
| } |
| goto TheEnd; |
| } else if (MposManager::getInstance().getEtsiReaederState() == |
| STATE_SE_RDR_MODE_STOP_IN_PROGRESS) { |
| android::startRfDiscovery(false); |
| goto TheEnd; |
| } |
| } |
| #endif |
| |
| if (sDiscoveryEnabled == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: already disabled", __func__); |
| goto TheEnd; |
| } |
| // Stop RF Discovery. |
| startRfDiscovery(false); |
| |
| if (sPollingEnabled) status = stopPolling_rfDiscoveryDisabled(); |
| sDiscoveryEnabled = false; |
| |
| if ((GetNumValue(NAME_UICC_LISTEN_TECH_MASK, &num, sizeof(num)))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s:UICC_LISTEN_MASK=0x0%lu;", __func__, num); |
| } |
| if ((GetNumValue("P2P_LISTEN_TECH_MASK", &p2p_listen_mask, |
| sizeof(p2p_listen_mask)))) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:P2P_LISTEN_MASK=0x0%lu;", __func__, p2p_listen_mask); |
| } |
| |
| PeerToPeer::getInstance().enableP2pListening(false); |
| NFA_PauseP2p(); |
| |
| if (sIsSecElemSelected) { |
| SecureElement& se = SecureElement::getInstance(); |
| tNFA_HANDLE ee_handleList[nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED]; |
| uint8_t count; |
| se.getEeHandleList(ee_handleList, &count); |
| for (int i = 0; i < count; i++) { |
| handle = |
| se.getEseHandleFromGenericId(se.getGenericEseId(ee_handleList[i])); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:Registering for active handle id=0x%x;", __func__, handle); |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| status = NFA_CeConfigureUiccListenTech(handle, 0x00); |
| if (status == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to start UICC listen"); |
| } |
| |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mUiccListenEvent); |
| status = NFA_CeConfigureUiccListenTech(handle, (num & 0x07)); |
| if (status == NFA_STATUS_OK) { |
| SecureElement::getInstance().mUiccListenEvent.wait(); |
| } else |
| LOG(ERROR) << StringPrintf("fail to start UICC listen"); |
| } |
| } |
| |
| PeerToPeer::getInstance().enableP2pListening(false); |
| startRfDiscovery(true); |
| } |
| |
| sP2pEnabled = false; |
| // if nothing is active after this, then tell the controller to power down |
| // if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::DISCOVERY)) |
| // PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); |
| |
| // We may have had RF field notifications that did not cause |
| // any activate/deactive events. For example, caused by wireless |
| // charging orbs. Those may cause us to go to sleep while the last |
| // field event was indicating a field. To prevent sticking in that |
| // state, always reset the rf field status when we disable discovery. |
| SecureElement::getInstance().resetRfFieldStatus(); |
| TheEnd: |
| #if (NXP_EXTNS == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(disableDiscovery)); |
| /* Set this state only during initialization and in all the other cases |
| NfcState should remain at NFC_ON except during Nfc deinit */ |
| if (NFC_INITIALIZING_IN_PROGRESS == sNfcState) { |
| if (nfcFL.eseFL._WIRED_MODE_STANDBY) { |
| sNfcState = NFC_ON; |
| ret_val = NFC_GetP61Status((void*)&p61_current_state); |
| if (ret_val < 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC_GetP61Status failed"); |
| } |
| if (!(p61_current_state & (P61_STATE_SPI) && |
| !(p61_current_state & (P61_STATE_SPI_PRIO)))) { |
| SecureElement::getInstance().setNfccPwrConfig( |
| SecureElement::getInstance().NFCC_DECIDES); |
| } |
| } |
| |
| NFC_SetNfcServicePid(); |
| } |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| void enableDisableLongGuardTime(bool enable) { |
| // TODO |
| // This is basically a work-around for an issue |
| // in BCM20791B5: if a reader is configured as follows |
| // 1) Only polls for NFC-A |
| // 2) Cuts field between polls |
| // 3) Has a short guard time (~5ms) |
| // the BCM20791B5 doesn't wake up when such a reader |
| // is polling it. Unfortunately the default reader |
| // mode configuration on Android matches those |
| // criteria. To avoid the issue, increase the guard |
| // time when in reader mode. |
| // |
| // Proper fix is firmware patch for B5 controllers. |
| SyncEventGuard guard(sNfaSetConfigEvent); |
| tNFA_STATUS stat = |
| NFA_SetConfig(NCI_PARAM_ID_T1T_RDR_ONLY, 2, |
| enable ? sLongGuardTime : sDefaultGuardTime); |
| if (stat == NFA_STATUS_OK) |
| sNfaSetConfigEvent.wait(); |
| else |
| LOG(ERROR) << StringPrintf("%s: Could not configure longer guard time", |
| __func__); |
| return; |
| } |
| |
| void setUiccIdleTimeout(bool enable) { |
| // This method is *NOT* thread-safe. Right now |
| // it is only called from the same thread so it's |
| // not an issue. |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| uint8_t swp_cfg_byte0 = 0x00; |
| { |
| SyncEventGuard guard(sNfaGetConfigEvent); |
| tNFA_PMID configParam[1] = {0xC2}; |
| stat = NFA_GetConfig(1, configParam); |
| if (stat != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("%s: NFA_GetConfig failed", __func__); |
| return; |
| } |
| sNfaGetConfigEvent.wait(); |
| if (sCurrentConfigLen < 4 || sConfig[1] != 0xC2) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Config TLV length %d returned is too short", __func__, |
| sCurrentConfigLen); |
| return; |
| } |
| swp_cfg_byte0 = sConfig[3]; |
| } |
| SyncEventGuard guard(sNfaSetConfigEvent); |
| if (enable) |
| swp_cfg_byte0 |= 0x01; |
| else |
| swp_cfg_byte0 &= ~0x01; |
| |
| stat = NFA_SetConfig(0xC2, 1, &swp_cfg_byte0); |
| if (stat == NFA_STATUS_OK) |
| sNfaSetConfigEvent.wait(); |
| else |
| LOG(ERROR) << StringPrintf( |
| "%s: Could not configure UICC idle timeout feature", __func__); |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doCreateLlcpServiceSocket |
| ** |
| ** Description: Create a new LLCP server socket. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** nSap: Service access point. |
| ** sn: Service name |
| ** miu: Maximum information unit. |
| ** rw: Receive window size. |
| ** linearBufferLength: Max buffer size. |
| ** |
| ** Returns: NativeLlcpServiceSocket Java object. |
| ** |
| *******************************************************************************/ |
| static jobject nfcManager_doCreateLlcpServiceSocket( |
| JNIEnv * e, jobject, jint nSap, jstring sn, jint miu, jint rw, |
| jint linearBufferLength) { |
| PeerToPeer::tJNI_HANDLE jniHandle = |
| PeerToPeer::getInstance().getNewJniHandle(); |
| |
| ScopedUtfChars serviceName(e, sn); |
| if (serviceName.c_str() == NULL) { |
| LOG(ERROR) << StringPrintf("%s: service name can not be null error", |
| __func__); |
| return NULL; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: enter: sap=%i; name=%s; miu=%i; rw=%i; buffLen=%i", __func__, nSap, |
| serviceName.c_str(), miu, rw, linearBufferLength); |
| |
| /* Create new NativeLlcpServiceSocket object */ |
| jobject serviceSocket = NULL; |
| if (nfc_jni_cache_object_local(e, gNativeLlcpServiceSocketClassName, |
| &(serviceSocket)) == -1) { |
| LOG(ERROR) << StringPrintf("%s: Llcp socket object creation error", |
| __func__); |
| return NULL; |
| } |
| |
| /* Get NativeLlcpServiceSocket class object */ |
| ScopedLocalRef<jclass> clsNativeLlcpServiceSocket( |
| e, e->GetObjectClass(serviceSocket)); |
| if (e->ExceptionCheck()) { |
| e->ExceptionClear(); |
| LOG(ERROR) << StringPrintf("%s: Llcp Socket get object class error", |
| __func__); |
| return NULL; |
| } |
| |
| if (!PeerToPeer::getInstance().registerServer(jniHandle, |
| serviceName.c_str())) { |
| LOG(ERROR) << StringPrintf("%s: RegisterServer error", __func__); |
| return NULL; |
| } |
| |
| jfieldID f; |
| |
| /* Set socket handle to be the same as the NfaHandle*/ |
| f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mHandle", "I"); |
| e->SetIntField(serviceSocket, f, (jint)jniHandle); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: socket Handle = 0x%X", __func__, jniHandle); |
| |
| /* Set socket linear buffer length */ |
| f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), |
| "mLocalLinearBufferLength", "I"); |
| e->SetIntField(serviceSocket, f, (jint)linearBufferLength); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: buffer length = %d", __func__, linearBufferLength); |
| |
| /* Set socket MIU */ |
| f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalMiu", "I"); |
| e->SetIntField(serviceSocket, f, (jint)miu); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: MIU = %d", __func__, miu); |
| |
| /* Set socket RW */ |
| f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalRw", "I"); |
| e->SetIntField(serviceSocket, f, (jint)rw); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: RW = %d", __func__, rw); |
| |
| sLastError = 0; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return serviceSocket; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doGetLastError |
| ** |
| ** Description: Get the last error code. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Last error code. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_doGetLastError(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: last error=%i", __func__, sLastError); |
| return sLastError; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDeinitialize |
| ** |
| ** Description: Turn off NFC. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_doDeinitialize(JNIEnv * e, jobject obj) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| sIsDisabling = true; |
| |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfcNxpEse && |
| (nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE || nfcFL.eseFL._ESE_SVDD_SYNC || |
| nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION || |
| nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC)) { |
| /* NFC state is put to NFC_OFF, no more request on NFC accepted(no signal |
| * events)*/ |
| sNfcState = NFC_OFF; |
| NFC_ResetNfcServicePid(); |
| releaseSPIEvtHandlerThread(); |
| } |
| |
| if (nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION && |
| (SecureElement::getInstance().mDownloadMode == JCOP_DOWNLOAD)) { |
| if (e != NULL) { |
| unsigned long maxTimeout = 0; |
| unsigned long elapsedTimeout = 0; |
| if (!GetNxpNumValue(NAME_OS_DOWNLOAD_TIMEOUT_VALUE, &maxTimeout, |
| sizeof(maxTimeout))) { |
| maxTimeout = MAX_JCOP_TIMEOUT_VALUE; |
| LOG(ERROR) << StringPrintf("%s: Failed to get timeout value = %ld", |
| __func__, maxTimeout); |
| } |
| while (SecureElement::getInstance().mDownloadMode == JCOP_DOWNLOAD) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: timeout waiting for Os Dowload", __func__); |
| usleep(MAX_WAIT_TIME_FOR_RETRY * 1000000); |
| e->CallVoidMethod( |
| gNativeData->manager, |
| android::gCachedNfcManagerNotifyJcosDownloadInProgress, true); |
| if (e->ExceptionCheck()) { |
| e->ExceptionClear(); |
| DwpChannel::getInstance().forceClose(); |
| LOG(ERROR) << StringPrintf("%s: fail notify", __func__); |
| } |
| elapsedTimeout += MAX_WAIT_TIME_FOR_RETRY; |
| if (elapsedTimeout * 1000 > maxTimeout) { |
| DwpChannel::getInstance().forceClose(); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Time elapsed force close DWP channel", __func__); |
| } |
| } |
| } else { |
| DwpChannel::getInstance().forceClose(); |
| LOG(ERROR) << StringPrintf( |
| "%s: Force close DWP channel as JNIEnv is null", __func__); |
| } |
| } |
| |
| if (isLowRamDevice()) { |
| SecureElement::getInstance().NfccStandByOperation( |
| STANDBY_ESE_PWR_RELEASE); |
| } |
| |
| if (nfcFL.eseFL._JCOP_WA_ENABLE) { |
| rfActivation = false; |
| } |
| #endif |
| doDwpChannel_ForceExit(); |
| if (nfcFL.eseFL._JCOP_WA_ENABLE) { |
| NFA_HciW4eSETransaction_Complete(Wait); |
| } |
| if (nfcFL.nfcNxpEse) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("De-Initializing p61-jcop-lib library"); |
| pJcopMgr->JcopDeInitialize(); |
| pJcopMgr->deleteInstance(); |
| } |
| pn544InteropAbortNow(); |
| |
| RoutingManager::getInstance().onNfccShutdown(); |
| SecureElement::getInstance().finalize(); |
| PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL); |
| // Stop the discovery before calling NFA_Disable. |
| if (sRfEnabled) startRfDiscovery(false); |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| |
| if (sIsNfaEnabled) { |
| /* |
| During device Power-Off while Nfc-On, Nfc mode will be NFC_MODE_ON |
| NFC_MODE_OFF indicates Nfc is turning off and only in this case reset the |
| venConfigValue |
| */ |
| if (gGeneralPowershutDown == NFC_MODE_OFF) { |
| stat = SetVenConfigValue(NFC_MODE_OFF); |
| |
| if (stat != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: fail enable SetVenConfigValue; error=0x%X", __func__, stat); |
| } |
| } |
| SyncEventGuard guard(sNfaDisableEvent); |
| EXTNS_Close(); |
| stat = NFA_Disable(true /* graceful */); |
| if (stat == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for completion", __func__); |
| sNfaDisableEvent.wait(); // wait for NFA command to finish |
| PeerToPeer::getInstance().handleNfcOnOff(false); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__, |
| stat); |
| } |
| } |
| NfcTag::getInstance().mNfcDisableinProgress = true; |
| nativeNfcTag_abortWaits(); |
| NfcTag::getInstance().abort(); |
| sAbortConnlessWait = true; |
| nativeLlcpConnectionlessSocket_abortWait(); |
| sIsNfaEnabled = false; |
| sDiscoveryEnabled = false; |
| sIsDisabling = false; |
| sPollingEnabled = false; |
| // sIsSecElemSelected = false; |
| sIsSecElemSelected = 0; |
| gActivated = false; |
| sP2pEnabled = false; |
| #if (NXP_EXTNS == TRUE) |
| gsRouteUpdated = false; |
| #endif |
| sLfT3tMax = 0; |
| { |
| // unblock NFA_EnablePolling() and NFA_DisablePolling() |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| theInstance.Finalize(); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return JNI_TRUE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doCreateLlcpSocket |
| ** |
| ** Description: Create a LLCP connection-oriented socket. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** nSap: Service access point. |
| ** miu: Maximum information unit. |
| ** rw: Receive window size. |
| ** linearBufferLength: Max buffer size. |
| ** |
| ** Returns: NativeLlcpSocket Java object. |
| ** |
| *******************************************************************************/ |
| static jobject nfcManager_doCreateLlcpSocket(JNIEnv * e, jobject, jint nSap, |
| jint miu, jint rw, |
| jint linearBufferLength) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter; sap=%d; miu=%d; rw=%d; buffer len=%d", |
| __func__, nSap, miu, rw, linearBufferLength); |
| |
| PeerToPeer::tJNI_HANDLE jniHandle = |
| PeerToPeer::getInstance().getNewJniHandle(); |
| PeerToPeer::getInstance().createClient(jniHandle, miu, rw); |
| |
| /* Create new NativeLlcpSocket object */ |
| jobject clientSocket = NULL; |
| if (nfc_jni_cache_object_local(e, gNativeLlcpSocketClassName, |
| &(clientSocket)) == -1) { |
| LOG(ERROR) << StringPrintf("%s: fail Llcp socket creation", __func__); |
| return clientSocket; |
| } |
| |
| /* Get NativeConnectionless class object */ |
| ScopedLocalRef<jclass> clsNativeLlcpSocket(e, |
| e->GetObjectClass(clientSocket)); |
| if (e->ExceptionCheck()) { |
| e->ExceptionClear(); |
| LOG(ERROR) << StringPrintf("%s: fail get class object", __func__); |
| return clientSocket; |
| } |
| |
| jfieldID f; |
| |
| /* Set socket SAP */ |
| f = e->GetFieldID(clsNativeLlcpSocket.get(), "mSap", "I"); |
| e->SetIntField(clientSocket, f, (jint)nSap); |
| |
| /* Set socket handle */ |
| f = e->GetFieldID(clsNativeLlcpSocket.get(), "mHandle", "I"); |
| e->SetIntField(clientSocket, f, (jint)jniHandle); |
| |
| /* Set socket MIU */ |
| f = e->GetFieldID(clsNativeLlcpSocket.get(), "mLocalMiu", "I"); |
| e->SetIntField(clientSocket, f, (jint)miu); |
| |
| /* Set socket RW */ |
| f = e->GetFieldID(clsNativeLlcpSocket.get(), "mLocalRw", "I"); |
| e->SetIntField(clientSocket, f, (jint)rw); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return clientSocket; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doCreateLlcpConnectionlessSocket |
| ** |
| ** Description: Create a connection-less socket. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** nSap: Service access point. |
| ** sn: Service name. |
| ** |
| ** Returns: NativeLlcpConnectionlessSocket Java object. |
| ** |
| *******************************************************************************/ |
| static jobject nfcManager_doCreateLlcpConnectionlessSocket( |
| JNIEnv*, jobject, jint nSap, jstring /*sn*/) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: nSap=0x%X", __func__, nSap); |
| return NULL; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doGetSecureElementList |
| ** |
| ** Description: Get a list of secure element handles. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: List of secure element handles. |
| ** |
| *******************************************************************************/ |
| static jintArray nfcManager_doGetSecureElementList(JNIEnv * e, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| return SecureElement::getInstance().getListOfEeHandles(e); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSelectSecureElement |
| ** |
| ** Description: NFC controller starts routing data in listen mode. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSelectSecureElement(JNIEnv * e, jobject o, |
| jint seId) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| bool stat = true; |
| |
| if (sIsSecElemSelected >= sIsSecElemDetected) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: already selected", __func__); |
| goto TheEnd; |
| } |
| |
| PowerSwitch::getInstance().setLevel(PowerSwitch::FULL_POWER); |
| |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| |
| stat = SecureElement::getInstance().activate(seId); |
| if (stat) { |
| SecureElement::getInstance().routeToSecureElement(); |
| sIsSecElemSelected++; |
| } |
| |
| startRfDiscovery(true); |
| PowerSwitch::getInstance().setModeOn(PowerSwitch::SE_ROUTING); |
| TheEnd: |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_activateSecureElement |
| ** |
| ** Description: This function shall activate the SE as per given |
| *identifier. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** seId: Secure element identifier |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_activateSecureElement(JNIEnv * e, jobject o, |
| jint seId) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| bool stat; |
| int maxRetryCount = 3; |
| |
| SecureElement::getInstance().deactivate(seId); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Deactivated", __func__); |
| do { |
| stat = SecureElement::getInstance().activate(seId); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Activate status %d", __func__, stat); |
| } while (!stat && maxRetryCount-- > 0); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetSEPowerOffState |
| ** |
| ** Description: NFC controller enable/disabe card emulation in power off |
| ** state from EE. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSetSEPowerOffState(JNIEnv * e, jobject o, jint seId, |
| jboolean enable) { |
| (void)e; |
| (void)o; |
| tNFA_HANDLE ee_handle; |
| uint8_t power_state_mask = ~NFA_EE_PWR_STATE_SWITCH_OFF; |
| |
| if (enable == true) { |
| power_state_mask = NFA_EE_PWR_STATE_SWITCH_OFF; |
| } |
| |
| ee_handle = SecureElement::getInstance().getEseHandleFromGenericId(seId); |
| |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| |
| tNFA_STATUS status = NFA_AddEePowerState(ee_handle, power_state_mask); |
| |
| // Commit the routing configuration |
| status |= NFA_EeUpdateNow(); |
| |
| if (status != NFA_STATUS_OK) |
| LOG(ERROR) << StringPrintf("Failed to commit routing configuration"); |
| |
| startRfDiscovery(true); |
| |
| // TheEnd: /*commented to eliminate warning label |
| // defined but not used*/ |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_GetDefaultSE |
| ** |
| ** Description: Get default Secure Element. |
| ** |
| ** |
| ** Returns: Returns 0. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_GetDefaultSE(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| unsigned long num; |
| GetNxpNumValue(NAME_NXP_DEFAULT_SE, (void*)&num, sizeof(num)); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%lu: nfcManager_GetDefaultSE", num); |
| return num; |
| } |
| |
| static jint nfcManager_getSecureElementTechList(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| uint8_t sak; |
| jint tech = 0x00; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("nfcManager_getSecureElementTechList -Enter"); |
| sak = HciRFParams::getInstance().getESeSak(); |
| bool isTypeBPresent = HciRFParams::getInstance().isTypeBSupported(); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "nfcManager_getSecureElementTechList - sak is %0x", sak); |
| |
| if (sak & 0x08) { |
| tech |= TARGET_TYPE_MIFARE_CLASSIC; |
| } |
| |
| if (sak & 0x20) { |
| tech |= NFA_TECHNOLOGY_MASK_A; |
| } |
| |
| if (isTypeBPresent == true) { |
| tech |= NFA_TECHNOLOGY_MASK_B; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "nfcManager_getSecureElementTechList - tech is %0x", tech); |
| return tech; |
| } |
| |
| static jintArray nfcManager_getActiveSecureElementList(JNIEnv * e, |
| jobject o) { |
| (void)e; |
| (void)o; |
| return SecureElement::getInstance().getActiveSecureElementList(e); |
| } |
| |
| static void nfcManager_setSecureElementListenTechMask(JNIEnv * e, jobject o, |
| jint tech_mask) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: ENTER", __func__); |
| // tNFA_STATUS status; /*commented to eliminate unused |
| // variable warning*/ |
| |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| SecureElement::getInstance().setEseListenTechMask(tech_mask); |
| |
| startRfDiscovery(true); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: EXIT", __func__); |
| } |
| |
| static jbyteArray nfcManager_getSecureElementUid(JNIEnv * e, jobject o) { |
| jbyteArray jbuff = NULL; |
| uint8_t bufflen = 0; |
| uint8_t buf[16] = { |
| 0, |
| }; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("nfcManager_getSecureElementUid -Enter"); |
| HciRFParams::getInstance().getESeUid(&buf[0], &bufflen); |
| if (bufflen > 0) { |
| jbuff = e->NewByteArray(bufflen); |
| e->SetByteArrayRegion(jbuff, 0, bufflen, (jbyte*)buf); |
| } |
| return jbuff; |
| } |
| |
| static tNFA_STATUS nfcManager_setEmvCoPollProfile( |
| JNIEnv * e, jobject o, jboolean enable, jint route) { |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| tNFA_TECHNOLOGY_MASK tech_mask = 0; |
| |
| LOG(ERROR) << StringPrintf( |
| "In nfcManager_setEmvCoPollProfile enable = 0x%x route = 0x%x", enable, |
| route); |
| /* Stop polling */ |
| if (isDiscoveryStarted()) { |
| // Stop RF discovery to reconfigure |
| startRfDiscovery(false); |
| } |
| |
| status = EmvCo_dosetPoll(enable); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", |
| __func__, status); |
| goto TheEnd; |
| } |
| |
| if (enable) { |
| if (route == 0x00) { |
| /* DH enable polling for A and B*/ |
| tech_mask = NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B; |
| } else if (route == 0x01) { |
| /* UICC is end-point at present not supported by FW */ |
| /* TBD : Get eeinfo (use handle appropirately, depending up |
| * on it enable the polling */ |
| } else if (route == 0x02) { |
| /* ESE is end-point at present not supported by FW */ |
| /* TBD : Get eeinfo (use handle appropirately, depending up |
| * on it enable the polling */ |
| } else { |
| } |
| } else { |
| unsigned long num = 0; |
| if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num))) |
| tech_mask = num; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enable polling", __func__); |
| { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| status = NFA_EnablePolling(tech_mask); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for enable event", __func__); |
| sNfaEnableDisablePollingEvent.wait(); // wait for NFA_POLL_ENABLED_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", |
| __func__, status); |
| } |
| } |
| |
| TheEnd: |
| /* start polling */ |
| if (!isDiscoveryStarted()) { |
| // Start RF discovery to reconfigure |
| startRfDiscovery(true); |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDeselectSecureElement |
| ** |
| ** Description: NFC controller stops routing data in listen mode. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doDeselectSecureElement(JNIEnv * e, jobject o, |
| jint seId) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| bool stat = false; |
| bool bRestartDiscovery = false; |
| |
| if (!sIsSecElemSelected) { |
| LOG(ERROR) << StringPrintf("%s: already deselected", __func__); |
| goto TheEnd2; |
| } |
| |
| if (PowerSwitch::getInstance().getLevel() == PowerSwitch::LOW_POWER) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: do not deselect while power is OFF", __func__); |
| // sIsSecElemSelected = false; |
| sIsSecElemSelected--; |
| goto TheEnd; |
| } |
| |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| bRestartDiscovery = true; |
| } |
| // sIsSecElemSelected = false; |
| // sIsSecElemSelected--; |
| |
| // if controller is not routing to sec elems AND there is no pipe connected, |
| // then turn off the sec elems |
| if (SecureElement::getInstance().isBusy() == false) { |
| // SecureElement::getInstance().deactivate (0xABCDEF); |
| stat = SecureElement::getInstance().deactivate(seId); |
| if (stat) { |
| sIsSecElemSelected--; |
| // RoutingManager::getInstance().commitRouting(); |
| } |
| } |
| |
| TheEnd: |
| /* |
| * conditional check is added to avoid multiple dicovery cmds |
| * at the time of NFC OFF in progress |
| */ |
| if ((gGeneralPowershutDown != NFC_MODE_OFF) && bRestartDiscovery) |
| startRfDiscovery(true); |
| |
| // if nothing is active after this, then tell the controller to power down |
| if (!PowerSwitch::getInstance().setModeOff(PowerSwitch::SE_ROUTING)) |
| PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER); |
| |
| TheEnd2: |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultAidRoute |
| ** |
| ** Description: Get the default Aid Route Entry. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** mode: Not used. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultAidRoute(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| #if (NXP_EXTNS == TRUE) |
| GetNxpNumValue(NAME_DEFAULT_AID_ROUTE, &num, sizeof(num)); |
| #endif |
| return num; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultDesfireRoute |
| ** |
| ** Description: Get the default Desfire Route Entry. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** mode: Not used. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultDesfireRoute(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| #if (NXP_EXTNS == TRUE) |
| GetNxpNumValue(NAME_DEFAULT_DESFIRE_ROUTE, (void*)&num, sizeof(num)); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: enter; NAME_DEFAULT_DESFIRE_ROUTE = %02lx", __func__, num); |
| #endif |
| return num; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultMifareCLTRoute |
| ** |
| ** Description: Get the default mifare CLT Route Entry. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** mode: Not used. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultMifareCLTRoute(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| #if (NXP_EXTNS == TRUE) |
| GetNxpNumValue(NAME_DEFAULT_MIFARE_CLT_ROUTE, &num, sizeof(num)); |
| #endif |
| return num; |
| } |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultAidPowerState |
| ** |
| ** Description: Get the default Desfire Power States. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Power State |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultAidPowerState(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| GetNxpNumValue(NAME_DEFAULT_AID_PWR_STATE, &num, sizeof(num)); |
| return num; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultDesfirePowerState |
| ** |
| ** Description: Get the default Desfire Power States. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Power State |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultDesfirePowerState(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| GetNxpNumValue(NAME_DEFAULT_DESFIRE_PWR_STATE, &num, sizeof(num)); |
| return num; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getDefaultMifareCLTPowerState |
| ** |
| ** Description: Get the default mifare CLT Power States. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Power State |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getDefaultMifareCLTPowerState(JNIEnv * e, jobject o) { |
| unsigned long num = 0; |
| GetNxpNumValue(NAME_DEFAULT_MIFARE_CLT_PWR_STATE, &num, sizeof(num)); |
| return num; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setDefaultTechRoute |
| ** |
| ** Description: Setting Default Technology Routing |
| ** e: JVM environment. |
| ** o: Java object. |
| ** seId: SecureElement Id |
| ** tech_swithon: technology switch_on |
| ** tech_switchoff: technology switch_off |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_setDefaultTechRoute(JNIEnv * e, jobject o, jint seId, |
| jint tech_switchon, |
| jint tech_switchoff) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: ENTER", __func__); |
| // tNFA_STATUS status; /*commented to eliminate unused |
| // variable warning*/ |
| |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| RoutingManager::getInstance().setDefaultTechRouting(seId, tech_switchon, |
| tech_switchoff); |
| // start discovery. |
| startRfDiscovery(true); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setDefaultProtoRoute |
| ** |
| ** Description: Setting Default Protocol Routing |
| ** |
| ** e: JVM environment. |
| ** o: Java object. |
| ** seId: SecureElement Id |
| ** proto_swithon: Protocol switch_on |
| ** proto_switchoff: Protocol switch_off |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_setDefaultProtoRoute(JNIEnv * e, jobject o, jint seId, |
| jint proto_switchon, |
| jint proto_switchoff) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: ENTER", __func__); |
| // tNFA_STATUS status; /*commented to eliminate unused |
| // variable warning*/ |
| // if (sRfEnabled) { |
| // // Stop RF Discovery if we were polling |
| // startRfDiscovery (false); |
| // } |
| RoutingManager::getInstance().setDefaultProtoRouting(seId, proto_switchon, |
| proto_switchoff); |
| // start discovery. |
| // startRfDiscovery (true); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setPreferredSimSlot() |
| ** |
| ** Description: This api is used to select a particular UICC slot. |
| ** |
| ** |
| ** Returns: success/failure |
| ** |
| *******************************************************************************/ |
| static int nfcManager_setPreferredSimSlot(JNIEnv * e, jobject o, |
| jint uiccSlot) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s : uiccslot : %d : enter", __func__, uiccSlot); |
| |
| tNFA_STATUS status = NFA_STATUS_OK; |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) { |
| sCurrentSelectedUICCSlot = uiccSlot; |
| NFA_SetPreferredUiccId( |
| (uiccSlot == 2) ? (SecureElement::getInstance().EE_HANDLE_0xF8 & |
| ~NFA_HANDLE_GROUP_EE) |
| : (SecureElement::getInstance().EE_HANDLE_0xF4 & |
| ~NFA_HANDLE_GROUP_EE)); |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isVzwFeatureEnabled |
| ** |
| ** Description: Check vzw feature is enabled or not |
| ** |
| ** Returns: True if the VZW_FEATURE_ENABLE is set. |
| ** |
| *******************************************************************************/ |
| static bool nfcManager_isVzwFeatureEnabled(JNIEnv * e, jobject o) { |
| unsigned int num = 0; |
| bool mStat = false; |
| |
| if (GetNxpNumValue("VZW_FEATURE_ENABLE", &num, sizeof(num))) { |
| if (num == 0x01) { |
| mStat = true; |
| } else { |
| mStat = false; |
| } |
| } else { |
| mStat = false; |
| } |
| return mStat; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isNfccBusy |
| ** |
| ** Description: Check If NFCC is busy |
| ** |
| ** Returns: True if NFCC is busy. |
| ** |
| *******************************************************************************/ |
| static bool nfcManager_isNfccBusy(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: ENTER", __func__); |
| bool statBusy = false; |
| if (SecureElement::getInstance().isBusy()) { |
| LOG(ERROR) << StringPrintf("%s:FAIL SE wired-mode : busy", __func__); |
| statBusy = true; |
| } else if (rfActivation) { |
| LOG(ERROR) << StringPrintf("%s:FAIL RF session ongoing", __func__); |
| statBusy = true; |
| } else if (transaction_data.trans_in_progress) { |
| LOG(ERROR) << StringPrintf("%s: FAIL Transaction in progress", __func__); |
| statBusy = true; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Exit statBusy : 0x%02x", __func__, statBusy); |
| return statBusy; |
| } |
| #endif |
| /******************************************************************************* |
| ** |
| ** Function: isPeerToPeer |
| ** |
| ** Description: Whether the activation data indicates the peer supports |
| *NFC-DEP. |
| ** activated: Activation data. |
| ** |
| ** Returns: True if the peer supports NFC-DEP. |
| ** |
| *******************************************************************************/ |
| static bool isPeerToPeer(tNFA_ACTIVATED & activated) { |
| return activated.activate_ntf.protocol == NFA_PROTOCOL_NFC_DEP; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: isListenMode |
| ** |
| ** Description: Indicates whether the activation data indicates it is |
| ** listen mode. |
| ** |
| ** Returns: True if this listen mode. |
| ** |
| *******************************************************************************/ |
| static bool isListenMode(tNFA_ACTIVATED & activated) { |
| return ( |
| (NFC_DISCOVERY_TYPE_LISTEN_A == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_B == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_F == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_INTERFACE_EE_DIRECT_RF == activated.activate_ntf.intf_param.type)); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doCheckLlcp |
| ** |
| ** Description: Not used. |
| ** |
| ** Returns: True |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_doCheckLlcp(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| return JNI_TRUE; |
| } |
| |
| static jboolean nfcManager_doCheckJcopDlAtBoot(JNIEnv * e, jobject o) { |
| unsigned int num = 0; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| if (GetNxpNumValue(NAME_NXP_JCOPDL_AT_BOOT_ENABLE, (void*)&num, |
| sizeof(num))) { |
| if (num == 0x01) { |
| return JNI_TRUE; |
| } else { |
| return JNI_FALSE; |
| } |
| } else { |
| return JNI_FALSE; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doActivateLlcp |
| ** |
| ** Description: Not used. |
| ** |
| ** Returns: True |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_doActivateLlcp(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| return JNI_TRUE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doAbort |
| ** |
| ** Description: Not used. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doAbort(JNIEnv * e, jobject, jstring msg) { |
| ScopedUtfChars message = {e, msg}; |
| e->FatalError(message.c_str()); |
| abort(); // <-- Unreachable |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDownload |
| ** |
| ** Description: Download firmware patch files. Do not turn on NFC. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static jboolean nfcManager_doDownload(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| |
| theInstance.Initialize(); // start GKI, NCI task, NFC task |
| theInstance.DownloadFirmware(); |
| theInstance.Finalize(); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return JNI_TRUE; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doResetTimeouts |
| ** |
| ** Description: Not used. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doResetTimeouts(JNIEnv*, jobject) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| NfcTag::getInstance().resetAllTransceiveTimeouts(); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetTimeout |
| ** |
| ** Description: Set timeout value. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** tech: technology ID. |
| ** timeout: Timeout value. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint tech, |
| jint timeout) { |
| if (timeout <= 0) { |
| LOG(ERROR) << StringPrintf("%s: Timeout must be positive.", __func__); |
| return false; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech, timeout); |
| |
| NfcTag::getInstance().setTransceiveTimeout(tech, timeout); |
| return true; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doGetTimeout |
| ** |
| ** Description: Get timeout value. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** tech: technology ID. |
| ** |
| ** Returns: Timeout value. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint tech) { |
| int timeout = NfcTag::getInstance().getTransceiveTimeout(tech); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech, timeout); |
| return timeout; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doDump |
| ** |
| ** Description: Get libnfc-nci dump |
| ** e: JVM environment. |
| ** obj: Java object. |
| ** fdobj: File descriptor to be used |
| ** |
| ** Returns: Void |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doDump(JNIEnv * e, jobject obj, jobject fdobj) { |
| int fd = jniGetFDFromFileDescriptor(e, fdobj); |
| if (fd < 0) return; |
| |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| theInstance.Dump(fd); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetP2pInitiatorModes |
| ** |
| ** Description: Set P2P initiator's activation modes. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** modes: Active and/or passive modes. The values are |
| *specified |
| ** in external/libnfc-nxp/inc/phNfcTypes.h. See |
| ** enum phNfc_eP2PMode_t. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSetP2pInitiatorModes(JNIEnv * e, jobject o, |
| jint modes) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: modes=0x%X", __func__, modes); |
| struct nfc_jni_native_data* nat = getNative(e, o); |
| |
| tNFA_TECHNOLOGY_MASK mask = 0; |
| if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A; |
| if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F; |
| if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F; |
| if (modes & 0x08) mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE; |
| if (modes & 0x10) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE; |
| if (modes & 0x20) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE; |
| nat->tech_mask = mask; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getRouting |
| ** |
| ** Description: Get Routing Table information. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: Current routing Settings. |
| ** |
| *******************************************************************************/ |
| static jbyteArray nfcManager_getRouting(JNIEnv * e, jobject o) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : Enter", __func__); |
| jbyteArray jbuff = NULL; |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| SyncEventGuard guard(sNfaGetRoutingEvent); |
| sRoutingBuffLen = 0; |
| RoutingManager::getInstance().getRouting(); |
| sNfaGetRoutingEvent.wait(); |
| if (sRoutingBuffLen > 0) { |
| jbuff = e->NewByteArray(sRoutingBuffLen); |
| e->SetByteArrayRegion(jbuff, 0, sRoutingBuffLen, (jbyte*)sRoutingBuff); |
| } |
| |
| startRfDiscovery(true); |
| return jbuff; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getNfcInitTimeout |
| ** |
| ** Description: Gets the chip version. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: timeout in seconds |
| ** |
| *******************************************************************************/ |
| static int nfcManager_getNfcInitTimeout(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| unsigned long disc_timeout = 0; |
| unsigned long session_id_timeout = 0; |
| disc_timeout = 0; |
| gNfcInitTimeout = 0; |
| gdisc_timeout = 0; |
| |
| if (GetNxpNumValue(NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT, |
| (void*)&disc_timeout, sizeof(disc_timeout)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT not found"); |
| disc_timeout = 0; |
| } |
| if (GetNxpNumValue(NAME_NXP_DEFAULT_NFCEE_TIMEOUT, |
| (void*)&session_id_timeout, |
| sizeof(session_id_timeout)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_NXP_DEFAULT_NFCEE_TIMEOUT not found"); |
| session_id_timeout = 0; |
| } |
| |
| gNfcInitTimeout = (disc_timeout + session_id_timeout) * 1000; |
| gdisc_timeout = disc_timeout * 1000; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| " gNfcInitTimeout = %d: gdisc_timeout = %d " |
| "nfcManager_getNfcInitTimeout", |
| gNfcInitTimeout, gdisc_timeout); |
| return gNfcInitTimeout; |
| } |
| |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetP2pTargetModes |
| ** |
| ** Description: Set P2P target's activation modes. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** modes: Active and/or passive modes. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSetP2pTargetModes(JNIEnv*, jobject, jint modes) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: modes=0x%X", __func__, modes); |
| // Map in the right modes |
| tNFA_TECHNOLOGY_MASK mask = 0; |
| if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A; |
| if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F; |
| if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F; |
| if (modes & 0x08) |
| mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE; |
| |
| PeerToPeer::getInstance().setP2pListenMask(mask); |
| } |
| |
| static void nfcManager_doEnableScreenOffSuspend(JNIEnv * e, jobject o) { |
| PowerSwitch::getInstance().setScreenOffPowerState( |
| PowerSwitch::POWER_STATE_FULL); |
| } |
| |
| static void nfcManager_doDisableScreenOffSuspend(JNIEnv * e, jobject o) { |
| PowerSwitch::getInstance().setScreenOffPowerState( |
| PowerSwitch::POWER_STATE_OFF); |
| } |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doUpdateScreenState |
| ** |
| ** Description: Update If any Pending screen state is present |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doUpdateScreenState(JNIEnv * e, jobject o) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Enter ", __func__); |
| if (nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE) { |
| eScreenState_t last_screen_state_request; |
| |
| if (pendingScreenState == true) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: pendingScreenState = true ", __func__); |
| pendingScreenState = false; |
| last_screen_state_request = get_lastScreenStateRequest(); |
| nfcManager_doSetScreenState(NULL, NULL, last_screen_state_request); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: pendingScreenState = false ", __func__); |
| } |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSelectUicc() |
| ** |
| ** Description: Issue any single TLV set config command as per input |
| ** register values and bit values |
| ** |
| ** Returns: success/failure |
| ** |
| *******************************************************************************/ |
| static int nfcManager_doSelectUicc(JNIEnv * e, jobject o, jint uiccSlot) { |
| (void)e; |
| (void)o; |
| uint8_t retStat = STATUS_UNKNOWN_ERROR; |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| tNFA_STATUS status = NFC_STATUS_FAILED; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: sUicc1CntxLen : 0x%02x sUicc2CntxLen : 0x%02x", __func__, |
| dualUiccInfo.sUicc1CntxLen, dualUiccInfo.sUicc2CntxLen); |
| uint16_t RegAddr = 0xA0EC; |
| uint8_t bitVal; |
| eScreenState_t last_screen_state_request; |
| dualUiccInfo.uiccConfigStat = UICC_NOT_CONFIGURED; |
| |
| RoutingManager& routingManager = RoutingManager::getInstance(); |
| SecureElement& se = SecureElement::getInstance(); |
| |
| retStat = nfcManager_staticDualUicc_Precondition(uiccSlot); |
| |
| if (retStat != UICC_NOT_CONFIGURED) { |
| goto endSwitch; |
| } |
| |
| if (sRfEnabled) { |
| startRfDiscovery(false); |
| } |
| |
| bitVal = ((0x10) | uiccSlot); |
| |
| getUiccContext(uiccSlot); |
| |
| if ((dualUiccInfo.sUicc1CntxLen != 0) || |
| (dualUiccInfo.sUicc2CntxLen != 0)) { |
| if ((bitVal == 0x11) && (dualUiccInfo.sUicc1CntxLen != 0)) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : update uicc1 context information ", __func__); |
| uint8_t cfg[256] = {0x20, 0x02}; |
| |
| memcpy(cfg + 3, dualUiccInfo.sUicc1Cntx, dualUiccInfo.sUicc1CntxLen); |
| cfg[2] = dualUiccInfo.sUicc1CntxLen - 1; |
| status = NxpNfc_Write_Cmd_Common(dualUiccInfo.sUicc1CntxLen + 2, cfg); |
| |
| memcpy(cfg + 3, dualUiccInfo.sUicc1TechCapblty, 10); |
| cfg[2] = 9; |
| status = NxpNfc_Write_Cmd_Common(12, cfg); |
| |
| } else if ((bitVal == 0x12) && (dualUiccInfo.sUicc2CntxLen != 0)) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : update uicc2 context information", __func__); |
| uint8_t cfg[256] = {0x20, 0x02}; |
| memcpy(cfg + 3, dualUiccInfo.sUicc2Cntx, dualUiccInfo.sUicc2CntxLen); |
| cfg[2] = dualUiccInfo.sUicc2CntxLen - 1; |
| status = NxpNfc_Write_Cmd_Common(dualUiccInfo.sUicc2CntxLen + 2, cfg); |
| |
| memcpy(cfg + 3, dualUiccInfo.sUicc2TechCapblty, 10); |
| cfg[2] = 9; |
| status = NxpNfc_Write_Cmd_Common(12, cfg); |
| } |
| } |
| |
| /*Update NFCC SWIO line accordingly*/ |
| if ((Set_EERegisterValue(RegAddr, bitVal) != NFCSTATUS_OK)) { |
| retStat = DUAL_UICC_ERROR_SELECT_FAILED; |
| LOG(ERROR) << StringPrintf("%s : Set_EERegisterValue Failed", __func__); |
| goto endSwitch; |
| } |
| |
| /*Mode Set Off for UICC*/ |
| { |
| SyncEventGuard guard(routingManager.mEeSetModeEvent); |
| if ((NFA_EeModeSet(0x02, NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK) { |
| routingManager.mEeSetModeEvent.wait(); // wait for |
| // NFA_EE_MODE_SET_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s : Failed to set EE inactive", |
| __func__); |
| goto endSwitch; |
| } |
| } |
| gSeDiscoverycount = 0; |
| /*Perform HAL re-initialisation |
| * NFA EE and HCI Subsystem de-init*/ |
| { |
| SyncEventGuard guard(sNfceeHciCbDisableEvent); |
| NFA_EE_HCI_Control(false); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbDisableEvent waiting ......"); |
| if (sNfceeHciCbDisableEvent.wait(500) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbDisableEvent.wait Timeout happened"); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbDisableEvent.wait success"); |
| } |
| } |
| |
| /*Reset Nfcc*/ |
| status = NFA_ResetNfcc(); |
| /*Perform NFA EE and HCI Subsystem initialisation*/ |
| { |
| SyncEventGuard guard(sNfceeHciCbEnableEvent); |
| NFA_EE_HCI_Control(true); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbEnableEvent waiting ......"); |
| if (sNfceeHciCbEnableEvent.wait(500) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbEnableEvent.wait Timeout happened"); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("sNfceeHciCbEnableEvent.wait success"); |
| } |
| } |
| |
| { |
| se.updateEEStatus(); |
| routingManager.initialize(getNative(e, o)); |
| HciRFParams::getInstance().initialize(); |
| sIsSecElemSelected = (se.getActualNumEe() - 1); |
| sIsSecElemDetected = sIsSecElemSelected; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : gSeDiscoverycount = %d", __func__, gSeDiscoverycount); |
| { |
| SyncEventGuard g(gNfceeDiscCbEvent); |
| /*Get the SWP1 and SWP2 lines status*/ |
| if (NFA_STATUS_OK == GetNumNFCEEConfigured()) { |
| /*The SWP lines enabled and SE's discovered*/ |
| if (gSeDiscoverycount < gActualSeCount) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : Wait for ESE to discover, gdisc_timeout = %d", __func__, |
| gdisc_timeout); |
| if (gNfceeDiscCbEvent.wait(gdisc_timeout) == false) { |
| LOG(ERROR) << StringPrintf( |
| "%s: timeout waiting for nfcee dis event", __func__); |
| } |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s : All ESE are discovered ", __func__); |
| } |
| } |
| } |
| /*Get the eSE and UICC parameters for RF*/ |
| checkforNfceeConfig(UICC1 | UICC2 | ESE); |
| |
| if (se.getEeStatus(se.EE_HANDLE_0xF4) == NFC_NFCEE_STATUS_REMOVED) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : UICC 0x%02x status : NFC_NFCEE_STATUS_REMOVED. Clearing " |
| "buffer", |
| __func__, sSelectedUicc); |
| if ((sSelectedUicc == 0x01) && (dualUiccInfo.sUicc1CntxLen != 0x00)) { |
| memset(dualUiccInfo.sUicc1Cntx, 0x00, |
| sizeof(dualUiccInfo.sUicc1Cntx)); |
| memset(dualUiccInfo.sUicc1TechCapblty, 0x00, 10); |
| dualUiccInfo.sUicc1CntxLen = 0x00; |
| write_uicc_context( |
| dualUiccInfo.sUicc1Cntx, dualUiccInfo.sUicc1CntxLen, |
| dualUiccInfo.sUicc1TechCapblty, 10, 1, sSelectedUicc); |
| } else if ((sSelectedUicc == 0x02) && |
| (dualUiccInfo.sUicc2CntxLen != 0x00)) { |
| memset(dualUiccInfo.sUicc2Cntx, 0x00, |
| sizeof(dualUiccInfo.sUicc2Cntx)); |
| memset(dualUiccInfo.sUicc2TechCapblty, 0x00, 10); |
| dualUiccInfo.sUicc2CntxLen = 0x00; |
| write_uicc_context( |
| dualUiccInfo.sUicc2Cntx, dualUiccInfo.sUicc2CntxLen, |
| dualUiccInfo.sUicc2TechCapblty, 10, 1, sSelectedUicc); |
| } |
| } |
| |
| retStat = dualUiccInfo.uiccConfigStat; |
| |
| endSwitch: |
| if ((retStat == UICC_CONFIGURED) || (retStat == UICC_NOT_CONFIGURED)) { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(staticDualUicc)); |
| /*Apply screen state if pending*/ |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Apply screen state if pending", __func__); |
| if (pendingScreenState == true) { |
| pendingScreenState = false; |
| last_screen_state_request = get_lastScreenStateRequest(); |
| nfcManager_doSetScreenState(NULL, NULL, last_screen_state_request); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Can not reset transaction state", |
| __func__); |
| } |
| } |
| |
| /*If retStat is success then routing table will be reconfigured from |
| * NfcService |
| * As a part of commitRouting startRfDiscovery will be called. |
| * If retStat is failed then NfcService will not reconfigured routing |
| * table |
| * So do startRfDiscovery here*/ |
| if ((retStat != UICC_CONFIGURED) && (retStat != UICC_NOT_CONFIGURED) && |
| (!sRfEnabled)) { |
| startRfDiscovery(true); |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit retStat = %d", __func__, retStat); |
| } else if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) { |
| retStat = nfcManager_staticDualUicc_Precondition(uiccSlot); |
| |
| if (retStat != UICC_NOT_CONFIGURED) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("staticDualUicc_Precondition failed."); |
| return retStat; |
| } |
| |
| nfcManager_setPreferredSimSlot(NULL, NULL, uiccSlot); |
| retStat = UICC_CONFIGURED; |
| RoutingManager::getInstance().cleanRouting(); |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(staticDualUicc)); |
| } else { |
| retStat = DUAL_UICC_FEATURE_NOT_AVAILABLE; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Dual uicc not supported retStat = %d", __func__, retStat); |
| } |
| return retStat; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doGetSelectedUicc() |
| ** |
| ** Description: get the current selected active UICC |
| ** |
| ** Returns: UICC id |
| ** |
| *******************************************************************************/ |
| static int nfcManager_doGetSelectedUicc(JNIEnv * e, jobject o) { |
| uint8_t uicc_stat = STATUS_UNKNOWN_ERROR; |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter ", __func__); |
| uicc_stat = SecureElement::getInstance().getUiccStatus(sSelectedUicc); |
| } else if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) { |
| uicc_stat = |
| SecureElement::getInstance().getUiccStatus(sCurrentSelectedUICCSlot); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: dual uicc not supported ", __func__); |
| uicc_stat = DUAL_UICC_FEATURE_NOT_AVAILABLE; |
| } |
| return uicc_stat; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getIsoDepMaxTransceiveLength |
| ** |
| ** Description: Get maximum ISO DEP Transceive Length supported by the NFC |
| ** chip. Returns default 261 bytes if the property is not set. |
| ** |
| ** Returns: max value. |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_getIsoDepMaxTransceiveLength(JNIEnv*, jobject) { |
| unsigned long maxLength; |
| /* Check if extended APDU is supported by the chip. |
| * If not, default value is returned. |
| * The maximum length of a default IsoDep frame consists of: |
| * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes |
| */ |
| if (!GetNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &maxLength, |
| sizeof(maxLength))) |
| maxLength = 261; |
| return maxLength; |
| } |
| |
| /***************************************************************************** |
| ** |
| ** JNI functions for android-4.0.1_r1 |
| ** |
| *****************************************************************************/ |
| static JNINativeMethod gMethods[] = { |
| {"doDownload", "()Z", (void*)nfcManager_doDownload}, |
| |
| {"initializeNativeStructure", "()Z", (void*)nfcManager_initNativeStruc}, |
| |
| {"doInitialize", "()Z", (void*)nfcManager_doInitialize}, |
| |
| {"doDeinitialize", "()Z", (void*)nfcManager_doDeinitialize}, |
| |
| {"sendRawFrame", "([B)Z", (void*)nfcManager_sendRawFrame}, |
| |
| {"doRouteAid", "([BIII)Z", (void*)nfcManager_routeAid}, |
| |
| {"doUnrouteAid", "([B)Z", (void*)nfcManager_unrouteAid}, |
| |
| {"doSetRoutingEntry", "(IIII)Z", (void*)nfcManager_setRoutingEntry}, |
| |
| {"doClearRoutingEntry", "(I)Z", (void*)nfcManager_clearRoutingEntry}, |
| |
| {"clearAidTable", "()Z", (void*)nfcManager_clearAidTable}, |
| |
| {"setDefaultRoute", "(III)Z", (void*)nfcManager_setDefaultRoute}, |
| |
| {"getAidTableSize", "()I", (void*)nfcManager_getAidTableSize}, |
| |
| {"getRemainingAidTableSize", "()I", |
| (void*)nfcManager_getRemainingAidTableSize}, |
| |
| {"getDefaultAidRoute", "()I", (void*)nfcManager_getDefaultAidRoute}, |
| |
| {"getDefaultDesfireRoute", "()I", (void*)nfcManager_getDefaultDesfireRoute}, |
| |
| {"getDefaultMifareCLTRoute", "()I", |
| (void*)nfcManager_getDefaultMifareCLTRoute}, |
| #if (NXP_EXTNS == TRUE) |
| {"getDefaultAidPowerState", "()I", |
| (void*)nfcManager_getDefaultAidPowerState}, |
| |
| {"getDefaultDesfirePowerState", "()I", |
| (void*)nfcManager_getDefaultDesfirePowerState}, |
| |
| {"getDefaultMifareCLTPowerState", "()I", |
| (void*)nfcManager_getDefaultMifareCLTPowerState}, |
| #endif |
| {"doRegisterT3tIdentifier", "([B)I", |
| (void*)nfcManager_doRegisterT3tIdentifier}, |
| |
| {"doDeregisterT3tIdentifier", "(I)V", |
| (void*)nfcManager_doDeregisterT3tIdentifier}, |
| |
| {"getLfT3tMax", "()I", (void*)nfcManager_getLfT3tMax}, |
| |
| {"doEnableDiscovery", "(IZZZZ)V", (void*)nfcManager_enableDiscovery}, |
| |
| {"doGetSecureElementList", "()[I", |
| (void*)nfcManager_doGetSecureElementList}, |
| |
| {"doSelectSecureElement", "(I)V", (void*)nfcManager_doSelectSecureElement}, |
| |
| {"doActivateSecureElement", "(I)V", |
| (void*)nfcManager_activateSecureElement}, |
| |
| {"doDeselectSecureElement", "(I)V", |
| (void*)nfcManager_doDeselectSecureElement}, |
| |
| {"doSetSEPowerOffState", "(IZ)V", (void*)nfcManager_doSetSEPowerOffState}, |
| {"setDefaultTechRoute", "(III)V", (void*)nfcManager_setDefaultTechRoute}, |
| |
| {"setDefaultProtoRoute", "(III)V", (void*)nfcManager_setDefaultProtoRoute}, |
| |
| {"GetDefaultSE", "()I", (void*)nfcManager_GetDefaultSE}, |
| |
| {"doCheckLlcp", "()Z", (void*)nfcManager_doCheckLlcp}, |
| |
| {"doActivateLlcp", "()Z", (void*)nfcManager_doActivateLlcp}, |
| |
| {"doCreateLlcpConnectionlessSocket", |
| "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/" |
| "NativeLlcpConnectionlessSocket;", |
| (void*)nfcManager_doCreateLlcpConnectionlessSocket}, |
| |
| {"doCreateLlcpServiceSocket", |
| "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;", |
| (void*)nfcManager_doCreateLlcpServiceSocket}, |
| |
| {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;", |
| (void*)nfcManager_doCreateLlcpSocket}, |
| |
| {"doGetLastError", "()I", (void*)nfcManager_doGetLastError}, |
| |
| {"disableDiscovery", "()V", (void*)nfcManager_disableDiscovery}, |
| |
| {"doSetTimeout", "(II)Z", (void*)nfcManager_doSetTimeout}, |
| |
| {"doGetTimeout", "(I)I", (void*)nfcManager_doGetTimeout}, |
| |
| {"doResetTimeouts", "()V", (void*)nfcManager_doResetTimeouts}, |
| |
| {"doAbort", "(Ljava/lang/String;)V", (void*)nfcManager_doAbort}, |
| |
| {"doSetP2pInitiatorModes", "(I)V", |
| (void*)nfcManager_doSetP2pInitiatorModes}, |
| |
| {"doSetP2pTargetModes", "(I)V", (void*)nfcManager_doSetP2pTargetModes}, |
| |
| {"doEnableScreenOffSuspend", "()V", |
| (void*)nfcManager_doEnableScreenOffSuspend}, |
| |
| {"doDisableScreenOffSuspend", "()V", |
| (void*)nfcManager_doDisableScreenOffSuspend}, |
| |
| {"doDump", "(Ljava/io/FileDescriptor;)V", (void*)nfcManager_doDump}, |
| |
| {"getChipVer", "()I", (void*)nfcManager_getChipVer}, |
| |
| {"getFwFileName", "()[B", (void*)nfcManager_getFwFileName}, |
| |
| {"JCOSDownload", "()I", (void*)nfcManager_doJcosDownload}, |
| {"doCommitRouting", "()V", (void*)nfcManager_doCommitRouting}, |
| #if (NXP_EXTNS == TRUE) |
| {"doSetNfcMode", "(I)V", (void*)nfcManager_doSetNfcMode}, |
| #endif |
| {"doGetSecureElementTechList", "()I", |
| (void*)nfcManager_getSecureElementTechList}, |
| |
| {"doGetActiveSecureElementList", "()[I", |
| (void*)nfcManager_getActiveSecureElementList}, |
| |
| {"doGetSecureElementUid", "()[B", (void*)nfcManager_getSecureElementUid}, |
| |
| {"setEmvCoPollProfile", "(ZI)I", (void*)nfcManager_setEmvCoPollProfile}, |
| |
| {"doSetSecureElementListenTechMask", "(I)V", |
| (void*)nfcManager_setSecureElementListenTechMask}, |
| {"getNciVersion", "()I", (void*)nfcManager_doGetNciVersion}, |
| {"doSetScreenState", "(I)V", (void*)nfcManager_doSetScreenState}, |
| {"doSetScreenOrPowerState", "(I)V", |
| (void*)nfcManager_doSetScreenOrPowerState}, |
| // Factory Test Code |
| {"doPrbsOn", "(IIII)V", (void*)nfcManager_doPrbsOn}, |
| {"doPrbsOff", "()V", (void*)nfcManager_doPrbsOff}, |
| // SWP self test |
| {"SWPSelfTest", "(I)I", (void*)nfcManager_SWPSelfTest}, |
| // check firmware version |
| {"getFWVersion", "()I", (void*)nfcManager_getFwVersion}, |
| #if (NXP_EXTNS == TRUE) |
| {"updateScreenState", "()V", (void*)nfcManager_doUpdateScreenState}, |
| {"doEnablep2p", "(Z)V", (void*)nfcManager_Enablep2p}, |
| {"doSetProvisionMode", "(Z)V", (void*)nfcManager_setProvisionMode}, |
| {"doGetRouting", "()[B", (void*)nfcManager_getRouting}, |
| {"getNfcInitTimeout", "()I", (void*)nfcManager_getNfcInitTimeout}, |
| {"isVzwFeatureEnabled", "()Z", (void*)nfcManager_isVzwFeatureEnabled}, |
| {"isNfccBusy", "()Z", (void*)nfcManager_isNfccBusy}, |
| #endif |
| {"doSetEEPROM", "([B)V", (void*)nfcManager_doSetEEPROM}, |
| {"doGetSeInterface", "(I)I", (void*)nfcManager_doGetSeInterface}, |
| // Factory Test Code |
| {"doCheckJcopDlAtBoot", "()Z", (void*)nfcManager_doCheckJcopDlAtBoot}, |
| {"doEnableDtaMode", "()V", (void*)nfcManager_doEnableDtaMode}, |
| {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode}, |
| {"getIsoDepMaxTransceiveLength", "()I", |
| (void*)nfcManager_getIsoDepMaxTransceiveLength} |
| #if (NXP_EXTNS == TRUE) |
| , |
| {"doselectUicc", "(I)I", (void*)nfcManager_doSelectUicc}, |
| {"doGetSelectedUicc", "()I", (void*)nfcManager_doGetSelectedUicc}, |
| {"setPreferredSimSlot", "(I)I", (void*)nfcManager_setPreferredSimSlot}, |
| {"routeApduPattern", "(II[B[B)Z", (void*)nfcManager_routeApduPattern}, |
| {"unrouteApduPattern", "([B)Z", (void*)nfcManager_unrouteApduPattern} |
| #endif |
| }; |
| |
| /******************************************************************************* |
| ** |
| ** Function: register_com_android_nfc_NativeNfcManager |
| ** |
| ** Description: Regisgter JNI functions with Java Virtual Machine. |
| ** e: Environment of JVM. |
| ** |
| ** Returns: Status of registration. |
| ** |
| *******************************************************************************/ |
| int register_com_android_nfc_NativeNfcManager(JNIEnv * e) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| return jniRegisterNativeMethods(e, gNativeNfcManagerClassName, gMethods, |
| NELEM(gMethods)); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: startRfDiscovery |
| ** |
| ** Description: Ask stack to start polling and listening for devices. |
| ** isStart: Whether to start. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void startRfDiscovery(bool isStart) { |
| #if (NXP_EXTNS == TRUE) |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| if (sAutonomousSet == 1) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Autonomous mode set don't start RF disc %d", isStart); |
| return; |
| } |
| if ((!gsRouteUpdated) && isStart) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: Routing table update pending.Can not start RF disc. Returning..", |
| __FUNCTION__); |
| return; |
| } |
| if (isStart == sRfEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s Already in RF state: %d", __FUNCTION__, isStart); |
| return; |
| } |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: is start=%d", __func__, isStart); |
| nativeNfcTag_acquireRfInterfaceMutexLock(); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| status = isStart ? NFA_StartRfDiscovery() : NFA_StopRfDiscovery(); |
| if (status == NFA_STATUS_OK) { |
| if (gGeneralPowershutDown == NFC_MODE_OFF) sDiscCmdwhleNfcOff = true; |
| se_rd_req_state_t state = |
| MposManager::getInstance().getEtsiReaederState(); |
| if (state == STATE_SE_RDR_MODE_STOP_IN_PROGRESS || |
| state == STATE_SE_RDR_MODE_ACTIVATED) { |
| sNfaEnableDisablePollingEvent |
| .wait(); // wait for NFA_RF_DISCOVERY_xxxx_EVT |
| } else { |
| sNfaEnableDisablePollingEvent.wait( |
| NFC_CMD_TIMEOUT); // wait for NFA_RF_DISCOVERY_xxxx_EVT |
| } |
| sRfEnabled = isStart; |
| sDiscCmdwhleNfcOff = false; |
| } else { |
| LOG(ERROR) << StringPrintf( |
| "%s: Failed to start/stop RF discovery; error=0x%X", __func__, |
| status); |
| } |
| nativeNfcTag_releaseRfInterfaceMutexLock(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: is exit=%d", __func__, isStart); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: isDiscoveryStarted |
| ** |
| ** Description: Indicates whether the discovery is started. |
| ** |
| ** Returns: True if discovery is started |
| ** |
| *******************************************************************************/ |
| bool isDiscoveryStarted() { return sRfEnabled; } |
| |
| /******************************************************************************* |
| ** |
| ** Function: notifyPollingEventwhileNfcOff |
| ** |
| ** Description: Notifies sNfaEnableDisablePollingEvent if tag operations |
| ** is in progress at the time Nfc Off is in progress to avoid |
| ** NFC off thread infinite block. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void notifyPollingEventwhileNfcOff() { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: sDiscCmdwhleNfcOff=%x", __func__, sDiscCmdwhleNfcOff); |
| if (sDiscCmdwhleNfcOff == true) { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| sNfaEnableDisablePollingEvent.notifyOne(); |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: doStartupConfig |
| ** |
| ** Description: Configure the NFC controller. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void doStartupConfig() { |
| struct nfc_jni_native_data* nat = getNative(0, 0); |
| tNFA_STATUS stat = NFA_STATUS_FAILED; |
| int actualLen = 0; |
| |
| // If polling for Active mode, set the ordering so that we choose Active |
| // over Passive mode first. |
| if (nat && (nat->tech_mask & (NFA_TECHNOLOGY_MASK_A_ACTIVE | |
| NFA_TECHNOLOGY_MASK_F_ACTIVE))) { |
| uint8_t act_mode_order_param[] = {0x01}; |
| SyncEventGuard guard(sNfaSetConfigEvent); |
| stat = NFA_SetConfig(NCI_PARAM_ID_ACT_ORDER, sizeof(act_mode_order_param), |
| &act_mode_order_param[0]); |
| if (stat == NFA_STATUS_OK) sNfaSetConfigEvent.wait(); |
| } |
| |
| // configure RF polling frequency for each technology |
| static tNFA_DM_DISC_FREQ_CFG nfa_dm_disc_freq_cfg; |
| // values in the polling_frequency[] map to members of nfa_dm_disc_freq_cfg |
| uint8_t polling_frequency[8] = {1, 1, 1, 1, 1, 1, 1, 1}; |
| actualLen = GetStrValue(NAME_POLL_FREQUENCY, (char*)polling_frequency, 8); |
| if (actualLen == 8) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: polling frequency", __func__); |
| memset(&nfa_dm_disc_freq_cfg, 0, sizeof(nfa_dm_disc_freq_cfg)); |
| nfa_dm_disc_freq_cfg.pa = polling_frequency[0]; |
| nfa_dm_disc_freq_cfg.pb = polling_frequency[1]; |
| nfa_dm_disc_freq_cfg.pf = polling_frequency[2]; |
| nfa_dm_disc_freq_cfg.pi93 = polling_frequency[3]; |
| nfa_dm_disc_freq_cfg.pbp = polling_frequency[4]; |
| nfa_dm_disc_freq_cfg.pk = polling_frequency[5]; |
| nfa_dm_disc_freq_cfg.paa = polling_frequency[6]; |
| nfa_dm_disc_freq_cfg.pfa = polling_frequency[7]; |
| p_nfa_dm_rf_disc_freq_cfg = &nfa_dm_disc_freq_cfg; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isNfcActive |
| ** |
| ** Description: Used externaly to determine if NFC is active or not. |
| ** |
| ** Returns: 'true' if the NFC stack is running, else 'false'. |
| ** |
| *******************************************************************************/ |
| bool nfcManager_isNfcActive() { return sIsNfaEnabled; } |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isNfcDisabling |
| ** |
| ** Description: Used externaly to determine if NFC is deinit is ongoing or |
| *not. |
| ** |
| ** Returns: 'true' if the NFC deinit is running, else 'false'. |
| ** |
| *******************************************************************************/ |
| bool nfcManager_isNfcDisabling() { return sIsDisabling; } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getNfcState |
| ** |
| ** Description: Used internally and externally to check the current NFC |
| *state |
| ** |
| ** Returns: Returns the current state of NFC. |
| ** |
| *******************************************************************************/ |
| uint8_t nfcManager_getNfcState() { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: sNfcState = %d", __func__, sNfcState); |
| return sNfcState; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: startStopPolling |
| ** |
| ** Description: Start or stop polling. |
| ** isStartPolling: true to start polling; false to stop |
| *polling. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| void startStopPolling(bool isStartPolling) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter; isStart=%u", __func__, isStartPolling); |
| startRfDiscovery(false); |
| |
| if (isStartPolling) |
| startPolling_rfDiscoveryDisabled(0); |
| else |
| stopPolling_rfDiscoveryDisabled(); |
| |
| startRfDiscovery(true); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| static tNFA_STATUS startPolling_rfDiscoveryDisabled( |
| tNFA_TECHNOLOGY_MASK tech_mask) { |
| tNFA_STATUS stat = NFA_STATUS_FAILED; |
| |
| unsigned long num = 0; |
| |
| if (tech_mask == 0 && |
| GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num))) |
| tech_mask = num; |
| else if (tech_mask == 0) |
| tech_mask = DEFAULT_TECH_MASK; |
| |
| nativeNfcTag_acquireRfInterfaceMutexLock(); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enable polling", __func__); |
| stat = NFA_EnablePolling(tech_mask); |
| if (stat == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for enable event", __func__); |
| sPollingEnabled = true; |
| sNfaEnableDisablePollingEvent.wait(); // wait for NFA_POLL_ENABLED_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", |
| __func__, stat); |
| } |
| |
| nativeNfcTag_releaseRfInterfaceMutexLock(); |
| |
| return stat; |
| } |
| |
| static tNFA_STATUS stopPolling_rfDiscoveryDisabled() { |
| tNFA_STATUS stat = NFA_STATUS_FAILED; |
| |
| nativeNfcTag_acquireRfInterfaceMutexLock(); |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: disable polling", __func__); |
| stat = NFA_DisablePolling(); |
| if (stat == NFA_STATUS_OK) { |
| sPollingEnabled = false; |
| sNfaEnableDisablePollingEvent.wait(); // wait for NFA_POLL_DISABLED_EVT |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", |
| __func__, stat); |
| } |
| |
| nativeNfcTag_releaseRfInterfaceMutexLock(); |
| |
| return stat; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getChipVer |
| ** |
| ** Description: Gets the chip version. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None 0x00 |
| ** PN547C2 0x01 |
| ** PN65T 0x02 . |
| ** |
| *******************************************************************************/ |
| static int nfcManager_getChipVer(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| unsigned long num = 0; |
| |
| GetNxpNumValue(NAME_NXP_NFC_CHIP, (void*)&num, sizeof(num)); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%ld: nfcManager_getChipVer", num); |
| return num; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getFwFileName |
| ** |
| ** Description: Read Fw file name from config file. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: jbyteArray: File name read from config file |
| ** NULL in case file name not found |
| ** |
| *******************************************************************************/ |
| static jbyteArray nfcManager_getFwFileName(JNIEnv * e, jobject o) { |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| char fwFileName[256]; |
| int fileLen = 0; |
| jbyteArray jbuff = NULL; |
| |
| if (GetNxpStrValue(NAME_NXP_FW_NAME, (char*)fwFileName, |
| sizeof(fwFileName)) == true) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: FW_NAME read success = %s", __func__, fwFileName); |
| fileLen = strlen(fwFileName); |
| jbuff = e->NewByteArray(fileLen); |
| e->SetByteArrayRegion(jbuff, 0, fileLen, (jbyte*)fwFileName); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: FW_NAME not found", __func__); |
| } |
| |
| return jbuff; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: DWPChannel_init |
| ** |
| ** Description: Initializes the DWP channel functions. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| void DWPChannel_init(IChannel_t * DWP) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| if (nfcFL.nfcNxpEse) { |
| DWP->open = open; |
| DWP->close = close; |
| DWP->transceive = transceive; |
| DWP->doeSE_Reset = doeSE_Reset; |
| DWP->doeSE_JcopDownLoadReset = doeSE_JcopDownLoadReset; |
| } |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doJcosDownload |
| ** |
| ** Description: start jcos download. |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| static int nfcManager_doJcosDownload(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfcNxpEse) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| bool stat = false; |
| int ret_val = -1; |
| NFCSTATUS ese_status = NFA_STATUS_FAILED; |
| p61_access_state_t p61_current_state = P61_STATE_INVALID; |
| eScreenState_t last_screen_state_request = get_lastScreenStateRequest(); |
| SecureElement& se = SecureElement::getInstance(); |
| |
| if (nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) { |
| if (sIsDisabling || !sIsNfaEnabled || nfcManager_checkNfcStateBusy()) { |
| return NFA_STATUS_FAILED; |
| } |
| |
| ret_val = NFC_GetP61Status((void*)&p61_current_state); |
| if (ret_val < 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC_GetP61Status failed"); |
| return NFA_STATUS_FAILED; |
| } |
| if (p61_current_state & P61_STATE_JCP_DWNLD || |
| p61_current_state & P61_STATE_WIRED || |
| p61_current_state & P61_STATE_SPI || |
| p61_current_state & P61_STATE_SPI_PRIO) { |
| return NFA_STATUS_BUSY; |
| } |
| |
| if (sIsDisabling || !sIsNfaEnabled || nfcManager_checkNfcStateBusy()) { |
| return NFA_STATUS_FAILED; |
| } |
| |
| LOG(ERROR) << StringPrintf("%s: start JcopOs_Download 0x%X", __func__, |
| p61_current_state); |
| |
| ret_val = NFC_SetP61Status((void*)&ese_status, JCP_DWNLD_START); |
| if (ret_val < 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC_SetP61Status failed"); |
| } else { |
| if (ese_status != NFCSTATUS_SUCCESS) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Denying to set Jcop OS Download state"); |
| status = ese_status; |
| } else { |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(jcosDownload))) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Transaction in progress. Returning", __func__); |
| return NFA_STATUS_FAILED; |
| } |
| } |
| } |
| } |
| if (sRfEnabled) { |
| // Stop RF Discovery if we were polling |
| startRfDiscovery(false); |
| } |
| DWPChannel_init(&Dwp); |
| status = pJcopMgr->JCDnldInit(&Dwp); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("%s: JCDND initialization failed", __func__); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: start JcopOs_Download", __func__); |
| se.mDownloadMode = JCOP_DOWNLOAD; |
| status = pJcopMgr->JCDnldStartDownload(); |
| } |
| if (nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) { |
| ret_val = NFC_SetP61Status((void*)&ese_status, JCP_DWP_DWNLD_COMPLETE); |
| if (ret_val < 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "NFC_SetP61Status failed Deinit and starting discovery"); |
| } else { |
| if (ese_status != NFCSTATUS_SUCCESS) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Denying to set Jcop OS Download complete state"); |
| status = ese_status; |
| } |
| } |
| } |
| stat = pJcopMgr->JCDnldDeInit(); |
| if (nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(jcosDownload)); |
| if (pendingScreenState == true) { |
| pendingScreenState = false; |
| last_screen_state_request = get_lastScreenStateRequest(); |
| nfcManager_doSetScreenState(NULL, NULL, last_screen_state_request); |
| } |
| } |
| startRfDiscovery(true); |
| se.mDownloadMode = NONE; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| } else { |
| status = 0x0F; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: No p61", __func__); |
| } |
| #endif |
| return status; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| uint8_t getJCOPOS_UpdaterState() { |
| static const char fn[] = "getJCOPOS_UpdaterState"; |
| if (!nfcFL.nfcNxpEse) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: nfcNxpEse not Enabled. Returning.", fn); |
| return OSU_NOT_STARTED; |
| } |
| FILE* fp; |
| unsigned int val = 0; |
| uint8_t state = 0; |
| int32_t result = 0; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn); |
| |
| fp = fopen(JCOP_INFO_PATH, "r"); |
| if (fp != NULL) { |
| result = fscanf(fp, "%u", &val); |
| if (result != 0) { |
| state = (uint8_t)(val & 0x000000FF); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("JcopOsState %d", state); |
| } |
| fclose(fp); |
| } else { |
| LOG(ERROR) << StringPrintf("file <%s> not exits for reading-: %s", |
| JCOP_INFO_PATH, strerror(errno)); |
| } |
| return state; |
| } |
| #endif |
| |
| static void nfcManager_doCommitRouting(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| PowerSwitch::getInstance().setLevel(PowerSwitch::FULL_POWER); |
| PowerSwitch::getInstance().setModeOn(PowerSwitch::HOST_ROUTING); |
| #if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(commitRouting))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Not allowing to commit the routing", __func__); |
| } else { |
| #endif |
| if (sRfEnabled) { |
| /*Stop RF discovery to reconfigure*/ |
| startRfDiscovery(false); |
| } |
| RoutingManager::getInstance().commitRouting(); |
| startRfDiscovery(true); |
| #if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(commitRouting)); |
| } |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| #if (NXP_EXTNS == TRUE) |
| static void nfcManager_doSetNfcMode(JNIEnv * e, jobject o, jint nfcMode) { |
| /* Store the shutdown state */ |
| gGeneralPowershutDown = nfcMode; |
| } |
| #endif |
| bool isNfcInitializationDone() { |
| if (nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY) { |
| return sIsNfaEnabled; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: NFCEE_REMOVED_NTF_RECOVERY not enabled. Returning", __func__); |
| return false; |
| } |
| } |
| /******************************************************************************* |
| ** |
| ** Function: StoreScreenState |
| ** |
| ** Description: Sets screen state |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void StoreScreenState(int state) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| screenstate = state; |
| nfc_ncif_storeScreenState(state); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: getScreenState |
| ** |
| ** Description: returns screen state |
| ** |
| ** Returns: int |
| ** |
| *******************************************************************************/ |
| int getScreenState() { return screenstate; } |
| |
| /******************************************************************************* |
| ** |
| ** Function: isp2pActivated |
| ** |
| ** Description: returns p2pActive state |
| ** |
| ** Returns: bool |
| ** |
| *******************************************************************************/ |
| bool isp2pActivated() { |
| if (nfcFL.nfcNxpEse) { |
| return sP2pActive; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: nfcNxpEse not set. Returning", __func__); |
| return false; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doGetNciVersion |
| ** |
| ** Description: get the nci version. |
| ** |
| ** Returns: int |
| ** |
| *******************************************************************************/ |
| static jint nfcManager_doGetNciVersion(JNIEnv*, jobject) { |
| return NFC_GetNCIVersion(); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetScreenState |
| ** |
| ** Description: Set screen state |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSetScreenState(JNIEnv * e, jobject o, |
| jint screen_state_mask) { |
| tNFA_STATUS status = NFA_STATUS_OK; |
| unsigned long auto_num = 0; |
| uint8_t standby_num = 0x00; |
| uint8_t* buffer = NULL; |
| long bufflen = 260; |
| long retlen = 0; |
| int isfound; |
| uint8_t discovry_param = |
| NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK; |
| uint8_t state = (screen_state_mask & NFA_SCREEN_STATE_MASK); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Enter state = %d", __func__, state); |
| |
| if (sIsDisabling || !sIsNfaEnabled) { |
| return; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(setScreenState))) { |
| LOG(ERROR) << StringPrintf("Payment is in progress!!!"); |
| set_lastScreenStateRequest((eScreenState_t)state); |
| pendingScreenState = true; |
| return; |
| } |
| #endif |
| pendingScreenState = false; |
| int prevScreenState = getScreenState(); |
| if (prevScreenState == state && |
| get_lastScreenStateRequest() == NFA_SCREEN_STATE_UNKNOWN) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Screen state is not changed. "); |
| #if (NXP_EXTNS == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(setScreenState)); |
| #endif |
| return; |
| } |
| if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { |
| if (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED || |
| prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED || |
| prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) { |
| SyncEventGuard guard(sNfaSetPowerSubState); |
| status = NFA_SetPowerSubStateForScreenState(state); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: fail enable SetScreenState; error=0x%X", __FUNCTION__, |
| status); |
| } else { |
| sNfaSetPowerSubState.wait(); |
| } |
| } |
| |
| if (state == NFA_SCREEN_STATE_OFF_LOCKED || |
| state == NFA_SCREEN_STATE_OFF_UNLOCKED) { |
| // disable both poll and listen on DH 0x02 |
| discovry_param = |
| NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_DISABLE_MASK; |
| } |
| |
| if (state == NFA_SCREEN_STATE_ON_LOCKED) { |
| // disable poll and enable listen on DH 0x00 |
| discovry_param = |
| (screen_state_mask & NFA_SCREEN_POLLING_TAG_MASK) |
| ? (NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK) |
| : (NCI_POLLING_DH_DISABLE_MASK | |
| NCI_LISTEN_DH_NFCEE_ENABLE_MASK); |
| } |
| |
| if (state == NFA_SCREEN_STATE_ON_UNLOCKED) { |
| // enable both poll and listen on DH 0x01 |
| discovry_param = |
| NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK; |
| } |
| |
| SyncEventGuard guard(sNfaSetConfigEvent); |
| status = |
| NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM, |
| NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param); |
| if (status == NFA_STATUS_OK) { |
| sNfaSetConfigEvent.wait(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Disabled RF field events", __FUNCTION__); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Failed to disable RF field events", |
| __FUNCTION__); |
| return; |
| } |
| |
| if (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) { |
| SyncEventGuard guard(sNfaSetPowerSubState); |
| status = NFA_SetPowerSubStateForScreenState(state); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf( |
| "%s: fail enable SetScreenState; error=0x%X", __FUNCTION__, |
| status); |
| } else { |
| sNfaSetPowerSubState.wait(); |
| } |
| } |
| StoreScreenState(state); |
| #if (NXP_EXTNS == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(setScreenState)); |
| #endif |
| return; |
| } |
| if (state) { |
| if (sRfEnabled) { |
| // Stop RF discovery to reconfigure |
| startRfDiscovery(false); |
| } |
| |
| if (state == NFA_SCREEN_STATE_OFF_UNLOCKED || |
| state == NFA_SCREEN_STATE_OFF_LOCKED || |
| state == NFA_SCREEN_STATE_ON_LOCKED) { |
| SyncEventGuard guard(sNfaEnableDisablePollingEvent); |
| status = NFA_DisablePolling(); |
| if (status == NFA_STATUS_OK) { |
| sNfaEnableDisablePollingEvent |
| .wait(); // wait for NFA_POLL_DISABLED_EVT |
| } else |
| LOG(ERROR) << StringPrintf( |
| "%s: Failed to disable polling; error=0x%X", __func__, status); |
| } |
| |
| if (GetNxpNumValue(NAME_NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE, &auto_num, |
| sizeof(auto_num))) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: enter; NAME_NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE = %02lx", |
| __func__, auto_num); |
| } |
| |
| status = SetScreenState(state); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X", |
| __func__, status); |
| } else { |
| if (((prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED || |
| prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED) && |
| state == NFA_SCREEN_STATE_ON_LOCKED) || |
| #if (NXP_EXTNS == TRUE) |
| (prevScreenState == NFA_SCREEN_STATE_ON_LOCKED && |
| state == NFA_SCREEN_STATE_ON_UNLOCKED && sProvisionMode) || |
| #endif |
| (prevScreenState == NFA_SCREEN_STATE_ON_LOCKED && |
| (state == NFA_SCREEN_STATE_OFF_LOCKED || |
| state == NFA_SCREEN_STATE_OFF_UNLOCKED) && |
| sIsSecElemSelected)) { |
| if (auto_num != 0x01) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Start RF discovery"); |
| startRfDiscovery(true); |
| } |
| } |
| StoreScreenState(state); |
| } |
| if (sAutonomousSet == 1) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Send Core reset"); |
| NxpNfc_Send_CoreResetInit_Cmd(); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: auto_num : %lu sAutonomousSet : %d sRfFieldOff : %d", __func__, |
| auto_num, sAutonomousSet, sRfFieldOff); |
| if ((auto_num == 0x01) && (sAutonomousSet != 1) && |
| (sRfFieldOff == true) && |
| (state == NFA_SCREEN_STATE_OFF_LOCKED || |
| state == NFA_SCREEN_STATE_OFF_UNLOCKED)) { |
| buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t)); |
| if (buffer == NULL) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: enter; NAME_NXP_CORE_STANDBY buffer is NULL", __func__); |
| } else { |
| isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char*)buffer, |
| bufflen, &retlen); |
| if (retlen > 0) { |
| standby_num = buffer[3]; |
| } |
| status = SendAutonomousMode(state, standby_num); |
| sAutonomousSet = 1; |
| } |
| } else { |
| sAutonomousSet = 0; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Not sending AUTONOMOUS command state is %d", state); |
| if (!sRfEnabled) { |
| // Start RF discovery if not |
| startRfDiscovery(true); |
| } |
| } |
| if (buffer) { |
| free(buffer); |
| } |
| } |
| #if (NXP_EXTNS == TRUE) |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(setScreenState)); |
| #endif |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Exit", __func__); |
| } |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doSetScreenOrPowerState |
| ** This function combines both screen state and power |
| *state(ven power) values. |
| ** |
| ** Description: Set screen or power state |
| ** e: JVM environment. |
| ** o: Java object. |
| ** state:represents power or screen state (0-3 screen |
| *state),6 (power on),7(power off) |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManager_doSetScreenOrPowerState(JNIEnv * e, jobject o, |
| jint state) { |
| LOG(ERROR) << StringPrintf("%s: Enter", __func__); |
| if ((state & NFA_SCREEN_STATE_MASK) <= |
| NFA_SCREEN_STATE_ON_UNLOCKED) // SCREEN_STATE |
| nfcManager_doSetScreenState(e, o, state); |
| else if ((state & NFA_SCREEN_STATE_MASK) == |
| VEN_POWER_STATE_ON) // POWER_ON NFC_OFF |
| { |
| nfcManager_doSetNfcMode(e, o, NFC_MODE_OFF); |
| } else if ((state & NFA_SCREEN_STATE_MASK) == |
| VEN_POWER_STATE_OFF) // POWER_OFF |
| { |
| if (sIsNfaEnabled) { |
| if (nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION && |
| (SecureElement::getInstance().mDownloadMode == JCOP_DOWNLOAD)) { |
| DwpChannel::getInstance().forceClose(); |
| } |
| nfcManager_doSetNfcMode(e, o, NFC_MODE_ON); // POWER_OFF NFC_ON |
| } else { |
| nfcManager_doSetNfcMode(e, o, NFC_MODE_OFF); // POWER_OFF NFC_OFF |
| } |
| } else |
| LOG(ERROR) << StringPrintf("%s: unknown screen or power state. state=%d", |
| __func__, state); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isRequestPending() |
| ** |
| ** Description: Checks If any pending request |
| ** |
| ** Returns: true if any request pending else false |
| ** |
| *******************************************************************************/ |
| bool nfcManager_isRequestPending(void) { |
| bool isPending = false; |
| if ((transaction_data.current_transcation_state != |
| NFA_TRANS_DM_RF_TRANS_END) && |
| ((pendingScreenState == true) || (get_last_request() != 0x00))) { |
| isPending = true; |
| } |
| return isPending; |
| } |
| #endif |
| /******************************************************************************* |
| ** |
| ** Function: get_last_request |
| ** |
| ** Description: returns the last enable/disable discovery event |
| ** |
| ** Returns: last request (char) . |
| ** |
| *******************************************************************************/ |
| static char get_last_request() { return (transaction_data.last_request); } |
| /******************************************************************************* |
| ** |
| ** Function: set_last_request |
| ** |
| ** Description: stores the last enable/disable discovery event |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| static void set_last_request(char status, struct nfc_jni_native_data* nat) { |
| if ((status == ENABLE_DISCOVERY) || (status == DISABLE_DISCOVERY)) { |
| transaction_data.last_request &= CLEAR_ENABLE_DISABLE_PARAM; |
| } |
| #if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE) |
| transaction_data.last_request |= status; |
| #else |
| transaction_data.last_request = status; |
| #endif |
| if (nat != NULL) { |
| transaction_data.transaction_nat = nat; |
| } |
| } |
| /******************************************************************************* |
| ** |
| ** Function: get_lastScreenStateRequest |
| ** |
| ** Description: returns the last screen state request |
| ** |
| ** Returns: last screen state request event (eScreenState_t) . |
| ** |
| *******************************************************************************/ |
| static eScreenState_t get_lastScreenStateRequest() { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: %d", __func__, transaction_data.last_screen_state_request); |
| return (transaction_data.last_screen_state_request); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: set_lastScreenStateRequest |
| ** |
| ** Description: stores the last screen state request |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| static void set_lastScreenStateRequest(eScreenState_t status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: current=%d, new=%d", __func__, |
| transaction_data.last_screen_state_request, status); |
| transaction_data.last_screen_state_request = status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: switchBackTimerProc_transaction |
| ** |
| ** Description: Callback function for interval timer. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| #if 0 |
| static void cleanupTimerProc_transaction(union sigval) |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Inside cleanupTimerProc"); |
| cleanup_timer(); |
| } |
| |
| void cleanup_timer() |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Inside cleanup"); |
| pthread_t transaction_thread; |
| int irret = -1; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| |
| /* Transcation is done process the last request*/ |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| irret = pthread_create(&transaction_thread, &attr, enableThread, NULL); |
| if(irret != 0) |
| { |
| LOG(ERROR) << StringPrintf("Unable to create the thread"); |
| } |
| pthread_attr_destroy(&attr); |
| transaction_data.current_transcation_state = NFA_TRANS_DM_RF_TRANS_END; |
| } |
| #endif |
| |
| #if (NXP_EXTNS == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: update_transaction_stat |
| ** |
| ** Description: updates the transaction status set/reset |
| ** req_handle : Requesting handle - Module name |
| ** req_state : SET_TRANSACTION_STATE / RESET_TRANSACTION_STATE |
| ** |
| ** Returns: update status |
| ** ret_stat : true/false |
| ** |
| *******************************************************************************/ |
| #if 0 |
| bool update_transaction_stat(const char * req_handle, transaction_state_t req_state) |
| { |
| bool ret_stat = false; |
| |
| gTransactionMutex.lock(); |
| /*Check if it is initialisation*/ |
| if((req_handle == NULL)&&(req_state == RESET_TRANSACTION_STATE)) |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Initialisation. Resetting transaction data", __func__); |
| transaction_data.trans_in_progress = false; |
| cur_transaction_handle = NULL; |
| ret_stat = true; |
| } |
| else |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Enter. Requested by : %s Requested state : %s", __func__,req_handle,(req_state?"SET":"RESET")); |
| } |
| |
| /*Check if no transaction is currently ongoing*/ |
| if(!transaction_data.trans_in_progress) |
| { |
| if(req_state == SET_TRANSACTION_STATE) |
| { |
| transaction_data.trans_in_progress = req_state; |
| cur_transaction_handle = req_handle; |
| ret_stat = true; |
| /*Using a backup reset procedure as a timer to reset Transaction state, |
| *in case Transaction state is set but not reset because of some reason |
| * |
| *Also timer should not be started for below handles as these may take |
| *more time to reset depending on the transaction duration |
| **/ |
| if(strcmp(req_handle,"NFA_ACTIVATED_EVT") && |
| strcmp(req_handle,"NFA_EE_ACTION_EVT") && |
| strcmp(req_handle,"NFA_TRANS_CE_ACTIVATED") && |
| strcmp(req_handle,"RF_FIELD_EVT") ) |
| { |
| scleanupTimerProc_transaction.set (10000, cleanupTimerProc_transaction); |
| } |
| |
| } |
| else |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:Transaction state is already free. Returning", __func__); |
| cur_transaction_handle = NULL; |
| ret_stat = true; |
| scleanupTimerProc_transaction.kill (); |
| } |
| } |
| else |
| { |
| /*If transaction_stat is already set (transaction is ongoing) it can not be set again*/ |
| if(req_state == SET_TRANSACTION_STATE) |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:Transaction is in progress by : %s . Returning", __func__,cur_transaction_handle); |
| ret_stat = false; |
| } |
| else |
| { |
| /*If transaction_stat is already set only authorised module can reset it |
| *It should be either cur_transaction_handle (which has set transaction_stat) or |
| *exec_pending_req*/ |
| if(cur_transaction_handle != NULL) |
| { |
| if(!strcmp(cur_transaction_handle,req_handle) || !strcmp(req_handle,"exec_pending_req")) |
| { |
| transaction_data.trans_in_progress = req_state; |
| cur_transaction_handle = NULL; |
| ret_stat = true; |
| scleanupTimerProc_transaction.kill (); |
| } |
| else |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:Handle Mismatch. Returning ..cur_transaction_handle : %s Requested handle : %s ", __func__,cur_transaction_handle,req_handle); |
| ret_stat = false; |
| } |
| } |
| else |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: No cur_transaction_handle. Allowing requested handle : %s ", __func__,req_handle); |
| transaction_data.trans_in_progress = req_state; |
| cur_transaction_handle = req_handle; |
| ret_stat = true; |
| scleanupTimerProc_transaction.kill (); |
| } |
| } |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Exit. Requested by : %s Requested state : %s status : %s", __func__,req_handle,(req_state?"SET":"RESET"), (ret_stat?"SUCCESS":"FAILED")); |
| gTransactionMutex.unlock(); |
| return ret_stat; |
| } |
| #endif |
| #endif |
| /******************************************************************************* |
| ** |
| ** Function: checkforTranscation |
| ** |
| ** Description: Receive connection-related events from stack. |
| ** connEvent: Event code. |
| ** eventData: Event data. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void checkforTranscation(uint8_t connEvent, void* eventData) { |
| tNFA_CONN_EVT_DATA* eventAct_Data = (tNFA_CONN_EVT_DATA*)eventData; |
| tNFA_DM_CBACK_DATA* eventDM_Conn_data = (tNFA_DM_CBACK_DATA*)eventData; |
| tNFA_EE_CBACK_DATA* ee_action_data = (tNFA_EE_CBACK_DATA*)eventData; |
| tNFA_EE_ACTION& action = ee_action_data->action; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: enter; event=0x%X transaction_data.current_transcation_state = " |
| "0x%x", |
| __func__, connEvent, transaction_data.current_transcation_state); |
| switch (connEvent) { |
| case NFA_ACTIVATED_EVT: |
| if ((eventAct_Data->activated.activate_ntf.protocol != |
| NFA_PROTOCOL_NFC_DEP) && |
| (isListenMode(eventAct_Data->activated))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("ACTIVATED_EVT setting flag"); |
| transaction_data.current_transcation_state = NFA_TRANS_ACTIVATED_EVT; |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(NFA_ACTIVATED_EVENT))) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Transaction in progress. Can not set", __func__); |
| } |
| #endif |
| } else { |
| // DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("other |
| // event clearing flag "); |
| // memset(&transaction_data, 0x00, |
| // sizeof(Transcation_Check_t)); |
| } |
| break; |
| case NFA_EE_ACTION_EVT: |
| if (transaction_data.current_transcation_state == NFA_TRANS_DEFAULT || |
| transaction_data.current_transcation_state == |
| NFA_TRANS_ACTIVATED_EVT) { |
| if (getScreenState() == NFA_SCREEN_STATE_OFF_LOCKED || |
| getScreenState() == NFA_SCREEN_STATE_OFF_UNLOCKED) { |
| if (!sP2pActive && |
| eventDM_Conn_data->rf_field.status == NFA_STATUS_OK) |
| SecureElement::getInstance().notifyRfFieldEvent(true); |
| } |
| if (nfcFL.chipType == pn547C2) { |
| if ((action.param.technology == NFC_RF_TECHNOLOGY_A) && |
| ((getScreenState() == NFA_SCREEN_STATE_OFF_UNLOCKED || |
| getScreenState() == NFA_SCREEN_STATE_ON_LOCKED || |
| getScreenState() == NFA_SCREEN_STATE_OFF_LOCKED))) { |
| transaction_data.current_transcation_state = |
| NFA_TRANS_MIFARE_ACT_EVT; |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(NFA_EE_ACTION_EVENT))) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Transaction in progress. Can not set", __func__); |
| } |
| #endif |
| } |
| } else { |
| transaction_data.current_transcation_state = |
| NFA_TRANS_EE_ACTION_EVT; |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(NFA_EE_ACTION_EVENT))) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Transaction in progress. Can not set", __func__); |
| } |
| #endif |
| } |
| } |
| break; |
| case NFA_TRANS_CE_ACTIVATED: |
| if (transaction_data.current_transcation_state == NFA_TRANS_DEFAULT || |
| transaction_data.current_transcation_state == |
| NFA_TRANS_ACTIVATED_EVT) { |
| if (getScreenState() == NFA_SCREEN_STATE_OFF_LOCKED || |
| getScreenState() == NFA_SCREEN_STATE_OFF_UNLOCKED) { |
| if (!sP2pActive && |
| eventDM_Conn_data->rf_field.status == NFA_STATUS_OK) |
| SecureElement::getInstance().notifyRfFieldEvent(true); |
| } |
| transaction_data.current_transcation_state = NFA_TRANS_CE_ACTIVATED; |
| #if (NXP_EXTNS == TRUE) |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(NFA_TRANS_CE_ACTIVATED_EVENT))) { |
| LOG(ERROR) << StringPrintf( |
| "%s: Transaction in progress. Can not set", __func__); |
| } |
| #endif |
| } |
| break; |
| case NFA_TRANS_CE_DEACTIVATED: |
| rfActivation = false; |
| #if (NXP_EXTNS == TRUE) |
| if (transaction_data.current_transcation_state == |
| NFA_TRANS_CE_ACTIVATED) { |
| transaction_data.current_transcation_state = NFA_TRANS_CE_DEACTIVATED; |
| } |
| #endif |
| gActivated = false; |
| break; |
| case NFA_DEACTIVATED_EVT: |
| if (nfcFL.chipType == pn547C2) { |
| if (transaction_data.current_transcation_state == |
| NFA_TRANS_MIFARE_ACT_EVT) { |
| pTransactionController->lastRequestResume(); |
| } |
| } |
| break; |
| case NFA_TRANS_DM_RF_FIELD_EVT: |
| if (eventDM_Conn_data->rf_field.status == NFA_STATUS_OK && |
| (transaction_data.current_transcation_state == |
| NFA_TRANS_EE_ACTION_EVT || |
| transaction_data.current_transcation_state == |
| NFA_TRANS_CE_DEACTIVATED || |
| transaction_data.current_transcation_state == |
| NFA_TRANS_CE_ACTIVATED || |
| transaction_data.current_transcation_state == |
| NFA_TRANS_ACTIVATED_EVT) && |
| eventDM_Conn_data->rf_field.rf_field_status == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("start_timer"); |
| if (nfcFL.chipType != pn547C2) { |
| set_AGC_process_state(false); |
| } |
| transaction_data.current_transcation_state = |
| NFA_TRANS_DM_RF_FIELD_EVT_OFF; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Start guard RF ON timer"); |
| pTransactionController->setAbortTimer(50 /*msec*/); |
| } else if (eventDM_Conn_data->rf_field.status == NFA_STATUS_OK && |
| transaction_data.current_transcation_state == |
| NFA_TRANS_DM_RF_FIELD_EVT_OFF && |
| eventDM_Conn_data->rf_field.rf_field_status == 1) { |
| if (nfcFL.chipType != pn547C2) { |
| nfcManagerEnableAGCDebug(connEvent); |
| } |
| transaction_data.current_transcation_state = |
| NFA_TRANS_DM_RF_FIELD_EVT_ON; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Payment is in progress hold the screen on/off request "); |
| transaction_data.current_transcation_state = |
| NFA_TRANS_DM_RF_TRANS_START; |
| pTransactionController->killAbortTimer(); |
| |
| } else if (eventDM_Conn_data->rf_field.status == NFA_STATUS_OK && |
| transaction_data.current_transcation_state == |
| NFA_TRANS_DM_RF_TRANS_START && |
| eventDM_Conn_data->rf_field.rf_field_status == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Transcation is done"); |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(RF_FIELD_EVT)); |
| if (nfcFL.chipType != pn547C2) { |
| set_AGC_process_state(false); |
| } |
| transaction_data.current_transcation_state = |
| NFA_TRANS_DM_RF_TRANS_PROGRESS; |
| pTransactionController->lastRequestResume(); |
| } else if (eventDM_Conn_data->rf_field.status == NFA_STATUS_OK && |
| transaction_data.current_transcation_state == |
| NFA_TRANS_ACTIVATED_EVT && |
| eventDM_Conn_data->rf_field.rf_field_status == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("No transaction done cleaning up the variables"); |
| pTransactionController->lastRequestResume(); |
| } |
| break; |
| default: |
| break; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: exit; event=0x%X transaction_data.current_transcation_state = " |
| "0x%x", |
| __func__, connEvent, transaction_data.current_transcation_state); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: enableThread |
| ** |
| ** Description: thread to trigger enable/disable discovery related events |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| void* enableThread(void* arg) { |
| (void)arg; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| char last_request = get_last_request(); |
| eScreenState_t last_screen_state_request = get_lastScreenStateRequest(); |
| if (nfcFL.chipType != pn547C2) { |
| set_AGC_process_state(false); |
| } |
| |
| bool screen_lock_flag = false; |
| bool disable_discovery = false; |
| |
| if (sIsNfaEnabled != true || sIsDisabling == true) goto TheEnd; |
| |
| if (last_screen_state_request != NFA_SCREEN_STATE_UNKNOWN) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "update last screen state request: %d", last_screen_state_request); |
| nfcManager_doSetScreenState(NULL, NULL, last_screen_state_request); |
| set_lastScreenStateRequest(NFA_SCREEN_STATE_UNKNOWN); |
| if (last_screen_state_request == NFA_SCREEN_STATE_ON_LOCKED) |
| screen_lock_flag = true; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("No request pending"); |
| } |
| |
| if (last_request & ENABLE_DISCOVERY) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("send the last request enable"); |
| sDiscoveryEnabled = false; |
| sPollingEnabled = false; |
| |
| transaction_data.last_request &= ~(ENABLE_DISCOVERY); |
| nfcManager_enableDiscovery( |
| NULL, NULL, transaction_data.discovery_params.technologies_mask, |
| transaction_data.discovery_params.enable_lptd, |
| transaction_data.discovery_params.reader_mode, |
| transaction_data.discovery_params.enable_p2p, |
| transaction_data.discovery_params.restart); |
| } |
| |
| if (last_request & DISABLE_DISCOVERY) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("send the last request disable"); |
| transaction_data.last_request &= ~(DISABLE_DISCOVERY); |
| nfcManager_disableDiscovery(NULL, NULL); |
| disable_discovery = true; |
| } |
| #if (NXP_EXTNS == TRUE) |
| if (last_request & ENABLE_P2P) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("send the last request to enable P2P "); |
| nfcManager_Enablep2p(NULL, NULL, |
| transaction_data.discovery_params.enable_p2p); |
| transaction_data.last_request &= ~(ENABLE_P2P); |
| } |
| #if (NXP_NFCC_HCE_F == TRUE) |
| if (last_request & T3T_CONFIGURE) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| " transaction_data.t3thandle %d ", transaction_data.t3thandle); |
| if (transaction_data.t3thandle != 0) { |
| RoutingManager::getInstance().deregisterT3tIdentifier( |
| transaction_data.t3thandle); |
| } |
| transaction_data.last_request &= ~(T3T_CONFIGURE); |
| RoutingManager::getInstance().notifyT3tConfigure(); |
| } |
| #endif |
| if (last_request & RE_ROUTING) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf(" transaction_data.isInstallRequest %d ", |
| transaction_data.isInstallRequest); |
| if (!transaction_data.isInstallRequest) { |
| RoutingManager::getInstance().clearAidTable(); |
| // nfcManager_doCommitRouting(NULL,NULL); |
| } |
| transaction_data.last_request &= ~(RE_ROUTING); |
| RoutingManager::getInstance().notifyReRoutingEntry(); |
| } |
| #endif |
| if (screen_lock_flag && disable_discovery) { |
| startRfDiscovery(true); |
| } |
| screen_lock_flag = false; |
| disable_discovery = false; |
| last_screen_state_request = transaction_data.last_screen_state_request; |
| last_request = transaction_data.last_request; |
| memset(&transaction_data, 0x00, sizeof(Transcation_Check_t)); |
| |
| transaction_data.last_request = last_request; |
| set_lastScreenStateRequest(last_screen_state_request); |
| |
| if (nfcFL.chipType != pn547C2) { |
| memset(&menableAGC_debug_t, 0x00, sizeof(enableAGC_debug_t)); |
| } |
| TheEnd: |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| pthread_exit(NULL); |
| return NULL; |
| } |
| /******************************************************************************* |
| ** |
| ** Function sig_handler |
| ** |
| ** Description This function is used to handle the different types of |
| ** signal events. |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| void sig_handler(int signo) { |
| if (!nfcFL.eseFL._JCOP_WA_ENABLE) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("JCOP_WA_ENABLE not available..Returning"); |
| return; |
| } |
| switch (signo) { |
| case SIGINT: |
| LOG(ERROR) << StringPrintf("received SIGINT\n"); |
| break; |
| case SIGABRT: |
| LOG(ERROR) << StringPrintf("received SIGABRT\n"); |
| #if (NXP_EXTNS == TRUE) |
| if (nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD) { |
| NFA_MW_Fwdnlwd_Recovery(true); |
| } |
| #endif |
| NFA_HciW4eSETransaction_Complete(Wait); |
| break; |
| case SIGSEGV: |
| LOG(ERROR) << StringPrintf("received SIGSEGV\n"); |
| break; |
| case SIGHUP: |
| LOG(ERROR) << StringPrintf("received SIGHUP\n"); |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function nfcManager_doGetSeInterface |
| ** |
| ** Description This function is used to get the eSE Client interfaces. |
| ** |
| ** Returns integer - Physical medium |
| ** |
| *******************************************************************************/ |
| static int nfcManager_doGetSeInterface(JNIEnv * e, jobject o, jint type) { |
| unsigned long num = 0; |
| switch (type) { |
| case LDR_SRVCE: |
| if (GetNxpNumValue(NAME_NXP_P61_LS_DEFAULT_INTERFACE, (void*)&num, |
| sizeof(num)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_NXP_P61_LS_DEFAULT_INTERFACE not found"); |
| num = 1; |
| } |
| break; |
| case JCOP_SRVCE: |
| if (GetNxpNumValue(NAME_NXP_P61_JCOP_DEFAULT_INTERFACE, (void*)&num, |
| sizeof(num)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_NXP_P61_JCOP_DEFAULT_INTERFACE not found"); |
| num = 1; |
| } |
| break; |
| case LTSM_SRVCE: |
| if (GetNxpNumValue(NAME_NXP_P61_LTSM_DEFAULT_INTERFACE, (void*)&num, |
| sizeof(num)) == false) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_NXP_P61_LTSM_DEFAULT_INTERFACE not found"); |
| num = 1; |
| } |
| break; |
| default: |
| break; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%ld: nfcManager_doGetSeInterface", num); |
| return num; |
| } |
| |
| #if (NXP_EXTNS == TRUE) |
| /********************************************************************************** |
| ** |
| ** Function: pollT3TThread |
| ** |
| ** Description: This thread sends commands to switch from P2P to T3T |
| ** When ReaderMode is enabled, When P2P is detected,Switch to |
| *T3T |
| ** with Frame RF interface and Poll for T3T |
| ** |
| ** Returns: None. |
| ** |
| **********************************************************************************/ |
| static void* pollT3TThread(void* arg) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| bool status = false; |
| |
| if (sReaderModeEnabled && (sTechMask & NFA_TECHNOLOGY_MASK_F)) { |
| /*Deactivate RF to go to W4_HOST_SELECT state |
| *Send Select Command to Switch to FrameRF interface from NFCDEP |
| *interface |
| *After NFC-DEP activation with FrameRF Intf, invoke T3T Polling Cmd*/ |
| { |
| SyncEventGuard g(sRespCbEvent); |
| if (NFA_STATUS_OK != |
| (status = NFA_Deactivate(true))) // deactivate to sleep state |
| { |
| LOG(ERROR) << StringPrintf("%s: deactivate failed, status = %d", |
| __func__, status); |
| } |
| if (sRespCbEvent.wait(2000) == false) // if timeout occurred |
| { |
| LOG(ERROR) << StringPrintf("%s: timeout waiting for deactivate", |
| __func__); |
| } |
| } |
| { |
| SyncEventGuard g2(sRespCbEvent); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Switching RF Interface from NFC-DEP to FrameRF for T3T\n"); |
| if (NFA_STATUS_OK != |
| (status = NFA_Select(*((uint8_t*)arg), NFA_PROTOCOL_T3T, |
| NFA_INTERFACE_FRAME))) { |
| LOG(ERROR) << StringPrintf("%s: NFA_Select failed, status = %d", |
| __func__, status); |
| } |
| if (sRespCbEvent.wait(2000) == false) // if timeout occured |
| { |
| LOG(ERROR) << StringPrintf("%s: timeout waiting for select", |
| __func__); |
| } |
| } |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| pthread_exit(NULL); |
| return NULL; |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: switchP2PToT3TRead |
| ** |
| ** Description: Create a thread to change the RF interface by Deactivating |
| *to Sleep |
| ** |
| ** Returns: None. |
| ** |
| **********************************************************************************/ |
| static bool switchP2PToT3TRead(uint8_t disc_id) { |
| pthread_t pollT3TThreadId; |
| int irret = -1; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:entry", __func__); |
| felicaReader_Disc_id = disc_id; |
| |
| /* Transcation is done process the last request*/ |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| irret = pthread_create(&pollT3TThreadId, &attr, pollT3TThread, |
| (void*)&felicaReader_Disc_id); |
| if (irret != 0) { |
| LOG(ERROR) << StringPrintf("Unable to create the thread"); |
| } |
| pthread_attr_destroy(&attr); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:exit", __func__); |
| return irret; |
| } |
| |
| static void NxpResponsePropCmd_Cb(uint8_t event, uint16_t param_len, |
| uint8_t * p_param) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "NxpResponsePropCmd_Cb Received length data = 0x%x status = 0x%x", |
| param_len, p_param[3]); |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.notifyOne(); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_setProvisionMode |
| ** |
| ** Description: set/reset provision mode |
| ** e: JVM environment. |
| ** o: Java object. |
| ** |
| ** Returns: None. |
| ** |
| *******************************************************************************/ |
| static void nfcManager_setProvisionMode(JNIEnv * e, jobject o, |
| jboolean provisionMode) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Enter :%s provisionMode = %d", __func__, provisionMode); |
| sProvisionMode = provisionMode; |
| NFA_setProvisionMode(provisionMode); |
| // When disabling provisioning mode, make sure configuration of routing |
| // table is also updated |
| // this is required to make sure p2p is blocked during locked screen |
| if (!provisionMode) { |
| RoutingManager::getInstance().commitRouting(); |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: isActivatedTypeF |
| ** |
| ** Description: Indicates whether the activation data indicates it is |
| ** TypeF technology. |
| ** |
| ** Returns: True if activated technology is TypeF. |
| ** |
| *******************************************************************************/ |
| static bool isActivatedTypeF(tNFA_ACTIVATED & activated) { |
| return ((NFC_DISCOVERY_TYPE_POLL_F == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_F == |
| activated.activate_ntf.rf_tech_param.mode) || |
| (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == |
| activated.activate_ntf.rf_tech_param.mode)); |
| } |
| /********************************************************************************** |
| ** |
| ** Function: eSEPhyIntfInResponsive |
| ** |
| ** Description: checking inactivity of eSE physical interface |
| ** |
| ** Returns: 1(if true)/0 (if false) . |
| ** |
| **********************************************************************************/ |
| static uint32_t eSEPhyIntfInResponsive(tNFA_DM_CBACK_DATA * pEvtData) { |
| LOG(ERROR) << StringPrintf("%s: param_tlvs %x", __func__, |
| pEvtData->get_config.param_tlvs[5]); |
| if (nfcFL.chipType != pn553) |
| return (IS_ESE_RF_CE_PARAM_FETCHED() && IS_ESE_CE_MODE_DISABLED() && |
| SecureElement::getInstance().getEeStatus(ESE_HANDLE) == |
| NFA_EE_STATUS_ACTIVE); |
| else |
| return 0; |
| } |
| /********************************************************************************** |
| ** |
| ** Function: recoverEseConnectivity |
| ** |
| ** Description: reset eSE connection for recovering communication |
| ** |
| ** Returns: None |
| ** |
| **********************************************************************************/ |
| static void recoverEseConnectivity() { |
| tNFA_STATUS stat = ResetEseSession(); |
| if (stat == NFA_STATUS_OK) { |
| SecureElement::getInstance().SecEle_Modeset(0x00); |
| usleep(50 * 1000); |
| SecureElement::getInstance().SecEle_Modeset(0x01); |
| } |
| } |
| /********************************************************************************** |
| ** |
| ** Function: checkforNfceeBuffer |
| ** |
| ** Description: checking for the Nfcee Buffer (GetConfigs for |
| *SWP_INT_SESSION_ID (EA and EB)) |
| ** |
| ** Returns: None . |
| ** |
| **********************************************************************************/ |
| void checkforNfceeBuffer() { |
| int i, count = 0; |
| |
| for (i = 4; i < 12; i++) { |
| if (sConfig[i] == 0xff) count++; |
| } |
| |
| if (count >= 8) { |
| /*If session ID received all 0xff for UICC and dual UICC feature is |
| * enabled then |
| * clear the corresponding buffer (invalid session ID) |
| * */ |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH && |
| ((sConfig[1] == 0xA0) && (sConfig[2] == 0xEA) && |
| (dualUiccInfo.dualUiccEnable == 0x01))) { |
| if (sSelectedUicc == 0x01) { |
| memset(dualUiccInfo.sUicc1SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc1SessionId)); |
| dualUiccInfo.sUicc1SessionIdLen = 0; |
| } else { |
| memset(dualUiccInfo.sUicc2SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc2SessionId)); |
| dualUiccInfo.sUicc2SessionIdLen = 0; |
| } |
| } |
| sNfceeConfigured = 1; |
| } else { |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| if ((sConfig[1] == 0xA0) && (sConfig[2] == 0xEA) && |
| (dualUiccInfo.dualUiccEnable == 0x01)) { |
| sNfceeConfigured = getUiccSession(); |
| } else { |
| sNfceeConfigured = 0; |
| } |
| } else { |
| sNfceeConfigured = 0; |
| } |
| } |
| |
| memset(sConfig, 0, sizeof(sConfig)); |
| } |
| /********************************************************************************** |
| ** |
| ** Function: checkforNfceeConfig |
| ** |
| ** Description: checking for the Nfcee is configured or not (GetConfigs |
| *for SWP_INT_SESSION_ID (EA and EB)) |
| ** |
| ** Returns: None . |
| ** |
| **********************************************************************************/ |
| void checkforNfceeConfig(uint8_t type) { |
| uint8_t uicc_flag = 0, ese_flag = 0; |
| uint8_t uicc2_flag = 0; /*For Dynamic Dual UICC*/ |
| unsigned long timeout_buff_val = 0, check_cnt = 0, retry_cnt = 0; |
| |
| tNFA_STATUS status; |
| tNFA_PMID param_ids_UICC[] = {0xA0, 0xEA}; |
| tNFA_PMID param_ids_eSE[] = {0xA0, 0xEB}; |
| tNFA_PMID param_uicc1[] = {0xA0, 0x24}; |
| tNFA_PMID param_ids_UICC2[] = {0xA0, 0x1E}; |
| tNFA_PMID param_uicc2[] = {0xA0, 0xE9}; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enter, type=%x", __func__, type); |
| uint8_t pipeId = 0; |
| SecureElement::getInstance().updateEEStatus(); |
| bool configureuicc1 = false; |
| bool configureuicc2 = false; |
| |
| status = GetNxpNumValue(NAME_NXP_DEFAULT_NFCEE_TIMEOUT, |
| (void*)&timeout_buff_val, sizeof(timeout_buff_val)); |
| |
| if (status == true) { |
| check_cnt = timeout_buff_val * RETRY_COUNT; |
| } else { |
| check_cnt = DEFAULT_COUNT * RETRY_COUNT; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NAME_DEFAULT_NFCEE_TIMEOUT = %lu", check_cnt); |
| |
| if (SecureElement::getInstance().getEeStatus( |
| SecureElement::EE_HANDLE_0xF3) == NFC_NFCEE_STATUS_ACTIVE) { |
| ese_flag = 0x01; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("eSE_flag SET"); |
| } |
| if (SecureElement::getInstance().getEeStatus( |
| SecureElement::getInstance().EE_HANDLE_0xF4) == |
| NFC_NFCEE_STATUS_ACTIVE) { |
| uicc_flag = 0x01; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("uicc_flag SET"); |
| } |
| if (nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC) { |
| if (SecureElement::getInstance().getEeStatus( |
| SecureElement::EE_HANDLE_0xF8) == NFC_NFCEE_STATUS_ACTIVE) { |
| uicc2_flag = 0x01; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("uicc2_flag SET"); |
| } |
| } else if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| if (dualUiccInfo.dualUiccEnable == 0x01) { |
| if (sSelectedUicc == 0x01) { |
| memset(dualUiccInfo.sUicc1SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc1SessionId)); |
| dualUiccInfo.sUicc1SessionIdLen = 0; |
| } else { |
| memset(dualUiccInfo.sUicc2SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc2SessionId)); |
| dualUiccInfo.sUicc2SessionIdLen = 0; |
| } |
| } |
| } |
| if ((ese_flag == 0x01) || (uicc_flag == 0x01) || (uicc2_flag == 0x01)) { |
| if (nfcFL.nfcNxpEse && (ese_flag && ((type & ESE) == ESE))) { |
| sCheckNfceeFlag = 1; |
| { |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| while (check_cnt > retry_cnt) { |
| status = NFA_GetConfig(0x01, param_ids_eSE); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| if (sNfceeConfigured == 1) { |
| SecureElement::getInstance().meSESessionIdOk = false; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("eSE Not Configured"); |
| } else { |
| SecureElement::getInstance().meSESessionIdOk = true; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("eSE Configured"); |
| break; |
| } |
| |
| usleep(100000); |
| retry_cnt++; |
| } |
| } |
| if (check_cnt <= retry_cnt) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("eSE Not Configured"); |
| retry_cnt = 0; |
| } |
| |
| if (nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC && |
| (uicc2_flag && ((type & UICC2) == UICC2))) { |
| sCheckNfceeFlag = 1; |
| { |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| while (check_cnt > retry_cnt) { |
| status = NFA_GetConfig(0x01, param_ids_UICC2); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| |
| if (sNfceeConfigured == 1) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("UICC2 Not Configured"); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "UICC2 Configured connectivity pipeId = %x", pipeId); |
| configureuicc2 = true; |
| if (nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE != true) { |
| break; |
| } |
| } |
| if (nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE) { |
| if ((configureuicc2 == true) || (check_cnt == retry_cnt)) { |
| configureuicc2 = false; |
| pipeId = SecureElement::getInstance().getUiccGateAndPipeList( |
| SecureElement::getInstance().EE_HANDLE_0xF8 & |
| ~NFA_HANDLE_GROUP_EE); |
| if (pipeId == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Add pipe information"); |
| sCheckNfceeFlag = 0; |
| status = NFA_GetConfig(0x01, param_uicc2); |
| pipeId = 0x23; |
| |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| sCheckNfceeFlag = 1; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "UICC2 connectivity gate present = %s", |
| (sConfig[NFC_PIPE_STATUS_OFFSET] ? "true" : "false")); |
| /*If pipe is present and opened update MW status*/ |
| if (sConfig[NFC_PIPE_STATUS_OFFSET] > PIPE_DELETED) { |
| SyncEventGuard guard( |
| SecureElement::getInstance().mHciAddStaticPipe); |
| status = NFA_HciAddStaticPipe( |
| SecureElement::getInstance().getHciHandleInfo(), 0x81, |
| NFA_HCI_CONNECTIVITY_GATE, pipeId); |
| if (status == NFA_STATUS_OK) { |
| SecureElement::getInstance().mHciAddStaticPipe.wait(500); |
| } |
| } |
| } |
| break; |
| } |
| } |
| usleep(100000); |
| retry_cnt++; |
| } |
| } |
| |
| if (check_cnt <= retry_cnt) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("UICC2 Not Configured"); |
| retry_cnt = 0; |
| pipeId = 0; |
| } |
| if (uicc_flag && ((type & UICC1) == UICC1)) { |
| sCheckNfceeFlag = 1; |
| { |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| while (check_cnt > retry_cnt) { |
| status = NFA_GetConfig(0x01, param_ids_UICC); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| |
| if (sNfceeConfigured == 1) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("UICC Not Configured"); |
| } else { |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) |
| dualUiccInfo.uiccConfigStat = UICC_CONFIGURED; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "UICC1 Configured connectivity pipeId = %x", pipeId); |
| configureuicc1 = true; |
| if (nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE == false) { |
| break; |
| } |
| } |
| if (nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE) { |
| if ((configureuicc1 == true) || (check_cnt == retry_cnt)) { |
| configureuicc1 = false; |
| pipeId = SecureElement::getInstance().getUiccGateAndPipeList( |
| SecureElement::getInstance().EE_HANDLE_0xF4 & |
| ~NFA_HANDLE_GROUP_EE); |
| if (pipeId == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Add pipe information"); |
| sCheckNfceeFlag = 0; |
| status = NFA_GetConfig(0x01, param_uicc1); |
| pipeId = 0x0A; |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| sCheckNfceeFlag = 1; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "UICC1 connectivity gate present = %s", |
| (sConfig[NFC_PIPE_STATUS_OFFSET] ? "true" : "false")); |
| /*If pipe is present and opened update MW status*/ |
| if (sConfig[NFC_PIPE_STATUS_OFFSET] > PIPE_DELETED) { |
| SyncEventGuard guard( |
| SecureElement::getInstance().mHciAddStaticPipe); |
| status = NFA_HciAddStaticPipe( |
| SecureElement::getInstance().getHciHandleInfo(), 0x02, |
| NFA_HCI_CONNECTIVITY_GATE, pipeId); |
| if (status == NFA_STATUS_OK) { |
| SecureElement::getInstance().mHciAddStaticPipe.wait(); |
| } |
| } |
| } |
| break; |
| } |
| } |
| usleep(100000); |
| retry_cnt++; |
| } |
| } |
| |
| if (check_cnt <= retry_cnt) |
| LOG(ERROR) << StringPrintf("UICC Not Configured"); |
| retry_cnt = 0; |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| sCheckNfceeFlag = 0; |
| } |
| } |
| } |
| |
| sCheckNfceeFlag = 0; |
| |
| if (nfcFL.eseFL._JCOP_WA_ENABLE) { |
| RoutingManager::getInstance().handleSERemovedNtf(); |
| } |
| } |
| #endif |
| |
| #if (NXP_EXTNS == TRUE) |
| static void nfaNxpSelfTestNtfTimerCb(union sigval) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "NXP SWP SelfTest : Can't get a notification about SWP Status!!"); |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.notifyOne(); |
| SetCbStatus(NFA_STATUS_FAILED); |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: performNfceeETSI12Config |
| ** |
| ** Description: checking for Nfcee ETSI 12 Compliancy and configure if |
| *compliant |
| ** |
| ** Returns: None . |
| ** |
| **********************************************************************************/ |
| void performNfceeETSI12Config() { |
| bool status; |
| tNFA_STATUS configstatus = NFA_STATUS_FAILED; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| |
| SecureElement::getInstance().setNfccPwrConfig( |
| SecureElement::getInstance().POWER_ALWAYS_ON | |
| SecureElement::getInstance().COMM_LINK_ACTIVE); |
| |
| status = SecureElement::getInstance().configureNfceeETSI12(); |
| if (status == true) { |
| { |
| SyncEventGuard guard(SecureElement::getInstance().mNfceeInitCbEvent); |
| if (SecureElement::getInstance().mNfceeInitCbEvent.wait(4000) == |
| false) { |
| LOG(ERROR) << StringPrintf( |
| "%s: timeout waiting for Nfcee Init event", __func__); |
| } |
| } |
| if (SecureElement::getInstance().mETSI12InitStatus != NFA_STATUS_OK) { |
| // check for recovery |
| configstatus = ResetEseSession(); |
| if (configstatus == NFA_STATUS_OK) { |
| SecureElement::getInstance().meseETSI12Recovery = true; |
| SecureElement::getInstance().SecEle_Modeset(0x00); |
| usleep(50 * 1000); |
| SecureElement::getInstance().SecEle_Modeset(0x01); |
| SecureElement::getInstance().meseETSI12Recovery = false; |
| } |
| checkforNfceeConfig(ESE); |
| } |
| } |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: performHCIInitialization |
| ** |
| ** Description: Performs HCI and SWP interface Initialization |
| ** |
| ** Returns: None . |
| ** |
| **********************************************************************************/ |
| static void performHCIInitialization(JNIEnv * e, jobject o) { |
| NFCSTATUS status = NFA_STATUS_FAILED; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| GetNumNFCEEConfigured(); |
| status = android::enableSWPInterface(); |
| if (status == NFA_STATUS_OK) { |
| RoutingManager::getInstance().nfaEEDisconnect(); |
| usleep(1000 * 1000); |
| android::NxpNfc_Send_CoreResetInit_Cmd(); |
| /*Update Actual SE count gActualSeCount*/ |
| GetNumNFCEEConfigured(); |
| RoutingManager::getInstance().nfaEEConnect(); |
| SecureElement::getInstance().activateAllNfcee(); |
| sIsSecElemSelected = (SecureElement::getInstance().getActualNumEe() - 1); |
| sIsSecElemDetected = sIsSecElemSelected; |
| } else { |
| LOG(ERROR) << StringPrintf( |
| "No UICC update required/failed to enable SWP interfaces"); |
| } |
| } |
| |
| void checkforESERemoval() { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("checkforESERemoval enter"); |
| |
| bool nfaEseRemovedNtf = true; |
| uint8_t numNfceePresent = |
| SecureElement::getInstance().mNfceeData_t.mNfceePresent; |
| tNFA_HANDLE nfceeHandle[MAX_NFCEE]; |
| tNFA_EE_STATUS nfceeStatus[MAX_NFCEE]; |
| |
| uint8_t retry = 0; |
| uint8_t mActualNumEe = SecureElement::MAX_NUM_EE; |
| tNFA_EE_INFO mEeInfo[mActualNumEe]; |
| uint8_t eseDetected = 0; |
| |
| for (int i = 1; i <= numNfceePresent; i++) { |
| nfceeHandle[i] = |
| SecureElement::getInstance().mNfceeData_t.mNfceeHandle[i]; |
| nfceeStatus[i] = |
| SecureElement::getInstance().mNfceeData_t.mNfceeHandle[i]; |
| |
| if (nfceeHandle[i] == (SecureElement::EE_HANDLE_0xF3) && |
| nfceeStatus[i] == 0x0) { |
| nfaEseRemovedNtf = false; |
| break; |
| } |
| } |
| if (nfaEseRemovedNtf) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("nfaEseRemovedNtf true"); |
| tNFA_STATUS configstatus = NFA_STATUS_FAILED; |
| do { |
| if ((configstatus = NFA_AllEeGetInfo(&mActualNumEe, mEeInfo)) != |
| NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("unable to get the EE status"); |
| } else { |
| for (int xx = 0; xx < mActualNumEe; xx++) { |
| LOG(ERROR) << StringPrintf("xx=%d, ee_handle=0x0%x, status=0x0%x", |
| xx, mEeInfo[xx].ee_handle, |
| mEeInfo[xx].ee_status); |
| if (mEeInfo[xx].ee_handle == 0x4C0) { |
| if (mEeInfo[xx].ee_status == 0x02) { |
| configstatus = ResetEseSession(); |
| RoutingManager::getInstance().nfaEEDisconnect(); |
| usleep(1000 * 1000); |
| android::NxpNfc_Send_CoreResetInit_Cmd(); |
| RoutingManager::getInstance().nfaEEConnect(); |
| usleep(1000 * 1000); |
| } else { |
| eseDetected = 0x01; |
| } |
| break; |
| } |
| } |
| } |
| } while ((eseDetected == 0x00) && (retry++ < 1)); |
| } |
| usleep(1000 * 1000); |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: getUiccContext |
| ** |
| ** Description: Read and store UICC context values |
| ** Respective context will be applied during next switching |
| ** |
| ** Returns: None |
| ** |
| **********************************************************************************/ |
| static void getUiccContext(int uiccSlot) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return; |
| } |
| uint8_t i; |
| tNFA_STATUS status; |
| tNFA_PMID param_ids_UICC_getContext[] = {0xA0, 0xF4}; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Enter", __func__); |
| |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| status = NFA_GetConfig(0x01, param_ids_UICC_getContext); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: UICC context Info : Len = %x", __func__, sCurrentConfigLen); |
| /*If the session ID is changed or uicc changed*/ |
| |
| if ((dualUiccInfo.sUicc1CntxLen != 0) && (sSelectedUicc == 0x01)) { |
| for (i = 0; i < dualUiccInfo.sUicc1CntxLen; i++) { |
| if (sConfig[i] != dualUiccInfo.sUicc1Cntx[i]) break; |
| } |
| if (i != dualUiccInfo.sUicc1CntxLen) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: copying UICC1 info", __func__); |
| update_uicc_context_info(); |
| } |
| } |
| /*If the session ID is changed or uicc changed*/ |
| if ((dualUiccInfo.sUicc2CntxLen != 0) && (sSelectedUicc == 0x02)) { |
| for (i = 0; i < dualUiccInfo.sUicc2CntxLen; i++) { |
| if (sConfig[i] != dualUiccInfo.sUicc2Cntx[i]) break; |
| } |
| if (i != dualUiccInfo.sUicc1CntxLen) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: copying UICC2 info", __func__); |
| update_uicc_context_info(); |
| } |
| } |
| |
| /*For the first power cycle for uicc1*/ |
| if ((dualUiccInfo.sUicc1CntxLen == 0) && (sSelectedUicc == 0x01)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: power cycle storing UICC1 info", __func__); |
| dualUiccInfo.sUicc1CntxLen = sCurrentConfigLen; |
| for (i = 5; i < 13; i++) { |
| if (sConfig[i] != (uint8_t)0xFF) break; |
| } |
| if (i == 13) { |
| dualUiccInfo.sUicc1CntxLen = 0; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: copying UICC1 info", __func__); |
| update_uicc_context_info(); |
| } |
| } |
| /*For the first power cycle for uicc2*/ |
| else if ((dualUiccInfo.sUicc2CntxLen == 0) && (sSelectedUicc == 0x02)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: power cycle storing UICC2 info", __func__); |
| dualUiccInfo.sUicc2CntxLen = sCurrentConfigLen; |
| for (i = 5; i < 13; i++) { |
| if (sConfig[i] != (uint8_t)0xFF) break; |
| } |
| if (i == 13) { |
| dualUiccInfo.sUicc2CntxLen = 0; |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: copying UICC2 info", __func__); |
| update_uicc_context_info(); |
| } |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: UICC info are already stored..", __func__); |
| } |
| |
| if ((uiccSlot == 0x01) && (dualUiccInfo.sUicc1CntxLen == 0x00)) { |
| read_uicc_context(dualUiccInfo.sUicc1Cntx, dualUiccInfo.sUicc1CntxLen, |
| dualUiccInfo.sUicc1TechCapblty, |
| sizeof(dualUiccInfo.sUicc1TechCapblty), 1, uiccSlot); |
| } else if ((uiccSlot == 0x02) && (dualUiccInfo.sUicc2CntxLen == 0x00)) { |
| read_uicc_context(dualUiccInfo.sUicc2Cntx, dualUiccInfo.sUicc2CntxLen, |
| dualUiccInfo.sUicc2TechCapblty, |
| sizeof(dualUiccInfo.sUicc2TechCapblty), 1, uiccSlot); |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Exit", __func__); |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: update_uicc_context_info |
| ** |
| ** Description: updates UICC context related info to buffere and file |
| ** |
| ** Returns: none |
| ** |
| **********************************************************************************/ |
| static void update_uicc_context_info() { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| tNFA_PMID param_ids_UICC_getOtherContext[] = {0xA0, 0xF5}; |
| if (sSelectedUicc == 0x01) { |
| memcpy(dualUiccInfo.sUicc1Cntx, sConfig, sCurrentConfigLen); |
| status = NFA_GetConfig(0x01, param_ids_UICC_getOtherContext); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| memcpy(dualUiccInfo.sUicc1TechCapblty, sConfig, sCurrentConfigLen); |
| write_uicc_context(dualUiccInfo.sUicc1Cntx, dualUiccInfo.sUicc1CntxLen, |
| dualUiccInfo.sUicc1TechCapblty, 10, 1, sSelectedUicc); |
| } else if (sSelectedUicc == 0x02) { |
| memcpy(dualUiccInfo.sUicc2Cntx, sConfig, sCurrentConfigLen); |
| status = NFA_GetConfig(0x01, param_ids_UICC_getOtherContext); |
| if (status == NFA_STATUS_OK) { |
| android::sNfaGetConfigEvent.wait(); |
| } |
| memcpy(dualUiccInfo.sUicc2TechCapblty, sConfig, sCurrentConfigLen); |
| write_uicc_context(dualUiccInfo.sUicc2Cntx, dualUiccInfo.sUicc2CntxLen, |
| dualUiccInfo.sUicc2TechCapblty, 10, 1, sSelectedUicc); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Exit", __func__); |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: write_uicc_context |
| ** |
| ** Description: write UICC context to file |
| ** |
| ** Returns: none |
| ** |
| **********************************************************************************/ |
| void write_uicc_context(uint8_t * uiccContext, uint16_t uiccContextLen, |
| uint8_t * uiccTechCap, uint16_t uiccTechCapLen, |
| uint8_t block, uint8_t slotnum) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return; |
| } |
| char filename[256], filename2[256]; |
| uint8_t cntx_len = 128; |
| uint8_t techCap = 10; |
| uint8_t* frameByte; |
| uint16_t crcVal = 0; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : enter", __func__); |
| |
| memset(filename, 0, sizeof(filename)); |
| memset(filename2, 0, sizeof(filename2)); |
| strcpy(filename2, "/data/vendor/nfc"); |
| strncat(filename2, "/nxpStorage.bin", |
| sizeof(filename2) - strlen(filename2) - 1); |
| |
| if (strlen(filename2) > 200) { |
| LOG(ERROR) << StringPrintf("%s: filename too long", __func__); |
| return; |
| } |
| sprintf(filename, "%s%u", filename2, block); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: bytes=%u; file=%s slotnum=%d", __func__, |
| uiccContextLen, filename, slotnum); |
| |
| int fileStream = 0; |
| |
| fileStream = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); |
| if (fileStream >= 0) { |
| size_t actualWrittenCntx = 0; |
| size_t actualWrittenCrc = 0; |
| size_t actualWrittenTechCap = 0; |
| size_t actualWrittenCntxLen = 0; |
| |
| if (slotnum == 1) { |
| lseek(fileStream, 0, SEEK_SET); |
| } else if (slotnum == 2) { |
| lseek(fileStream, |
| sizeof(dualUiccInfo.sUicc1Cntx) + |
| sizeof(dualUiccInfo.sUicc1TechCapblty), |
| SEEK_SET); |
| } |
| |
| actualWrittenCntxLen = write(fileStream, &uiccContextLen, 1); |
| if (uiccContextLen > 0x00) { |
| cntx_len = uiccContextLen; |
| techCap = uiccTechCapLen; |
| crcVal = calc_crc16(uiccContext, cntx_len); |
| } |
| |
| frameByte = (uint8_t*)&crcVal; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:CRC calculated %02x %02x", __func__, frameByte[0], frameByte[1]); |
| |
| actualWrittenCntx = write(fileStream, uiccContext, cntx_len); |
| actualWrittenCrc = write(fileStream, frameByte, sizeof(crcVal)); |
| actualWrittenTechCap = write(fileStream, uiccTechCap, techCap); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: %u bytes written", __func__, cntx_len); |
| if ((actualWrittenCntx == cntx_len) && |
| (actualWrittenTechCap == techCap)) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Write Success!"); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail to write", __func__); |
| } |
| close(fileStream); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail to open, error = %d", __func__, |
| errno); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : exit", __func__); |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: read_uicc_context |
| ** |
| ** Description: read UICC context from file |
| ** |
| ** Returns: none |
| ** |
| **********************************************************************************/ |
| void read_uicc_context(uint8_t * uiccContext, uint16_t uiccContextLen, |
| uint8_t * uiccTechCap, uint16_t uiccTechCapLen, |
| uint8_t block, uint8_t slotnum) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return; |
| } |
| char filename[256], filename2[256]; |
| uint8_t* readCrc = NULL; |
| uint8_t* frameByte = NULL; |
| uint16_t crcVal; |
| uint8_t cmpStat; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : enter", __func__); |
| |
| memset(filename, 0, sizeof(filename)); |
| memset(filename2, 0, sizeof(filename2)); |
| strcpy(filename2, "/data/vendor/nfc"); |
| strncat(filename2, "/nxpStorage.bin", |
| sizeof(filename2) - strlen(filename2) - 1); |
| if (strlen(filename2) > 200) { |
| LOG(ERROR) << StringPrintf("%s: filename too long", __func__); |
| return; |
| } |
| sprintf(filename, "%s%u", filename2, block); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: buffer len=%u; file=%s, slotnum=%d", __func__, |
| uiccContextLen, filename, slotnum); |
| int fileStream = open(filename, O_RDONLY); |
| if (fileStream >= 0) { |
| size_t actualReadCntx = 0; |
| size_t actualReadCntxLen = 0; |
| size_t actualReadCrc = 0; |
| size_t actualReadTechCap = 0; |
| uint8_t readCntxLen = 0; |
| |
| if (slotnum == 1) { |
| lseek(fileStream, 0, SEEK_SET); |
| } else if (slotnum == 2) { |
| lseek(fileStream, |
| sizeof(dualUiccInfo.sUicc1Cntx) + |
| sizeof(dualUiccInfo.sUicc1TechCapblty), |
| SEEK_SET); |
| } |
| actualReadCntxLen = read(fileStream, &readCntxLen, 1); |
| if (readCntxLen > 0x00) { |
| actualReadCntx = read(fileStream, uiccContext, readCntxLen); |
| readCrc = (uint8_t*)malloc(2 * sizeof(uint8_t)); |
| actualReadCrc = read(fileStream, readCrc, sizeof(crcVal)); |
| crcVal = calc_crc16(uiccContext, readCntxLen); |
| frameByte = (uint8_t*)&crcVal; |
| actualReadTechCap = read(fileStream, uiccTechCap, uiccTechCapLen); |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:CRC calculated %02x %02x -- CRC read %02x %02x", __func__, |
| frameByte[0], frameByte[1], readCrc[0], readCrc[1]); |
| cmpStat = memcmp(readCrc, frameByte, sizeof(crcVal)); |
| if (cmpStat == 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s:CRC check result - success", __func__); |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:CRC check result - failed. Resetting buffer", __func__); |
| memset(uiccContext, 0x00, 128); |
| memset(uiccTechCap, 0x00, 10); |
| write_uicc_context(uiccContext, 0, uiccTechCap, 10, 1, slotnum); |
| } |
| free(readCrc); |
| } else { |
| memset(uiccContext, 0x00, 128); |
| memset(uiccTechCap, 0x00, 10); |
| } |
| |
| if (slotnum == 1) |
| dualUiccInfo.sUicc1CntxLen = readCntxLen; |
| else if (slotnum == 2) |
| dualUiccInfo.sUicc2CntxLen = readCntxLen; |
| |
| close(fileStream); |
| if (actualReadCntx > 0) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: data size=%zu", __func__, actualReadCntx); |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail to read", __func__); |
| } |
| } else { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: fail to open", __func__); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : exit", __func__); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function calc_crc16 |
| ** |
| ** Description Calculates CRC16 for the frame buffer |
| ** |
| ** Parameters pBuff - CRC16 calculation input buffer |
| ** wLen - input buffer length |
| ** |
| ** Returns wCrc - computed 2 byte CRC16 value |
| ** |
| *******************************************************************************/ |
| uint16_t calc_crc16(uint8_t * pBuff, uint16_t wLen) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return 0xFF; |
| } |
| uint16_t wTmp; |
| uint16_t wValue; |
| uint16_t wCrc = 0xffff; |
| uint32_t i; |
| uint16_t aCrcTab[256] = { |
| 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, |
| 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, |
| 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, |
| 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, |
| 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, |
| 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, |
| 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, |
| 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, |
| 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, |
| 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, |
| 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, |
| 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, |
| 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, |
| 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, |
| 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, |
| 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, |
| 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, |
| 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, |
| 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, |
| 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, |
| 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, |
| 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, |
| 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, |
| 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, |
| 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, |
| 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, |
| 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, |
| 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, |
| 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; |
| |
| if ((NULL == pBuff) || (0 == wLen)) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: Invalid Params supplied", __func__); |
| } else { |
| /* Perform CRC calculation according to ccitt with a initial value of |
| * 0x1d0f */ |
| for (i = 0; i < wLen; i++) { |
| wValue = 0x00ffU & (uint16_t)pBuff[i]; |
| wTmp = (wCrc >> 8U) ^ wValue; |
| wCrc = (wCrc << 8U) ^ aCrcTab[wTmp]; |
| } |
| } |
| |
| return wCrc; |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: getUiccSession |
| ** |
| ** Description: Read and store UICC session values |
| ** |
| ** Returns: UICC Configured status |
| ** 1 : failed |
| ** 0 : success |
| ** |
| **********************************************************************************/ |
| static int getUiccSession() { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return 0; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Enter", __func__); |
| |
| int cmpStat = 0, sUiccConfigured = 1; |
| /*techInfo will be set if any DISCOVERY_REQ_NTF is received for current UICC |
| *It will be used to validate received session id belongs to current |
| *selected UICC or not |
| * */ |
| bool techInfo = SecureElement::getInstance().isTeckInfoReceived( |
| SecureElement::getInstance().EE_HANDLE_0xF4); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: techInfo 0x%02x", __func__, techInfo); |
| |
| /* sConfig will have session ID received |
| * If received different from previous UICC save it in corresponding UICC |
| * buffer |
| * If same, reset the UICC buffer |
| * */ |
| if (sSelectedUicc == 0x01) { |
| if (dualUiccInfo.sUicc2SessionIdLen != 0) { |
| cmpStat = memcmp(sConfig + 4, dualUiccInfo.sUicc2SessionId, |
| dualUiccInfo.sUicc2SessionIdLen); |
| if ((cmpStat == 0) || (!techInfo)) { |
| memset(dualUiccInfo.sUicc1SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc1SessionId)); |
| dualUiccInfo.sUicc1SessionIdLen = 0; |
| sUiccConfigured = 1; |
| } else { |
| memcpy(dualUiccInfo.sUicc1SessionId, sConfig + 4, 8); |
| dualUiccInfo.sUicc1SessionIdLen = 8; |
| sUiccConfigured = 0; |
| } |
| } else if (techInfo) { |
| memcpy(dualUiccInfo.sUicc1SessionId, sConfig + 4, 8); |
| dualUiccInfo.sUicc1SessionIdLen = 8; |
| sUiccConfigured = 0; |
| } |
| } else if (sSelectedUicc == 0x02) { |
| if (dualUiccInfo.sUicc1SessionIdLen != 0) { |
| cmpStat = memcmp(sConfig + 4, dualUiccInfo.sUicc1SessionId, |
| dualUiccInfo.sUicc1SessionIdLen); |
| if ((cmpStat == 0) || (!techInfo)) { |
| memset(dualUiccInfo.sUicc2SessionId, 0x00, |
| sizeof(dualUiccInfo.sUicc2SessionId)); |
| dualUiccInfo.sUicc2SessionIdLen = 0; |
| sUiccConfigured = 1; |
| } else { |
| memcpy(dualUiccInfo.sUicc2SessionId, sConfig + 4, 8); |
| dualUiccInfo.sUicc2SessionIdLen = 8; |
| sUiccConfigured = 0; |
| } |
| } else if (techInfo) { |
| memcpy(dualUiccInfo.sUicc2SessionId, sConfig + 4, 8); |
| dualUiccInfo.sUicc2SessionIdLen = 8; |
| sUiccConfigured = 0; |
| } |
| } |
| return sUiccConfigured; |
| } |
| /********************************************************************************** |
| ** |
| ** Function: notifyUiccEvent |
| ** |
| ** Description: Notifies UICC event sto Service |
| ** Possible values: |
| ** UICC_CONNECTED_0 - 0 UICC connected |
| ** UICC_CONNECTED_1 - 1 UICC connected |
| ** UICC_CONNECTED_2 - 2 UICCs connected |
| ** |
| ** Returns: None |
| ** |
| **********************************************************************************/ |
| static void notifyUiccEvent(union sigval) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: STAT_DUAL_UICC_EXT_SWITCH not available. Returning", __func__); |
| return; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| struct nfc_jni_native_data* nat = getNative(NULL, NULL); |
| JNIEnv* e; |
| ScopedAttach attach(nat->vm, &e); |
| if (e == NULL) { |
| LOG(ERROR) << StringPrintf("jni env is null"); |
| return; |
| } |
| if (dualUiccInfo.uiccActivStat == 0x00) /*No UICC Detected*/ |
| { |
| e->CallVoidMethod(nat->manager, |
| android::gCachedNfcManagerNotifyUiccStatusEvent, |
| UICC_CONNECTED_0); |
| } else if ((dualUiccInfo.uiccActivStat == 0x01) || |
| (dualUiccInfo.uiccActivStat == 0x02)) /*One UICC Detected*/ |
| { |
| e->CallVoidMethod(nat->manager, |
| android::gCachedNfcManagerNotifyUiccStatusEvent, |
| UICC_CONNECTED_1); |
| } else if (dualUiccInfo.uiccActivStat == 0x03) /*Two UICC Detected*/ |
| { |
| e->CallVoidMethod(nat->manager, |
| android::gCachedNfcManagerNotifyUiccStatusEvent, |
| UICC_CONNECTED_2); |
| } |
| } |
| |
| static int nfcManager_staticDualUicc_Precondition(int uiccSlot) { |
| if (!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH && |
| !nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s:Dual UICC feature not available . Returning", __func__); |
| return DUAL_UICC_FEATURE_NOT_AVAILABLE; |
| } |
| unsigned long uicc_active_state = 0; |
| |
| uint8_t retStat = UICC_NOT_CONFIGURED; |
| if (nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) { |
| if (GetNxpNumValue(NAME_NXP_DUAL_UICC_ENABLE, (void*)&uicc_active_state, |
| sizeof(uicc_active_state))) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "NXP_DUAL_UICC_ENABLE : 0x%02lx", uicc_active_state); |
| } else { |
| LOG(ERROR) << StringPrintf( |
| "NXP_DUAL_UICC_ENABLE Not found taking default value 0x00"); |
| uicc_active_state = 0x00; |
| } |
| |
| if (uicc_active_state != 0x01) { |
| LOG(ERROR) << StringPrintf("%s:FAIL Dual UICC feature not available", |
| __func__); |
| retStat = DUAL_UICC_FEATURE_NOT_AVAILABLE; |
| } |
| } |
| |
| if (sIsDisabling) { |
| LOG(ERROR) << StringPrintf( |
| "%s:FAIL Nfc is Disabling : Switch UICC not allowed", __func__); |
| retStat = DUAL_UICC_ERROR_NFC_TURNING_OFF; |
| } else if (SecureElement::getInstance().isBusy()) { |
| LOG(ERROR) << StringPrintf("%s:FAIL SE wired-mode : busy", __func__); |
| retStat = DUAL_UICC_ERROR_NFCC_BUSY; |
| } else if (rfActivation) { |
| LOG(ERROR) << StringPrintf("%s:FAIL RF session ongoing", __func__); |
| retStat = DUAL_UICC_ERROR_NFCC_BUSY; |
| } else if ((uiccSlot != 0x01) && (uiccSlot != 0x02)) { |
| LOG(ERROR) << StringPrintf("%s: Invalid slot id", __func__); |
| retStat = DUAL_UICC_ERROR_INVALID_SLOT; |
| } else if (SecureElement::getInstance().isRfFieldOn()) { |
| LOG(ERROR) << StringPrintf("%s:FAIL RF field on", __func__); |
| retStat = DUAL_UICC_ERROR_NFCC_BUSY; |
| } else if (sDiscoveryEnabled || sRfEnabled) { |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(staticDualUicc))) { |
| LOG(ERROR) << StringPrintf("%s: Transaction in progress. Can not set", |
| __func__); |
| retStat = DUAL_UICC_ERROR_NFCC_BUSY; |
| } else { |
| LOG(ERROR) << StringPrintf("%s: Transaction state enabled", __func__); |
| } |
| } |
| return retStat; |
| } |
| |
| static void nfaNxpSelfTestNtfCallback(uint8_t event, uint16_t param_len, |
| uint8_t * p_param) { |
| (void)event; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); |
| |
| if (param_len == 0x05 && |
| p_param[3] == 00) // p_param[4] 0x00:SWP Link OK 0x03:SWP link dead. |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : SWP Link OK "); |
| SetCbStatus(NFA_STATUS_OK); |
| } else { |
| if (p_param[3] == 0x03) |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : SWP Link dead "); |
| SetCbStatus(NFA_STATUS_FAILED); |
| } |
| |
| switch (p_param[4]) { // information of PMUVCC. |
| case 0x00: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : No PMUVCC "); |
| break; |
| case 0x01: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : PMUVCC = 1.8V "); |
| break; |
| case 0x02: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : PMUVCC = 3.3V "); |
| break; |
| case 0x03: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : PMUVCC = undetermined "); |
| break; |
| default: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NXP SWP SelfTest : unknown PMUVCC "); |
| break; |
| } |
| |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.notifyOne(); |
| } |
| |
| static void nfcManager_doPrbsOn(JNIEnv * e, jobject o, jint prbs, |
| jint hw_prbs, jint tech, jint rate) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| // bool stat = false; /*commented to eliminate unused |
| // variable warning*/ |
| |
| if (!sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC does not enabled!!"); |
| return; |
| } |
| |
| if (sDiscoveryEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Discovery must not be enabled for SelfTest"); |
| return; |
| } |
| |
| if (tech < 0 || tech > 2) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Invalid tech! please choose A or B or F"); |
| return; |
| } |
| |
| if (rate < 0 || rate > 3) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "Invalid bitrate! please choose 106 or 212 or 424 or 848"); |
| return; |
| } |
| |
| // Technology to stream 0x00:TypeA 0x01:TypeB 0x02:TypeF |
| // Bitrate 0x00:106kbps 0x01:212kbps 0x02:424kbps |
| // 0x03:848kbps |
| // prbs and hw_prbs 0x00 or 0x01 two extra parameters included |
| // in case of pn548AD |
| uint8_t param[4]; |
| memset(param, 0x00, sizeof(param)); |
| if (nfcFL.chipType != pn547C2) { |
| param[0] = prbs; |
| param[1] = hw_prbs; |
| param[2] = tech; // technology |
| param[3] = rate; // bitrate |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "phNxpNciHal_getPrbsCmd: PRBS = %d HW_PRBS = %d", prbs, hw_prbs); |
| } else { |
| param[0] = tech; |
| param[1] = rate; |
| } |
| switch (tech) { |
| case 0x00: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_A"); |
| break; |
| case 0x01: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_B"); |
| break; |
| case 0x02: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_F"); |
| break; |
| default: |
| break; |
| } |
| switch (rate) { |
| case 0x00: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_106"); |
| break; |
| case 0x01: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_212"); |
| break; |
| case 0x02: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_424"); |
| break; |
| case 0x03: |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_848"); |
| break; |
| default: |
| break; |
| } |
| // step2. PRBS Test stop : CORE RESET_CMD |
| status = Nxp_SelfTest(3, param); // CORE_RESET_CMD |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: CORE RESET_CMD Fail!", __func__); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| // step3. PRBS Test stop : CORE_INIT_CMD |
| status = Nxp_SelfTest(4, param); // CORE_INIT_CMD |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: CORE_INIT_CMD Fail!", __func__); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| // step4. : NXP_ACT_PROP_EXTN |
| status = Nxp_SelfTest(5, param); // NXP_ACT_PROP_EXTN |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: NXP_ACT_PROP_EXTN Fail!", __func__); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| status = Nxp_SelfTest(1, param); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| |
| TheEnd: |
| // Factory Test Code |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| return; |
| } |
| |
| static void nfcManager_doPrbsOff(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| // bool stat = false; /*commented to eliminate unused |
| // variable warning*/ |
| uint8_t param; |
| |
| if (!sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC does not enabled!!"); |
| return; |
| } |
| |
| if (sDiscoveryEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Discovery must not be enabled for SelfTest"); |
| return; |
| } |
| |
| // Factory Test Code |
| // step1. PRBS Test stop : VEN RESET |
| status = Nxp_SelfTest(2, ¶m); // VEN RESET |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("step1. PRBS Test stop : VEN RESET Fail!"); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| TheEnd: |
| // Factory Test Code |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| |
| return; |
| } |
| |
| static jint nfcManager_SWPSelfTest(JNIEnv * e, jobject o, jint ch) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| tNFA_STATUS regcb_stat = NFA_STATUS_FAILED; |
| uint8_t param[1]; |
| |
| if (!sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC does not enabled!!"); |
| return status; |
| } |
| |
| if (sDiscoveryEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Discovery must not be enabled for SelfTest"); |
| return status; |
| } |
| |
| if (ch < 0 || ch > 1) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Invalid channel!! please choose 0 or 1"); |
| return status; |
| } |
| |
| // step1. : CORE RESET_CMD |
| status = Nxp_SelfTest(3, param); // CORE_RESET_CMD |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("step2. PRBS Test stop : CORE RESET_CMD Fail!"); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| // step2. : CORE_INIT_CMD |
| status = Nxp_SelfTest(4, param); // CORE_INIT_CMD |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("step3. PRBS Test stop : CORE_INIT_CMD Fail!"); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| // step3. : NXP_ACT_PROP_EXTN |
| status = Nxp_SelfTest(5, param); // NXP_ACT_PROP_EXTN |
| if (NFA_STATUS_OK != status) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("step: NXP_ACT_PROP_EXTN Fail!"); |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| regcb_stat = NFA_RegVSCback( |
| true, nfaNxpSelfTestNtfCallback); // Register CallBack for NXP NTF |
| if (NFA_STATUS_OK != regcb_stat) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("To Regist Ntf Callback is Fail!"); |
| goto TheEnd; |
| } |
| |
| param[0] = ch; // SWP channel 0x00 : SWP1(UICC) 0x01:SWP2(eSE) |
| status = Nxp_SelfTest(0, param); |
| if (NFA_STATUS_OK != status) { |
| status = NFA_STATUS_FAILED; |
| goto TheEnd; |
| } |
| |
| { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC NXP SelfTest wait for Notificaiton"); |
| nfaNxpSelfTestNtfTimer.set(1000, nfaNxpSelfTestNtfTimerCb); |
| SyncEventGuard guard(sNfaNxpNtfEvent); |
| sNfaNxpNtfEvent.wait(); // wait for NXP Self NTF to come |
| } |
| |
| status = GetCbStatus(); |
| if (NFA_STATUS_OK != status) { |
| status = NFA_STATUS_FAILED; |
| } |
| |
| TheEnd: |
| if (NFA_STATUS_OK == regcb_stat) { |
| regcb_stat = NFA_RegVSCback( |
| false, nfaNxpSelfTestNtfCallback); // DeRegister CallBack for NXP NTF |
| } |
| nfaNxpSelfTestNtfTimer.kill(); |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_doPartialDeInitialize |
| ** |
| ** Description: DeInitializes the NFC partially if it is partially |
| *initialized. |
| ** |
| ** Returns: true/false . |
| ** |
| *******************************************************************************/ |
| static bool nfcManager_doPartialDeInitialize() { |
| tNFA_STATUS stat = NFA_STATUS_OK; |
| if (!gsNfaPartialEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s: cannot deinitialize NFC , not partially initilaized", __func__); |
| return true; |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s:enter", __func__); |
| stat = NFA_Disable(true /* graceful */); |
| if (stat == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: wait for completion", __func__); |
| SyncEventGuard guard(sNfaDisableEvent); |
| sNfaDisableEvent.wait(); // wait for NFA command to finish |
| } else { |
| LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__, |
| stat); |
| } |
| NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); |
| theInstance.Finalize(); |
| NFA_SetBootMode(NFA_NORMAL_BOOT_MODE); |
| gsNfaPartialEnabled = false; |
| return true; |
| } |
| |
| /********************************************************************************** |
| ** |
| ** Function: nfcManager_getFwVersion |
| ** |
| ** Description: To get the FW Version |
| ** |
| ** Returns: int fw version as below four byte format |
| ** [0x00 0xROM_CODE_V 0xFW_MAJOR_NO 0xFW_MINOR_NO] |
| ** |
| **********************************************************************************/ |
| static jint nfcManager_getFwVersion(JNIEnv * e, jobject o) { |
| (void)e; |
| (void)o; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| // bool stat = false; /*commented to eliminate |
| // unused variable warning*/ |
| jint version = 0, temp = 0; |
| tNFC_FW_VERSION nfc_native_fw_version; |
| |
| if (!sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC does not enabled!!"); |
| return status; |
| } |
| memset(&nfc_native_fw_version, 0, sizeof(nfc_native_fw_version)); |
| |
| nfc_native_fw_version = nfc_ncif_getFWVersion(); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "FW Version: %x.%x.%x", nfc_native_fw_version.rom_code_version, |
| nfc_native_fw_version.major_version, |
| nfc_native_fw_version.minor_version); |
| |
| temp = nfc_native_fw_version.rom_code_version; |
| version = temp << 16; |
| temp = nfc_native_fw_version.major_version; |
| version |= temp << 8; |
| version |= nfc_native_fw_version.minor_version; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; version =0x%X", __func__, version); |
| return version; |
| } |
| |
| static void nfcManager_doSetEEPROM(JNIEnv * e, jobject o, jbyteArray val) { |
| (void)e; |
| (void)o; |
| (void)val; |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| // bool stat = false; /*commented to eliminate |
| // unused variable warning*/ |
| // uint8_t param; /*commented to eliminate |
| // unused variable warning*/ |
| |
| if (!sIsNfaEnabled) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("NFC does not enabled!!"); |
| return; |
| } |
| |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: exit; status =0x%X", __func__, status); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: getUICC_RF_Param_SetSWPBitRate() |
| ** |
| ** Description: Get All UICC Parameters and set SWP bit rate |
| ** |
| ** Returns: success/failure |
| ** |
| *******************************************************************************/ |
| tNFA_STATUS getUICC_RF_Param_SetSWPBitRate() { |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| tNFA_PMID rf_params_NFCEE_UICC[] = {0xA0, 0xEF}; |
| uint8_t sakValue = 0x00; |
| bool isMifareSupported; |
| |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); |
| |
| SyncEventGuard guard(android::sNfaGetConfigEvent); |
| status = NFA_GetConfig(0x01, rf_params_NFCEE_UICC); |
| if (status != NFA_STATUS_OK) { |
| LOG(ERROR) << StringPrintf("%s: NFA_GetConfig failed", __func__); |
| return status; |
| } |
| android::sNfaGetConfigEvent.wait(); |
| sakValue = sConfig[SAK_VALUE_AT]; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("SAK Value =0x%X", sakValue); |
| if ((sakValue & 0x08) == 0x00) { |
| isMifareSupported = false; |
| } else { |
| isMifareSupported = true; |
| } |
| status = SetUICC_SWPBitRate(isMifareSupported); |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManagerEnableAGCDebug |
| ** |
| ** Description: Enable/Disable Dynamic RSSI feature. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| static void nfcManagerEnableAGCDebug(uint8_t connEvent) { |
| if (nfcFL.chipType == pn547C2) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s ,chipType : pn547C2. Not allowed. Returning", __func__); |
| return; |
| } |
| unsigned long enableAGCDebug = 0; |
| int retvalue = 0xFF; |
| GetNxpNumValue(NAME_NXP_AGC_DEBUG_ENABLE, (void*)&enableAGCDebug, |
| sizeof(enableAGCDebug)); |
| menableAGC_debug_t.enableAGC = enableAGCDebug; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s ,%lu:", __func__, enableAGCDebug); |
| if (sIsNfaEnabled != true || sIsDisabling == true) return; |
| if (!menableAGC_debug_t.enableAGC) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s AGCDebug not enabled", __func__); |
| return; |
| } |
| if (connEvent == NFA_TRANS_DM_RF_FIELD_EVT && |
| menableAGC_debug_t.AGCdebugstarted == false) { |
| pthread_t agcThread; |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| retvalue = pthread_create(&agcThread, &attr, enableAGCThread, NULL); |
| pthread_attr_destroy(&attr); |
| if (retvalue == 0) { |
| menableAGC_debug_t.AGCdebugstarted = true; |
| set_AGC_process_state(true); |
| } |
| } |
| } |
| |
| void* enableAGCThread(void* arg) { |
| if (nfcFL.chipType == pn547C2) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s ,chipType : pn547C2. Not allowed. Returning", __func__); |
| return NULL; |
| } |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| while (menableAGC_debug_t.AGCdebugstarted == true) { |
| if (get_AGC_process_state() == false) { |
| sleep(10000); |
| continue; |
| } |
| |
| if (sIsNfaEnabled != true || sIsDisabling == true) { |
| menableAGC_debug_t.AGCdebugstarted = false; |
| set_AGC_process_state(false); |
| break; |
| } |
| |
| status = SendAGCDebugCommand(); |
| if (status == NFA_STATUS_OK) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("%s: enable success exit", __func__); |
| } |
| usleep(500000); |
| } |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); |
| pthread_exit(NULL); |
| return NULL; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: set_AGC_process_state |
| ** |
| ** Description: sets the AGC process to stop |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| void set_AGC_process_state(bool state) { |
| if (nfcFL.chipType == pn547C2) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s ,chipType : pn547C2. Not allowed. Returning", __func__); |
| return; |
| } |
| menableAGC_debug_t.AGCdebugrunning = state; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: get_AGC_process_state |
| ** |
| ** Description: returns the AGC process state. |
| ** |
| ** Returns: true/false . |
| ** |
| *******************************************************************************/ |
| bool get_AGC_process_state() { |
| if (nfcFL.chipType == pn547C2) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s ,chipType : pn547C2. Not allowed. Returning", __func__); |
| return false; |
| } |
| return menableAGC_debug_t.AGCdebugrunning; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: getrfDiscoveryDuration() |
| ** |
| ** Description: gets the current rf discovery duration. |
| ** |
| ** Returns: uint16_t |
| ** |
| *******************************************************************************/ |
| uint16_t getrfDiscoveryDuration() { return discDuration; } |
| |
| #if (NXP_NFCC_HCE_F == TRUE) |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getTransanctionRequest |
| ** |
| ** Description: returns the payment check for HCE-F |
| ** |
| ** Returns: true/false . |
| ** |
| *******************************************************************************/ |
| bool nfcManager_getTransanctionRequest(int t3thandle, bool registerRequest) { |
| bool stat = false; |
| |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(getTransanctionRequest))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("Transcation is in progress store the requst %d %d", |
| t3thandle, registerRequest); |
| set_last_request(T3T_CONFIGURE, NULL); |
| if (!registerRequest) transaction_data.t3thandle = t3thandle; |
| stat = true; |
| } else { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(getTransanctionRequest)); |
| } |
| return stat; |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_isTransanctionOnGoing(bool isInstallRequest) |
| ** |
| ** Description: Base on the input parameter.It update the parameter for |
| ** install/uninstall request. |
| ** |
| ** Returns: success/failure |
| ** |
| *******************************************************************************/ |
| bool nfcManager_isTransanctionOnGoing(bool isInstallRequest) { |
| if (!pTransactionController->transactionAttempt( |
| TRANSACTION_REQUESTOR(isTransanctionOnGoing))) { |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf(" Transcation is in progress store the requst"); |
| set_last_request(RE_ROUTING, NULL); |
| if (!isInstallRequest) |
| transaction_data.isInstallRequest = isInstallRequest; |
| return true; |
| } else { |
| pTransactionController->transactionEnd( |
| TRANSACTION_REQUESTOR(isTransanctionOnGoing)); |
| } |
| return false; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_sendEmptyDataMsg() |
| ** |
| ** Description: Sends Empty Data packet |
| ** |
| ** Returns: True/False |
| ** |
| *******************************************************************************/ |
| bool nfcManager_sendEmptyDataMsg() { |
| if (!nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET) { |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( |
| "%s : NXP_NFCC_EMPTY_DATA_PACKET not available." |
| "Returning", |
| __func__); |
| return false; |
| } |
| tNFA_STATUS status = NFA_STATUS_FAILED; |
| size_t bufLen = 0; |
| uint8_t* buf = NULL; |
| DLOG_IF(INFO, nfc_debug_enabled) |
| << StringPrintf("nfcManager_sendEmptyRawFrame"); |
| |
| status = NFA_SendRawFrame(buf, bufLen, 0); |
| |
| return (status == NFA_STATUS_OK); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_transactionDetail() |
| ** |
| ** Description: Provides transaction detail data reference |
| ** |
| ** Returns: Pointer to transaction data |
| ** |
| *******************************************************************************/ |
| Transcation_Check_t* nfcManager_transactionDetail(void) { |
| return &android::transaction_data; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: nfcManager_getFeatureList() |
| ** |
| ** Description: Get the Chipe type & Configure Chip type macros |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void nfcManager_getFeatureList() { |
| tNFC_chipType chipType; // = pn553; |
| chipType = NFC_GetChipType(); |
| DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s : chipType", __func__); |
| CONFIGURE_FEATURELIST(chipType); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: register_signal_handler() |
| ** |
| ** Description: Register Signal handlers |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| void register_signal_handler() { |
| struct sigaction sig; |
| |
| memset(&sig, 0, sizeof(struct sigaction)); |
| sig.sa_sigaction = spi_prio_signal_handler; |
| sig.sa_flags = SA_SIGINFO; |
| if (sigaction(SIG_NFC, &sig, NULL) < 0) { |
| LOG(ERROR) << StringPrintf( |
| "Failed to register spi prio session signal handler"); |
| } |
| if ((signal(SIGABRT, sig_handler) == SIG_ERR) && |
| (signal(SIGSEGV, sig_handler) == SIG_ERR)) { |
| LOG(ERROR) << StringPrintf("Failed to register signal handler"); |
| } |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: isLowRamDevice() |
| ** |
| ** Description: Provides whether device is low ram enabled or not |
| ** |
| ** Returns: None . |
| ** |
| *******************************************************************************/ |
| bool isLowRamDevice() { return sIsLowRamDevice; } |
| |
| #endif |
| } |
| |
| /* namespace android */ |