Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <android-base/stringprintf.h>
     18 #include <base/logging.h>
     19 #include <cutils/properties.h>
     20 #include <errno.h>
     21 #include <nativehelper/ScopedLocalRef.h>
     22 #include <nativehelper/ScopedPrimitiveArray.h>
     23 #include <nativehelper/ScopedUtfChars.h>
     24 #include <semaphore.h>
     25 #include "HciEventManager.h"
     26 #include "JavaClassConstants.h"
     27 #include "NfcAdaptation.h"
     28 #include "NfcJniUtil.h"
     29 #include "NfcTag.h"
     30 #include "PeerToPeer.h"
     31 #include "Pn544Interop.h"
     32 #include "PowerSwitch.h"
     33 #include "RoutingManager.h"
     34 #include "SyncEvent.h"
     35 #include "nfc_config.h"
     36 
     37 #include "ce_api.h"
     38 #include "nfa_api.h"
     39 #include "nfa_ee_api.h"
     40 #include "nfa_p2p_api.h"
     41 #include "nfc_brcm_defs.h"
     42 #include "phNxpExtns.h"
     43 #include "rw_api.h"
     44 
     45 using android::base::StringPrintf;
     46 
     47 extern tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg;  // defined in stack
     48 namespace android {
     49 extern bool gIsTagDeactivating;
     50 extern bool gIsSelectingRfInterface;
     51 extern void nativeNfcTag_doTransceiveStatus(tNFA_STATUS status, uint8_t* buf,
     52                                             uint32_t buflen);
     53 extern void nativeNfcTag_notifyRfTimeout();
     54 extern void nativeNfcTag_doConnectStatus(jboolean is_connect_ok);
     55 extern void nativeNfcTag_doDeactivateStatus(int status);
     56 extern void nativeNfcTag_doWriteStatus(jboolean is_write_ok);
     57 extern jboolean nativeNfcTag_doDisconnect(JNIEnv*, jobject);
     58 extern void nativeNfcTag_doCheckNdefResult(tNFA_STATUS status,
     59                                            uint32_t max_size,
     60                                            uint32_t current_size,
     61                                            uint8_t flags);
     62 extern void nativeNfcTag_doMakeReadonlyResult(tNFA_STATUS status);
     63 extern void nativeNfcTag_doPresenceCheckResult(tNFA_STATUS status);
     64 extern void nativeNfcTag_formatStatus(bool is_ok);
     65 extern void nativeNfcTag_resetPresenceCheck();
     66 extern void nativeNfcTag_doReadCompleted(tNFA_STATUS status);
     67 extern void nativeNfcTag_setRfInterface(tNFA_INTF_TYPE rfInterface);
     68 extern void nativeNfcTag_abortWaits();
     69 extern void nativeLlcpConnectionlessSocket_abortWait();
     70 extern void nativeNfcTag_registerNdefTypeHandler();
     71 extern void nativeNfcTag_acquireRfInterfaceMutexLock();
     72 extern void nativeNfcTag_releaseRfInterfaceMutexLock();
     73 extern void nativeLlcpConnectionlessSocket_receiveData(uint8_t* data,
     74                                                        uint32_t len,
     75                                                        uint32_t remote_sap);
     76 }  // namespace android
     77 
     78 /*****************************************************************************
     79 **
     80 ** public variables and functions
     81 **
     82 *****************************************************************************/
     83 bool gActivated = false;
     84 SyncEvent gDeactivatedEvent;
     85 SyncEvent sNfaSetPowerSubState;
     86 
     87 namespace android {
     88 jmethodID gCachedNfcManagerNotifyNdefMessageListeners;
     89 jmethodID gCachedNfcManagerNotifyTransactionListeners;
     90 jmethodID gCachedNfcManagerNotifyLlcpLinkActivation;
     91 jmethodID gCachedNfcManagerNotifyLlcpLinkDeactivated;
     92 jmethodID gCachedNfcManagerNotifyLlcpFirstPacketReceived;
     93 jmethodID gCachedNfcManagerNotifyHostEmuActivated;
     94 jmethodID gCachedNfcManagerNotifyHostEmuData;
     95 jmethodID gCachedNfcManagerNotifyHostEmuDeactivated;
     96 jmethodID gCachedNfcManagerNotifyRfFieldActivated;
     97 jmethodID gCachedNfcManagerNotifyRfFieldDeactivated;
     98 const char* gNativeP2pDeviceClassName =
     99     "com/android/nfc/dhimpl/NativeP2pDevice";
    100 const char* gNativeLlcpServiceSocketClassName =
    101     "com/android/nfc/dhimpl/NativeLlcpServiceSocket";
    102 const char* gNativeLlcpConnectionlessSocketClassName =
    103     "com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket";
    104 const char* gNativeLlcpSocketClassName =
    105     "com/android/nfc/dhimpl/NativeLlcpSocket";
    106 const char* gNativeNfcTagClassName = "com/android/nfc/dhimpl/NativeNfcTag";
    107 const char* gNativeNfcManagerClassName =
    108     "com/android/nfc/dhimpl/NativeNfcManager";
    109 void doStartupConfig();
    110 void startStopPolling(bool isStartPolling);
    111 void startRfDiscovery(bool isStart);
    112 bool isDiscoveryStarted();
    113 }  // namespace android
    114 
    115 /*****************************************************************************
    116 **
    117 ** private variables and functions
    118 **
    119 *****************************************************************************/
    120 namespace android {
    121 static jint sLastError = ERROR_BUFFER_TOO_SMALL;
    122 static SyncEvent sNfaEnableEvent;                // event for NFA_Enable()
    123 static SyncEvent sNfaDisableEvent;               // event for NFA_Disable()
    124 static SyncEvent sNfaEnableDisablePollingEvent;  // event for
    125                                                  // NFA_EnablePolling(),
    126                                                  // NFA_DisablePolling()
    127 static SyncEvent sNfaSetConfigEvent;             // event for Set_Config....
    128 static SyncEvent sNfaGetConfigEvent;             // event for Get_Config....
    129 static bool sIsNfaEnabled = false;
    130 static bool sDiscoveryEnabled = false;  // is polling or listening
    131 static bool sPollingEnabled = false;    // is polling for tag?
    132 static bool sIsDisabling = false;
    133 static bool sRfEnabled = false;   // whether RF discovery is enabled
    134 static bool sSeRfActive = false;  // whether RF with SE is likely active
    135 static bool sReaderModeEnabled =
    136     false;  // whether we're only reading tags, not allowing P2p/card emu
    137 static bool sP2pEnabled = false;
    138 static bool sP2pActive = false;  // whether p2p was last active
    139 static bool sAbortConnlessWait = false;
    140 static jint sLfT3tMax = 0;
    141 
    142 #define CONFIG_UPDATE_TECH_MASK (1 << 1)
    143 #define DEFAULT_TECH_MASK                                                  \
    144   (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F | \
    145    NFA_TECHNOLOGY_MASK_V | NFA_TECHNOLOGY_MASK_B_PRIME |                   \
    146    NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE |           \
    147    NFA_TECHNOLOGY_MASK_KOVIO)
    148 #define DEFAULT_DISCOVERY_DURATION 500
    149 #define READER_MODE_DISCOVERY_DURATION 200
    150 
    151 static void nfaConnectionCallback(uint8_t event, tNFA_CONN_EVT_DATA* eventData);
    152 static void nfaDeviceManagementCallback(uint8_t event,
    153                                         tNFA_DM_CBACK_DATA* eventData);
    154 static bool isPeerToPeer(tNFA_ACTIVATED& activated);
    155 static bool isListenMode(tNFA_ACTIVATED& activated);
    156 static void enableDisableLptd(bool enable);
    157 static tNFA_STATUS stopPolling_rfDiscoveryDisabled();
    158 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
    159     tNFA_TECHNOLOGY_MASK tech_mask);
    160 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
    161                                         jint screen_state_mask);
    162 
    163 static uint16_t sCurrentConfigLen;
    164 static uint8_t sConfig[256];
    165 static int prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
    166 static int NFA_SCREEN_POLLING_TAG_MASK = 0x10;
    167 static bool gIsDtaEnabled = false;
    168 /////////////////////////////////////////////////////////////
    169 /////////////////////////////////////////////////////////////
    170 
    171 bool nfc_debug_enabled;
    172 
    173 namespace {
    174 void initializeGlobalDebugEnabledFlag() {
    175   nfc_debug_enabled =
    176       (NfcConfig::getUnsigned(NAME_NFC_DEBUG_ENABLED, 1) != 0) ? true : false;
    177 
    178   char valueStr[PROPERTY_VALUE_MAX] = {0};
    179   int len = property_get("nfc.debug_enabled", valueStr, "");
    180   if (len > 0) {
    181     unsigned debug_enabled = 1;
    182     // let Android property override .conf variable
    183     sscanf(valueStr, "%u", &debug_enabled);
    184     nfc_debug_enabled = (debug_enabled == 0) ? false : true;
    185   }
    186 
    187   DLOG_IF(INFO, nfc_debug_enabled)
    188       << StringPrintf("%s: level=%u", __func__, nfc_debug_enabled);
    189 }
    190 }  // namespace
    191 
    192 /*******************************************************************************
    193 **
    194 ** Function:        getNative
    195 **
    196 ** Description:     Get native data
    197 **
    198 ** Returns:         Native data structure.
    199 **
    200 *******************************************************************************/
    201 nfc_jni_native_data* getNative(JNIEnv* e, jobject o) {
    202   static struct nfc_jni_native_data* sCachedNat = NULL;
    203   if (e) {
    204     sCachedNat = nfc_jni_get_nat(e, o);
    205   }
    206   return sCachedNat;
    207 }
    208 
    209 /*******************************************************************************
    210 **
    211 ** Function:        handleRfDiscoveryEvent
    212 **
    213 ** Description:     Handle RF-discovery events from the stack.
    214 **                  discoveredDevice: Discovered device.
    215 **
    216 ** Returns:         None
    217 **
    218 *******************************************************************************/
    219 static void handleRfDiscoveryEvent(tNFC_RESULT_DEVT* discoveredDevice) {
    220   if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) {
    221     // there is more discovery notification coming
    222     return;
    223   }
    224 
    225   bool isP2p = NfcTag::getInstance().isP2pDiscovered();
    226   if (!sReaderModeEnabled && isP2p) {
    227     // select the peer that supports P2P
    228     NfcTag::getInstance().selectP2p();
    229   } else {
    230     // select the first of multiple tags that is discovered
    231     NfcTag::getInstance().selectFirstTag();
    232   }
    233 }
    234 
    235 /*******************************************************************************
    236 **
    237 ** Function:        nfaConnectionCallback
    238 **
    239 ** Description:     Receive connection-related events from stack.
    240 **                  connEvent: Event code.
    241 **                  eventData: Event data.
    242 **
    243 ** Returns:         None
    244 **
    245 *******************************************************************************/
    246 static void nfaConnectionCallback(uint8_t connEvent,
    247                                   tNFA_CONN_EVT_DATA* eventData) {
    248   tNFA_STATUS status = NFA_STATUS_FAILED;
    249   DLOG_IF(INFO, nfc_debug_enabled)
    250       << StringPrintf("%s: event= %u", __func__, connEvent);
    251 
    252   switch (connEvent) {
    253     case NFA_POLL_ENABLED_EVT:  // whether polling successfully started
    254     {
    255       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    256           "%s: NFA_POLL_ENABLED_EVT: status = %u", __func__, eventData->status);
    257 
    258       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
    259       sNfaEnableDisablePollingEvent.notifyOne();
    260     } break;
    261 
    262     case NFA_POLL_DISABLED_EVT:  // Listening/Polling stopped
    263     {
    264       DLOG_IF(INFO, nfc_debug_enabled)
    265           << StringPrintf("%s: NFA_POLL_DISABLED_EVT: status = %u", __func__,
    266                           eventData->status);
    267 
    268       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
    269       sNfaEnableDisablePollingEvent.notifyOne();
    270     } break;
    271 
    272     case NFA_RF_DISCOVERY_STARTED_EVT:  // RF Discovery started
    273     {
    274       DLOG_IF(INFO, nfc_debug_enabled)
    275           << StringPrintf("%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u",
    276                           __func__, eventData->status);
    277 
    278       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
    279       sNfaEnableDisablePollingEvent.notifyOne();
    280     } break;
    281 
    282     case NFA_RF_DISCOVERY_STOPPED_EVT:  // RF Discovery stopped event
    283     {
    284       DLOG_IF(INFO, nfc_debug_enabled)
    285           << StringPrintf("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u",
    286                           __func__, eventData->status);
    287 
    288       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
    289       sNfaEnableDisablePollingEvent.notifyOne();
    290     } break;
    291 
    292     case NFA_DISC_RESULT_EVT:  // NFC link/protocol discovery notificaiton
    293       status = eventData->disc_result.status;
    294       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    295           "%s: NFA_DISC_RESULT_EVT: status = %d", __func__, status);
    296       if (status != NFA_STATUS_OK) {
    297         LOG(ERROR) << StringPrintf("%s: NFA_DISC_RESULT_EVT error: status = %d",
    298                                    __func__, status);
    299       } else {
    300         NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
    301         handleRfDiscoveryEvent(&eventData->disc_result.discovery_ntf);
    302       }
    303       break;
    304 
    305     case NFA_SELECT_RESULT_EVT:  // NFC link/protocol discovery select response
    306       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    307           "%s: NFA_SELECT_RESULT_EVT: status = %d, gIsSelectingRfInterface = "
    308           "%d, "
    309           "sIsDisabling=%d",
    310           __func__, eventData->status, gIsSelectingRfInterface, sIsDisabling);
    311 
    312       if (sIsDisabling) break;
    313 
    314       if (eventData->status != NFA_STATUS_OK) {
    315         if (gIsSelectingRfInterface) {
    316           nativeNfcTag_doConnectStatus(false);
    317         }
    318 
    319         LOG(ERROR) << StringPrintf(
    320             "%s: NFA_SELECT_RESULT_EVT error: status = %d", __func__,
    321             eventData->status);
    322         NFA_Deactivate(FALSE);
    323       }
    324       break;
    325 
    326     case NFA_DEACTIVATE_FAIL_EVT:
    327       DLOG_IF(INFO, nfc_debug_enabled)
    328           << StringPrintf("%s: NFA_DEACTIVATE_FAIL_EVT: status = %d", __func__,
    329                           eventData->status);
    330       break;
    331 
    332     case NFA_ACTIVATED_EVT:  // NFC link/protocol activated
    333       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    334           "%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d",
    335           __func__, gIsSelectingRfInterface, sIsDisabling);
    336       if ((eventData->activated.activate_ntf.protocol !=
    337            NFA_PROTOCOL_NFC_DEP) &&
    338           (!isListenMode(eventData->activated))) {
    339         nativeNfcTag_setRfInterface(
    340             (tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param.type);
    341       }
    342       if (EXTNS_GetConnectFlag() == TRUE) {
    343         NfcTag::getInstance().setActivationState();
    344         nativeNfcTag_doConnectStatus(true);
    345         break;
    346       }
    347       NfcTag::getInstance().setActive(true);
    348       if (sIsDisabling || !sIsNfaEnabled) break;
    349       gActivated = true;
    350 
    351       NfcTag::getInstance().setActivationState();
    352       if (gIsSelectingRfInterface) {
    353         nativeNfcTag_doConnectStatus(true);
    354         break;
    355       }
    356 
    357       nativeNfcTag_resetPresenceCheck();
    358       if (isPeerToPeer(eventData->activated)) {
    359         if (sReaderModeEnabled) {
    360           DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    361               "%s: ignoring peer target in reader mode.", __func__);
    362           NFA_Deactivate(FALSE);
    363           break;
    364         }
    365         sP2pActive = true;
    366         DLOG_IF(INFO, nfc_debug_enabled)
    367             << StringPrintf("%s: NFA_ACTIVATED_EVT; is p2p", __func__);
    368         if (NFC_GetNCIVersion() == NCI_VERSION_1_0) {
    369           // Disable RF field events in case of p2p
    370           uint8_t nfa_disable_rf_events[] = {0x00};
    371           DLOG_IF(INFO, nfc_debug_enabled)
    372               << StringPrintf("%s: Disabling RF field events", __func__);
    373           status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO,
    374                                  sizeof(nfa_disable_rf_events),
    375                                  &nfa_disable_rf_events[0]);
    376           if (status == NFA_STATUS_OK) {
    377             DLOG_IF(INFO, nfc_debug_enabled)
    378                 << StringPrintf("%s: Disabled RF field events", __func__);
    379           } else {
    380             LOG(ERROR) << StringPrintf("%s: Failed to disable RF field events",
    381                                        __func__);
    382           }
    383         }
    384       } else if (pn544InteropIsBusy() == false) {
    385         NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
    386 
    387         // We know it is not activating for P2P.  If it activated in
    388         // listen mode then it is likely for an SE transaction.
    389         // Send the RF Event.
    390         if (isListenMode(eventData->activated)) {
    391           sSeRfActive = true;
    392         }
    393       }
    394       break;
    395 
    396     case NFA_DEACTIVATED_EVT:  // NFC link/protocol deactivated
    397       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    398           "%s: NFA_DEACTIVATED_EVT   Type: %u, gIsTagDeactivating: %d",
    399           __func__, eventData->deactivated.type, gIsTagDeactivating);
    400       NfcTag::getInstance().setDeactivationState(eventData->deactivated);
    401       if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP) {
    402         {
    403           SyncEventGuard g(gDeactivatedEvent);
    404           gActivated = false;  // guard this variable from multi-threaded access
    405           gDeactivatedEvent.notifyOne();
    406         }
    407         nativeNfcTag_resetPresenceCheck();
    408         NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
    409         nativeNfcTag_abortWaits();
    410         NfcTag::getInstance().abort();
    411       } else if (gIsTagDeactivating) {
    412         NfcTag::getInstance().setActive(false);
    413         nativeNfcTag_doDeactivateStatus(0);
    414       } else if (EXTNS_GetDeactivateFlag() == TRUE) {
    415         NfcTag::getInstance().setActive(false);
    416         nativeNfcTag_doDeactivateStatus(0);
    417       }
    418 
    419       // If RF is activated for what we think is a Secure Element transaction
    420       // and it is deactivated to either IDLE or DISCOVERY mode, notify w/event.
    421       if ((eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE) ||
    422           (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_DISCOVERY)) {
    423         if (sSeRfActive) {
    424           sSeRfActive = false;
    425         } else if (sP2pActive) {
    426           sP2pActive = false;
    427           // Make sure RF field events are re-enabled
    428           DLOG_IF(INFO, nfc_debug_enabled)
    429               << StringPrintf("%s: NFA_DEACTIVATED_EVT; is p2p", __func__);
    430           if (NFC_GetNCIVersion() == NCI_VERSION_1_0) {
    431             // Disable RF field events in case of p2p
    432             uint8_t nfa_enable_rf_events[] = {0x01};
    433 
    434             if (!sIsDisabling && sIsNfaEnabled) {
    435               DLOG_IF(INFO, nfc_debug_enabled)
    436                   << StringPrintf("%s: Enabling RF field events", __func__);
    437               status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO,
    438                                      sizeof(nfa_enable_rf_events),
    439                                      &nfa_enable_rf_events[0]);
    440               if (status == NFA_STATUS_OK) {
    441                 DLOG_IF(INFO, nfc_debug_enabled)
    442                     << StringPrintf("%s: Enabled RF field events", __func__);
    443               } else {
    444                 LOG(ERROR) << StringPrintf(
    445                     "%s: Failed to enable RF field events", __func__);
    446               }
    447             }
    448           }
    449         }
    450       }
    451 
    452       break;
    453 
    454     case NFA_TLV_DETECT_EVT:  // TLV Detection complete
    455       status = eventData->tlv_detect.status;
    456       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    457           "%s: NFA_TLV_DETECT_EVT: status = %d, protocol = %d, num_tlvs = %d, "
    458           "num_bytes = %d",
    459           __func__, status, eventData->tlv_detect.protocol,
    460           eventData->tlv_detect.num_tlvs, eventData->tlv_detect.num_bytes);
    461       if (status != NFA_STATUS_OK) {
    462         LOG(ERROR) << StringPrintf("%s: NFA_TLV_DETECT_EVT error: status = %d",
    463                                    __func__, status);
    464       }
    465       break;
    466 
    467     case NFA_NDEF_DETECT_EVT:  // NDEF Detection complete;
    468       // if status is failure, it means the tag does not contain any or valid
    469       // NDEF data;  pass the failure status to the NFC Service;
    470       status = eventData->ndef_detect.status;
    471       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    472           "%s: NFA_NDEF_DETECT_EVT: status = 0x%X, protocol = %u, "
    473           "max_size = %u, cur_size = %u, flags = 0x%X",
    474           __func__, status, eventData->ndef_detect.protocol,
    475           eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size,
    476           eventData->ndef_detect.flags);
    477       NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
    478       nativeNfcTag_doCheckNdefResult(status, eventData->ndef_detect.max_size,
    479                                      eventData->ndef_detect.cur_size,
    480                                      eventData->ndef_detect.flags);
    481       break;
    482 
    483     case NFA_DATA_EVT:  // Data message received (for non-NDEF reads)
    484       DLOG_IF(INFO, nfc_debug_enabled)
    485           << StringPrintf("%s: NFA_DATA_EVT: status = 0x%X, len = %d", __func__,
    486                           eventData->status, eventData->data.len);
    487       nativeNfcTag_doTransceiveStatus(eventData->status, eventData->data.p_data,
    488                                       eventData->data.len);
    489       break;
    490     case NFA_RW_INTF_ERROR_EVT:
    491       DLOG_IF(INFO, nfc_debug_enabled)
    492           << StringPrintf("%s: NFC_RW_INTF_ERROR_EVT", __func__);
    493       nativeNfcTag_notifyRfTimeout();
    494       nativeNfcTag_doReadCompleted(NFA_STATUS_TIMEOUT);
    495       break;
    496     case NFA_SELECT_CPLT_EVT:  // Select completed
    497       status = eventData->status;
    498       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    499           "%s: NFA_SELECT_CPLT_EVT: status = %d", __func__, status);
    500       if (status != NFA_STATUS_OK) {
    501         LOG(ERROR) << StringPrintf("%s: NFA_SELECT_CPLT_EVT error: status = %d",
    502                                    __func__, status);
    503       }
    504       break;
    505 
    506     case NFA_READ_CPLT_EVT:  // NDEF-read or tag-specific-read completed
    507       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    508           "%s: NFA_READ_CPLT_EVT: status = 0x%X", __func__, eventData->status);
    509       nativeNfcTag_doReadCompleted(eventData->status);
    510       NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
    511       break;
    512 
    513     case NFA_WRITE_CPLT_EVT:  // Write completed
    514       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    515           "%s: NFA_WRITE_CPLT_EVT: status = %d", __func__, eventData->status);
    516       nativeNfcTag_doWriteStatus(eventData->status == NFA_STATUS_OK);
    517       break;
    518 
    519     case NFA_SET_TAG_RO_EVT:  // Tag set as Read only
    520       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    521           "%s: NFA_SET_TAG_RO_EVT: status = %d", __func__, eventData->status);
    522       nativeNfcTag_doMakeReadonlyResult(eventData->status);
    523       break;
    524 
    525     case NFA_CE_NDEF_WRITE_START_EVT:  // NDEF write started
    526       DLOG_IF(INFO, nfc_debug_enabled)
    527           << StringPrintf("%s: NFA_CE_NDEF_WRITE_START_EVT: status: %d",
    528                           __func__, eventData->status);
    529 
    530       if (eventData->status != NFA_STATUS_OK)
    531         LOG(ERROR) << StringPrintf(
    532             "%s: NFA_CE_NDEF_WRITE_START_EVT error: status = %d", __func__,
    533             eventData->status);
    534       break;
    535 
    536     case NFA_CE_NDEF_WRITE_CPLT_EVT:  // NDEF write completed
    537       DLOG_IF(INFO, nfc_debug_enabled)
    538           << StringPrintf("%s: FA_CE_NDEF_WRITE_CPLT_EVT: len = %u", __func__,
    539                           eventData->ndef_write_cplt.len);
    540       break;
    541 
    542     case NFA_LLCP_ACTIVATED_EVT:  // LLCP link is activated
    543       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    544           "%s: NFA_LLCP_ACTIVATED_EVT: is_initiator: %d  remote_wks: %d, "
    545           "remote_lsc: %d, remote_link_miu: %d, local_link_miu: %d",
    546           __func__, eventData->llcp_activated.is_initiator,
    547           eventData->llcp_activated.remote_wks,
    548           eventData->llcp_activated.remote_lsc,
    549           eventData->llcp_activated.remote_link_miu,
    550           eventData->llcp_activated.local_link_miu);
    551 
    552       PeerToPeer::getInstance().llcpActivatedHandler(getNative(0, 0),
    553                                                      eventData->llcp_activated);
    554       break;
    555 
    556     case NFA_LLCP_DEACTIVATED_EVT:  // LLCP link is deactivated
    557       DLOG_IF(INFO, nfc_debug_enabled)
    558           << StringPrintf("%s: NFA_LLCP_DEACTIVATED_EVT", __func__);
    559       PeerToPeer::getInstance().llcpDeactivatedHandler(
    560           getNative(0, 0), eventData->llcp_deactivated);
    561       break;
    562     case NFA_LLCP_FIRST_PACKET_RECEIVED_EVT:  // Received first packet over llcp
    563       DLOG_IF(INFO, nfc_debug_enabled)
    564           << StringPrintf("%s: NFA_LLCP_FIRST_PACKET_RECEIVED_EVT", __func__);
    565       PeerToPeer::getInstance().llcpFirstPacketHandler(getNative(0, 0));
    566       break;
    567     case NFA_PRESENCE_CHECK_EVT:
    568       DLOG_IF(INFO, nfc_debug_enabled)
    569           << StringPrintf("%s: NFA_PRESENCE_CHECK_EVT", __func__);
    570       nativeNfcTag_doPresenceCheckResult(eventData->status);
    571       break;
    572     case NFA_FORMAT_CPLT_EVT:
    573       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    574           "%s: NFA_FORMAT_CPLT_EVT: status=0x%X", __func__, eventData->status);
    575       nativeNfcTag_formatStatus(eventData->status == NFA_STATUS_OK);
    576       break;
    577 
    578     case NFA_I93_CMD_CPLT_EVT:
    579       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    580           "%s: NFA_I93_CMD_CPLT_EVT: status=0x%X", __func__, eventData->status);
    581       break;
    582 
    583     case NFA_CE_UICC_LISTEN_CONFIGURED_EVT:
    584       DLOG_IF(INFO, nfc_debug_enabled)
    585           << StringPrintf("%s: NFA_CE_UICC_LISTEN_CONFIGURED_EVT : status=0x%X",
    586                           __func__, eventData->status);
    587       break;
    588 
    589     case NFA_SET_P2P_LISTEN_TECH_EVT:
    590       DLOG_IF(INFO, nfc_debug_enabled)
    591           << StringPrintf("%s: NFA_SET_P2P_LISTEN_TECH_EVT", __func__);
    592       PeerToPeer::getInstance().connectionEventHandler(connEvent, eventData);
    593       break;
    594 
    595     default:
    596       DLOG_IF(INFO, nfc_debug_enabled)
    597           << StringPrintf("%s: unknown event ????", __func__);
    598       break;
    599   }
    600 }
    601 
    602 /*******************************************************************************
    603 **
    604 ** Function:        nfcManager_initNativeStruc
    605 **
    606 ** Description:     Initialize variables.
    607 **                  e: JVM environment.
    608 **                  o: Java object.
    609 **
    610 ** Returns:         True if ok.
    611 **
    612 *******************************************************************************/
    613 static jboolean nfcManager_initNativeStruc(JNIEnv* e, jobject o) {
    614   initializeGlobalDebugEnabledFlag();
    615   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
    616 
    617   nfc_jni_native_data* nat =
    618       (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
    619   if (nat == NULL) {
    620     LOG(ERROR) << StringPrintf("%s: fail allocate native data", __func__);
    621     return JNI_FALSE;
    622   }
    623 
    624   memset(nat, 0, sizeof(*nat));
    625   e->GetJavaVM(&(nat->vm));
    626   nat->env_version = e->GetVersion();
    627   nat->manager = e->NewGlobalRef(o);
    628 
    629   ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
    630   jfieldID f = e->GetFieldID(cls.get(), "mNative", "J");
    631   e->SetLongField(o, f, (jlong)nat);
    632 
    633   /* Initialize native cached references */
    634   gCachedNfcManagerNotifyNdefMessageListeners =
    635       e->GetMethodID(cls.get(), "notifyNdefMessageListeners",
    636                      "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
    637   gCachedNfcManagerNotifyLlcpLinkActivation =
    638       e->GetMethodID(cls.get(), "notifyLlcpLinkActivation",
    639                      "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
    640   gCachedNfcManagerNotifyLlcpLinkDeactivated =
    641       e->GetMethodID(cls.get(), "notifyLlcpLinkDeactivated",
    642                      "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
    643   gCachedNfcManagerNotifyLlcpFirstPacketReceived =
    644       e->GetMethodID(cls.get(), "notifyLlcpLinkFirstPacketReceived",
    645                      "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
    646 
    647   gCachedNfcManagerNotifyHostEmuActivated =
    648       e->GetMethodID(cls.get(), "notifyHostEmuActivated", "(I)V");
    649 
    650   gCachedNfcManagerNotifyHostEmuData =
    651       e->GetMethodID(cls.get(), "notifyHostEmuData", "(I[B)V");
    652 
    653   gCachedNfcManagerNotifyHostEmuDeactivated =
    654       e->GetMethodID(cls.get(), "notifyHostEmuDeactivated", "(I)V");
    655 
    656   gCachedNfcManagerNotifyRfFieldActivated =
    657       e->GetMethodID(cls.get(), "notifyRfFieldActivated", "()V");
    658   gCachedNfcManagerNotifyRfFieldDeactivated =
    659       e->GetMethodID(cls.get(), "notifyRfFieldDeactivated", "()V");
    660 
    661   gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID(
    662       cls.get(), "notifyTransactionListeners", "([B[BLjava/lang/String;)V");
    663 
    664   if (nfc_jni_cache_object(e, gNativeNfcTagClassName, &(nat->cached_NfcTag)) ==
    665       -1) {
    666     LOG(ERROR) << StringPrintf("%s: fail cache NativeNfcTag", __func__);
    667     return JNI_FALSE;
    668   }
    669 
    670   if (nfc_jni_cache_object(e, gNativeP2pDeviceClassName,
    671                            &(nat->cached_P2pDevice)) == -1) {
    672     LOG(ERROR) << StringPrintf("%s: fail cache NativeP2pDevice", __func__);
    673     return JNI_FALSE;
    674   }
    675 
    676   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
    677   return JNI_TRUE;
    678 }
    679 
    680 /*******************************************************************************
    681 **
    682 ** Function:        nfaDeviceManagementCallback
    683 **
    684 ** Description:     Receive device management events from stack.
    685 **                  dmEvent: Device-management event ID.
    686 **                  eventData: Data associated with event ID.
    687 **
    688 ** Returns:         None
    689 **
    690 *******************************************************************************/
    691 void nfaDeviceManagementCallback(uint8_t dmEvent,
    692                                  tNFA_DM_CBACK_DATA* eventData) {
    693   DLOG_IF(INFO, nfc_debug_enabled)
    694       << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent);
    695 
    696   switch (dmEvent) {
    697     case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
    698     {
    699       SyncEventGuard guard(sNfaEnableEvent);
    700       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    701           "%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__, eventData->status);
    702       sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
    703       sIsDisabling = false;
    704       sNfaEnableEvent.notifyOne();
    705     } break;
    706 
    707     case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
    708     {
    709       SyncEventGuard guard(sNfaDisableEvent);
    710       DLOG_IF(INFO, nfc_debug_enabled)
    711           << StringPrintf("%s: NFA_DM_DISABLE_EVT", __func__);
    712       sIsNfaEnabled = false;
    713       sIsDisabling = false;
    714       sNfaDisableEvent.notifyOne();
    715     } break;
    716 
    717     case NFA_DM_SET_CONFIG_EVT:  // result of NFA_SetConfig
    718       DLOG_IF(INFO, nfc_debug_enabled)
    719           << StringPrintf("%s: NFA_DM_SET_CONFIG_EVT", __func__);
    720       {
    721         SyncEventGuard guard(sNfaSetConfigEvent);
    722         sNfaSetConfigEvent.notifyOne();
    723       }
    724       break;
    725 
    726     case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */
    727       DLOG_IF(INFO, nfc_debug_enabled)
    728           << StringPrintf("%s: NFA_DM_GET_CONFIG_EVT", __func__);
    729       {
    730         SyncEventGuard guard(sNfaGetConfigEvent);
    731         if (eventData->status == NFA_STATUS_OK &&
    732             eventData->get_config.tlv_size <= sizeof(sConfig)) {
    733           sCurrentConfigLen = eventData->get_config.tlv_size;
    734           memcpy(sConfig, eventData->get_config.param_tlvs,
    735                  eventData->get_config.tlv_size);
    736         } else {
    737           LOG(ERROR) << StringPrintf("%s: NFA_DM_GET_CONFIG failed", __func__);
    738           sCurrentConfigLen = 0;
    739         }
    740         sNfaGetConfigEvent.notifyOne();
    741       }
    742       break;
    743 
    744     case NFA_DM_RF_FIELD_EVT:
    745       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    746           "%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __func__,
    747           eventData->rf_field.status, eventData->rf_field.rf_field_status);
    748       if (!sP2pActive && eventData->rf_field.status == NFA_STATUS_OK) {
    749         struct nfc_jni_native_data* nat = getNative(NULL, NULL);
    750         JNIEnv* e = NULL;
    751         ScopedAttach attach(nat->vm, &e);
    752         if (e == NULL) {
    753           LOG(ERROR) << StringPrintf("jni env is null");
    754           return;
    755         }
    756         if (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON)
    757           e->CallVoidMethod(nat->manager,
    758                             android::gCachedNfcManagerNotifyRfFieldActivated);
    759         else
    760           e->CallVoidMethod(nat->manager,
    761                             android::gCachedNfcManagerNotifyRfFieldDeactivated);
    762       }
    763       break;
    764 
    765     case NFA_DM_NFCC_TRANSPORT_ERR_EVT:
    766     case NFA_DM_NFCC_TIMEOUT_EVT: {
    767       if (dmEvent == NFA_DM_NFCC_TIMEOUT_EVT)
    768         LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TIMEOUT_EVT; abort",
    769                                    __func__);
    770       else if (dmEvent == NFA_DM_NFCC_TRANSPORT_ERR_EVT)
    771         LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TRANSPORT_ERR_EVT; abort",
    772                                    __func__);
    773 
    774       nativeNfcTag_abortWaits();
    775       NfcTag::getInstance().abort();
    776       sAbortConnlessWait = true;
    777       nativeLlcpConnectionlessSocket_abortWait();
    778       {
    779         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    780             "%s: aborting  sNfaEnableDisablePollingEvent", __func__);
    781         SyncEventGuard guard(sNfaEnableDisablePollingEvent);
    782         sNfaEnableDisablePollingEvent.notifyOne();
    783       }
    784       {
    785         DLOG_IF(INFO, nfc_debug_enabled)
    786             << StringPrintf("%s: aborting  sNfaEnableEvent", __func__);
    787         SyncEventGuard guard(sNfaEnableEvent);
    788         sNfaEnableEvent.notifyOne();
    789       }
    790       {
    791         DLOG_IF(INFO, nfc_debug_enabled)
    792             << StringPrintf("%s: aborting  sNfaDisableEvent", __func__);
    793         SyncEventGuard guard(sNfaDisableEvent);
    794         sNfaDisableEvent.notifyOne();
    795       }
    796       sDiscoveryEnabled = false;
    797       sPollingEnabled = false;
    798       PowerSwitch::getInstance().abort();
    799 
    800       if (!sIsDisabling && sIsNfaEnabled) {
    801         EXTNS_Close();
    802         NFA_Disable(FALSE);
    803         sIsDisabling = true;
    804       } else {
    805         sIsNfaEnabled = false;
    806         sIsDisabling = false;
    807       }
    808       PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
    809       LOG(ERROR) << StringPrintf("%s: crash NFC service", __func__);
    810       //////////////////////////////////////////////
    811       // crash the NFC service process so it can restart automatically
    812       abort();
    813       //////////////////////////////////////////////
    814     } break;
    815 
    816     case NFA_DM_PWR_MODE_CHANGE_EVT:
    817       PowerSwitch::getInstance().deviceManagementCallback(dmEvent, eventData);
    818       break;
    819 
    820     case NFA_DM_SET_POWER_SUB_STATE_EVT: {
    821       DLOG_IF(INFO, nfc_debug_enabled)
    822           << StringPrintf("%s: NFA_DM_SET_POWER_SUB_STATE_EVT; status=0x%X",
    823                           __FUNCTION__, eventData->power_sub_state.status);
    824       SyncEventGuard guard(sNfaSetPowerSubState);
    825       sNfaSetPowerSubState.notifyOne();
    826     } break;
    827     default:
    828       DLOG_IF(INFO, nfc_debug_enabled)
    829           << StringPrintf("%s: unhandled event", __func__);
    830       break;
    831   }
    832 }
    833 
    834 /*******************************************************************************
    835 **
    836 ** Function:        nfcManager_sendRawFrame
    837 **
    838 ** Description:     Send a raw frame.
    839 **                  e: JVM environment.
    840 **                  o: Java object.
    841 **
    842 ** Returns:         True if ok.
    843 **
    844 *******************************************************************************/
    845 static jboolean nfcManager_sendRawFrame(JNIEnv* e, jobject, jbyteArray data) {
    846   ScopedByteArrayRO bytes(e, data);
    847   uint8_t* buf =
    848       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
    849   size_t bufLen = bytes.size();
    850   tNFA_STATUS status = NFA_SendRawFrame(buf, bufLen, 0);
    851 
    852   return (status == NFA_STATUS_OK);
    853 }
    854 
    855 /*******************************************************************************
    856 **
    857 ** Function:        nfcManager_routeAid
    858 **
    859 ** Description:     Route an AID to an EE
    860 **                  e: JVM environment.
    861 **                  aid: aid to be added to routing table.
    862 **                  route: aid route location. i.e. DH/eSE/UICC
    863 **                  aidInfo: prefix or suffix aid.
    864 **
    865 ** Returns:         True if aid is accpted by NFA Layer.
    866 **
    867 *******************************************************************************/
    868 static jboolean nfcManager_routeAid(JNIEnv* e, jobject, jbyteArray aid,
    869                                     jint route, jint aidInfo) {
    870   ScopedByteArrayRO bytes(e, aid);
    871   uint8_t* buf =
    872       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
    873   size_t bufLen = bytes.size();
    874   return RoutingManager::getInstance().addAidRouting(buf, bufLen, route,
    875                                                      aidInfo);
    876 }
    877 
    878 /*******************************************************************************
    879 **
    880 ** Function:        nfcManager_unrouteAid
    881 **
    882 ** Description:     Remove a AID routing
    883 **                  e: JVM environment.
    884 **                  o: Java object.
    885 **
    886 ** Returns:         True if ok.
    887 **
    888 *******************************************************************************/
    889 static jboolean nfcManager_unrouteAid(JNIEnv* e, jobject, jbyteArray aid) {
    890   ScopedByteArrayRO bytes(e, aid);
    891   uint8_t* buf =
    892       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
    893   size_t bufLen = bytes.size();
    894   bool result = RoutingManager::getInstance().removeAidRouting(buf, bufLen);
    895   return result;
    896 }
    897 
    898 /*******************************************************************************
    899 **
    900 ** Function:        nfcManager_commitRouting
    901 **
    902 ** Description:     Sends the AID routing table to the controller
    903 **                  e: JVM environment.
    904 **                  o: Java object.
    905 **
    906 ** Returns:         True if ok.
    907 **
    908 *******************************************************************************/
    909 static jboolean nfcManager_commitRouting(JNIEnv* e, jobject) {
    910   if (sRfEnabled) {
    911     /*Update routing table only in Idle state.*/
    912     startRfDiscovery(false);
    913   }
    914   jboolean commitStatus = RoutingManager::getInstance().commitRouting();
    915   startRfDiscovery(true);
    916   return commitStatus;
    917 }
    918 
    919 /*******************************************************************************
    920 **
    921 ** Function:        nfcManager_doRegisterT3tIdentifier
    922 **
    923 ** Description:     Registers LF_T3T_IDENTIFIER for NFC-F.
    924 **                  e: JVM environment.
    925 **                  o: Java object.
    926 **                  t3tIdentifier: LF_T3T_IDENTIFIER value (10 or 18 bytes)
    927 **
    928 ** Returns:         Handle retrieve from RoutingManager.
    929 **
    930 *******************************************************************************/
    931 static jint nfcManager_doRegisterT3tIdentifier(JNIEnv* e, jobject,
    932                                                jbyteArray t3tIdentifier) {
    933   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
    934 
    935   ScopedByteArrayRO bytes(e, t3tIdentifier);
    936   uint8_t* buf =
    937       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
    938   size_t bufLen = bytes.size();
    939   int handle = RoutingManager::getInstance().registerT3tIdentifier(buf, bufLen);
    940 
    941   DLOG_IF(INFO, nfc_debug_enabled)
    942       << StringPrintf("%s: handle=%d", __func__, handle);
    943   if (handle != NFA_HANDLE_INVALID)
    944     RoutingManager::getInstance().commitRouting();
    945   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
    946 
    947   return handle;
    948 }
    949 
    950 /*******************************************************************************
    951 **
    952 ** Function:        nfcManager_doDeregisterT3tIdentifier
    953 **
    954 ** Description:     Deregisters LF_T3T_IDENTIFIER for NFC-F.
    955 **                  e: JVM environment.
    956 **                  o: Java object.
    957 **                  handle: Handle retrieve from libnfc-nci.
    958 **
    959 ** Returns:         None
    960 **
    961 *******************************************************************************/
    962 static void nfcManager_doDeregisterT3tIdentifier(JNIEnv*, jobject,
    963                                                  jint handle) {
    964   DLOG_IF(INFO, nfc_debug_enabled)
    965       << StringPrintf("%s: enter; handle=%d", __func__, handle);
    966 
    967   RoutingManager::getInstance().deregisterT3tIdentifier(handle);
    968   RoutingManager::getInstance().commitRouting();
    969 
    970   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
    971 }
    972 
    973 /*******************************************************************************
    974 **
    975 ** Function:        nfcManager_getLfT3tMax
    976 **
    977 ** Description:     Returns LF_T3T_MAX value.
    978 **                  e: JVM environment.
    979 **                  o: Java object.
    980 **
    981 ** Returns:         LF_T3T_MAX value.
    982 **
    983 *******************************************************************************/
    984 static jint nfcManager_getLfT3tMax(JNIEnv*, jobject) {
    985   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
    986   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("LF_T3T_MAX=%d", sLfT3tMax);
    987   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
    988 
    989   return sLfT3tMax;
    990 }
    991 
    992 /*******************************************************************************
    993 **
    994 ** Function:        nfcManager_doInitialize
    995 **
    996 ** Description:     Turn on NFC.
    997 **                  e: JVM environment.
    998 **                  o: Java object.
    999 **
   1000 ** Returns:         True if ok.
   1001 **
   1002 *******************************************************************************/
   1003 static jboolean nfcManager_doInitialize(JNIEnv* e, jobject o) {
   1004   initializeGlobalDebugEnabledFlag();
   1005   tNFA_STATUS stat = NFA_STATUS_OK;
   1006 
   1007   PowerSwitch& powerSwitch = PowerSwitch::getInstance();
   1008 
   1009   if (sIsNfaEnabled) {
   1010     DLOG_IF(INFO, nfc_debug_enabled)
   1011         << StringPrintf("%s: already enabled", __func__);
   1012     goto TheEnd;
   1013   }
   1014 
   1015   powerSwitch.initialize(PowerSwitch::FULL_POWER);
   1016 
   1017   {
   1018 
   1019     NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1020     theInstance.Initialize();  // start GKI, NCI task, NFC task
   1021 
   1022     {
   1023       SyncEventGuard guard(sNfaEnableEvent);
   1024       tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
   1025 
   1026       NFA_Init(halFuncEntries);
   1027 
   1028       stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
   1029       if (stat == NFA_STATUS_OK) {
   1030         sNfaEnableEvent.wait();  // wait for NFA command to finish
   1031       }
   1032       EXTNS_Init(nfaDeviceManagementCallback, nfaConnectionCallback);
   1033     }
   1034 
   1035     if (stat == NFA_STATUS_OK) {
   1036       // sIsNfaEnabled indicates whether stack started successfully
   1037       if (sIsNfaEnabled) {
   1038         RoutingManager::getInstance().initialize(getNative(e, o));
   1039         nativeNfcTag_registerNdefTypeHandler();
   1040         NfcTag::getInstance().initialize(getNative(e, o));
   1041         PeerToPeer::getInstance().initialize();
   1042         PeerToPeer::getInstance().handleNfcOnOff(true);
   1043         HciEventManager::getInstance().initialize(getNative(e, o));
   1044 
   1045         /////////////////////////////////////////////////////////////////////////////////
   1046         // Add extra configuration here (work-arounds, etc.)
   1047 
   1048         if (gIsDtaEnabled == true) {
   1049           uint8_t configData = 0;
   1050           configData = 0x01; /* Poll NFC-DEP : Highest Available Bit Rates */
   1051           NFA_SetConfig(NCI_PARAM_ID_BITR_NFC_DEP, sizeof(uint8_t),
   1052                         &configData);
   1053           configData = 0x0B; /* Listen NFC-DEP : Waiting Time */
   1054           NFA_SetConfig(NFC_PMID_WT, sizeof(uint8_t), &configData);
   1055           configData = 0x0F; /* Specific Parameters for NFC-DEP RF Interface */
   1056           NFA_SetConfig(NCI_PARAM_ID_NFC_DEP_OP, sizeof(uint8_t), &configData);
   1057         }
   1058 
   1059         struct nfc_jni_native_data* nat = getNative(e, o);
   1060         if (nat) {
   1061           nat->tech_mask =
   1062               NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
   1063           DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1064               "%s: tag polling tech mask=0x%X", __func__, nat->tech_mask);
   1065         }
   1066 
   1067         // if this value exists, set polling interval.
   1068         nat->discovery_duration = NfcConfig::getUnsigned(
   1069             NAME_NFA_DM_DISC_DURATION_POLL, DEFAULT_DISCOVERY_DURATION);
   1070 
   1071         NFA_SetRfDiscoveryDuration(nat->discovery_duration);
   1072 
   1073         // get LF_T3T_MAX
   1074         {
   1075           SyncEventGuard guard(sNfaGetConfigEvent);
   1076           tNFA_PMID configParam[1] = {NCI_PARAM_ID_LF_T3T_MAX};
   1077           stat = NFA_GetConfig(1, configParam);
   1078           if (stat == NFA_STATUS_OK) {
   1079             sNfaGetConfigEvent.wait();
   1080             if (sCurrentConfigLen >= 4 ||
   1081                 sConfig[1] == NCI_PARAM_ID_LF_T3T_MAX) {
   1082               DLOG_IF(INFO, nfc_debug_enabled)
   1083                   << StringPrintf("%s: lfT3tMax=%d", __func__, sConfig[3]);
   1084               sLfT3tMax = sConfig[3];
   1085             }
   1086           }
   1087         }
   1088 
   1089         prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
   1090 
   1091         // Do custom NFCA startup configuration.
   1092         doStartupConfig();
   1093         goto TheEnd;
   1094       }
   1095     }
   1096 
   1097     LOG(ERROR) << StringPrintf("%s: fail nfa enable; error=0x%X", __func__,
   1098                                stat);
   1099 
   1100     if (sIsNfaEnabled) {
   1101       EXTNS_Close();
   1102       stat = NFA_Disable(FALSE /* ungraceful */);
   1103     }
   1104 
   1105     theInstance.Finalize();
   1106   }
   1107 
   1108 TheEnd:
   1109   if (sIsNfaEnabled)
   1110     PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER);
   1111   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1112   return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE;
   1113 }
   1114 
   1115 static void nfcManager_doEnableDtaMode(JNIEnv*, jobject) {
   1116   gIsDtaEnabled = true;
   1117 }
   1118 
   1119 static void nfcManager_doDisableDtaMode(JNIEnv*, jobject) {
   1120   gIsDtaEnabled = false;
   1121 }
   1122 
   1123 static void nfcManager_doFactoryReset(JNIEnv*, jobject) {
   1124   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1125   theInstance.FactoryReset();
   1126 }
   1127 
   1128 static void nfcManager_doShutdown(JNIEnv*, jobject) {
   1129   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1130   theInstance.DeviceShutdown();
   1131 }
   1132 /*******************************************************************************
   1133 **
   1134 ** Function:        nfcManager_enableDiscovery
   1135 **
   1136 ** Description:     Start polling and listening for devices.
   1137 **                  e: JVM environment.
   1138 **                  o: Java object.
   1139 **                  technologies_mask: the bitmask of technologies for which to
   1140 *enable discovery
   1141 **                  enable_lptd: whether to enable low power polling (default:
   1142 *false)
   1143 **
   1144 ** Returns:         None
   1145 **
   1146 *******************************************************************************/
   1147 static void nfcManager_enableDiscovery(JNIEnv* e, jobject o,
   1148                                        jint technologies_mask,
   1149                                        jboolean enable_lptd,
   1150                                        jboolean reader_mode,
   1151                                        jboolean enable_host_routing,
   1152                                        jboolean enable_p2p, jboolean restart) {
   1153   tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
   1154   struct nfc_jni_native_data* nat = getNative(e, o);
   1155 
   1156   if (technologies_mask == -1 && nat)
   1157     tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask;
   1158   else if (technologies_mask != -1)
   1159     tech_mask = (tNFA_TECHNOLOGY_MASK)technologies_mask;
   1160   DLOG_IF(INFO, nfc_debug_enabled)
   1161       << StringPrintf("%s: enter; tech_mask = %02x", __func__, tech_mask);
   1162 
   1163   if (sDiscoveryEnabled && !restart) {
   1164     LOG(ERROR) << StringPrintf("%s: already discovering", __func__);
   1165     return;
   1166   }
   1167 
   1168   PowerSwitch::getInstance().setLevel(PowerSwitch::FULL_POWER);
   1169 
   1170   if (sRfEnabled) {
   1171     // Stop RF discovery to reconfigure
   1172     startRfDiscovery(false);
   1173   }
   1174 
   1175   // Check polling configuration
   1176   if (tech_mask != 0) {
   1177     stopPolling_rfDiscoveryDisabled();
   1178     enableDisableLptd(enable_lptd);
   1179     startPolling_rfDiscoveryDisabled(tech_mask);
   1180 
   1181     // Start P2P listening if tag polling was enabled
   1182     if (sPollingEnabled) {
   1183       DLOG_IF(INFO, nfc_debug_enabled)
   1184           << StringPrintf("%s: Enable p2pListening", __func__);
   1185 
   1186       if (enable_p2p && !sP2pEnabled) {
   1187         sP2pEnabled = true;
   1188         PeerToPeer::getInstance().enableP2pListening(true);
   1189         NFA_ResumeP2p();
   1190       } else if (!enable_p2p && sP2pEnabled) {
   1191         sP2pEnabled = false;
   1192         PeerToPeer::getInstance().enableP2pListening(false);
   1193         NFA_PauseP2p();
   1194       }
   1195 
   1196       if (reader_mode && !sReaderModeEnabled) {
   1197         sReaderModeEnabled = true;
   1198         NFA_DisableListening();
   1199         NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
   1200       } else if (!reader_mode && sReaderModeEnabled) {
   1201         struct nfc_jni_native_data* nat = getNative(e, o);
   1202         sReaderModeEnabled = false;
   1203         NFA_EnableListening();
   1204         NFA_SetRfDiscoveryDuration(nat->discovery_duration);
   1205       }
   1206     }
   1207   } else {
   1208     // No technologies configured, stop polling
   1209     stopPolling_rfDiscoveryDisabled();
   1210   }
   1211 
   1212   // Check listen configuration
   1213   if (enable_host_routing) {
   1214     RoutingManager::getInstance().enableRoutingToHost();
   1215     RoutingManager::getInstance().commitRouting();
   1216   } else {
   1217     RoutingManager::getInstance().disableRoutingToHost();
   1218     RoutingManager::getInstance().commitRouting();
   1219   }
   1220   // Actually start discovery.
   1221   startRfDiscovery(true);
   1222   sDiscoveryEnabled = true;
   1223 
   1224   PowerSwitch::getInstance().setModeOn(PowerSwitch::DISCOVERY);
   1225 
   1226   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1227 }
   1228 
   1229 /*******************************************************************************
   1230 **
   1231 ** Function:        nfcManager_disableDiscovery
   1232 **
   1233 ** Description:     Stop polling and listening for devices.
   1234 **                  e: JVM environment.
   1235 **                  o: Java object.
   1236 **
   1237 ** Returns:         None
   1238 **
   1239 *******************************************************************************/
   1240 void nfcManager_disableDiscovery(JNIEnv* e, jobject o) {
   1241   tNFA_STATUS status = NFA_STATUS_OK;
   1242   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter;", __func__);
   1243 
   1244   pn544InteropAbortNow();
   1245   if (sDiscoveryEnabled == false) {
   1246     DLOG_IF(INFO, nfc_debug_enabled)
   1247         << StringPrintf("%s: already disabled", __func__);
   1248     goto TheEnd;
   1249   }
   1250 
   1251   // Stop RF Discovery.
   1252   startRfDiscovery(false);
   1253 
   1254   if (sPollingEnabled) status = stopPolling_rfDiscoveryDisabled();
   1255 
   1256   PeerToPeer::getInstance().enableP2pListening(false);
   1257   sP2pEnabled = false;
   1258   sDiscoveryEnabled = false;
   1259   // if nothing is active after this, then tell the controller to power down
   1260   if (!PowerSwitch::getInstance().setModeOff(PowerSwitch::DISCOVERY))
   1261     PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER);
   1262 TheEnd:
   1263   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1264 }
   1265 
   1266 void enableDisableLptd(bool enable) {
   1267   // This method is *NOT* thread-safe. Right now
   1268   // it is only called from the same thread so it's
   1269   // not an issue.
   1270   static bool sCheckedLptd = false;
   1271   static bool sHasLptd = false;
   1272 
   1273   tNFA_STATUS stat = NFA_STATUS_OK;
   1274   if (!sCheckedLptd) {
   1275     sCheckedLptd = true;
   1276     SyncEventGuard guard(sNfaGetConfigEvent);
   1277     tNFA_PMID configParam[1] = {NCI_PARAM_ID_TAGSNIFF_CFG};
   1278     stat = NFA_GetConfig(1, configParam);
   1279     if (stat != NFA_STATUS_OK) {
   1280       LOG(ERROR) << StringPrintf("%s: NFA_GetConfig failed", __func__);
   1281       return;
   1282     }
   1283     sNfaGetConfigEvent.wait();
   1284     if (sCurrentConfigLen < 4 || sConfig[1] != NCI_PARAM_ID_TAGSNIFF_CFG) {
   1285       LOG(ERROR) << StringPrintf(
   1286           "%s: Config TLV length %d returned is too short", __func__,
   1287           sCurrentConfigLen);
   1288       return;
   1289     }
   1290     if (sConfig[3] == 0) {
   1291       LOG(ERROR) << StringPrintf(
   1292           "%s: LPTD is disabled, not enabling in current config", __func__);
   1293       return;
   1294     }
   1295     sHasLptd = true;
   1296   }
   1297   // Bail if we checked and didn't find any LPTD config before
   1298   if (!sHasLptd) return;
   1299   uint8_t enable_byte = enable ? 0x01 : 0x00;
   1300 
   1301   SyncEventGuard guard(sNfaSetConfigEvent);
   1302 
   1303   stat = NFA_SetConfig(NCI_PARAM_ID_TAGSNIFF_CFG, 1, &enable_byte);
   1304   if (stat == NFA_STATUS_OK)
   1305     sNfaSetConfigEvent.wait();
   1306   else
   1307     LOG(ERROR) << StringPrintf("%s: Could not configure LPTD feature",
   1308                                __func__);
   1309   return;
   1310 }
   1311 
   1312 /*******************************************************************************
   1313 **
   1314 ** Function:        nfcManager_doCreateLlcpServiceSocket
   1315 **
   1316 ** Description:     Create a new LLCP server socket.
   1317 **                  e: JVM environment.
   1318 **                  o: Java object.
   1319 **                  nSap: Service access point.
   1320 **                  sn: Service name
   1321 **                  miu: Maximum information unit.
   1322 **                  rw: Receive window size.
   1323 **                  linearBufferLength: Max buffer size.
   1324 **
   1325 ** Returns:         NativeLlcpServiceSocket Java object.
   1326 **
   1327 *******************************************************************************/
   1328 static jobject nfcManager_doCreateLlcpServiceSocket(JNIEnv* e, jobject,
   1329                                                     jint nSap, jstring sn,
   1330                                                     jint miu, jint rw,
   1331                                                     jint linearBufferLength) {
   1332   PeerToPeer::tJNI_HANDLE jniHandle =
   1333       PeerToPeer::getInstance().getNewJniHandle();
   1334 
   1335   ScopedUtfChars serviceName(e, sn);
   1336 
   1337   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1338       "%s: enter: sap=%i; name=%s; miu=%i; rw=%i; buffLen=%i", __func__, nSap,
   1339       serviceName.c_str(), miu, rw, linearBufferLength);
   1340 
   1341   /* Create new NativeLlcpServiceSocket object */
   1342   jobject serviceSocket = NULL;
   1343   if (nfc_jni_cache_object_local(e, gNativeLlcpServiceSocketClassName,
   1344                                  &(serviceSocket)) == -1) {
   1345     LOG(ERROR) << StringPrintf("%s: Llcp socket object creation error",
   1346                                __func__);
   1347     return NULL;
   1348   }
   1349 
   1350   /* Get NativeLlcpServiceSocket class object */
   1351   ScopedLocalRef<jclass> clsNativeLlcpServiceSocket(
   1352       e, e->GetObjectClass(serviceSocket));
   1353   if (e->ExceptionCheck()) {
   1354     e->ExceptionClear();
   1355     LOG(ERROR) << StringPrintf("%s: Llcp Socket get object class error",
   1356                                __func__);
   1357     return NULL;
   1358   }
   1359 
   1360   if (!PeerToPeer::getInstance().registerServer(jniHandle,
   1361                                                 serviceName.c_str())) {
   1362     LOG(ERROR) << StringPrintf("%s: RegisterServer error", __func__);
   1363     return NULL;
   1364   }
   1365 
   1366   jfieldID f;
   1367 
   1368   /* Set socket handle to be the same as the NfaHandle*/
   1369   f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mHandle", "I");
   1370   e->SetIntField(serviceSocket, f, (jint)jniHandle);
   1371   DLOG_IF(INFO, nfc_debug_enabled)
   1372       << StringPrintf("%s: socket Handle = 0x%X", __func__, jniHandle);
   1373 
   1374   /* Set socket linear buffer length */
   1375   f = e->GetFieldID(clsNativeLlcpServiceSocket.get(),
   1376                     "mLocalLinearBufferLength", "I");
   1377   e->SetIntField(serviceSocket, f, (jint)linearBufferLength);
   1378   DLOG_IF(INFO, nfc_debug_enabled)
   1379       << StringPrintf("%s: buffer length = %d", __func__, linearBufferLength);
   1380 
   1381   /* Set socket MIU */
   1382   f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalMiu", "I");
   1383   e->SetIntField(serviceSocket, f, (jint)miu);
   1384   DLOG_IF(INFO, nfc_debug_enabled)
   1385       << StringPrintf("%s: MIU = %d", __func__, miu);
   1386 
   1387   /* Set socket RW */
   1388   f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalRw", "I");
   1389   e->SetIntField(serviceSocket, f, (jint)rw);
   1390   DLOG_IF(INFO, nfc_debug_enabled)
   1391       << StringPrintf("%s:  RW = %d", __func__, rw);
   1392 
   1393   sLastError = 0;
   1394   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1395   return serviceSocket;
   1396 }
   1397 
   1398 /*******************************************************************************
   1399 **
   1400 ** Function:        nfcManager_doGetLastError
   1401 **
   1402 ** Description:     Get the last error code.
   1403 **                  e: JVM environment.
   1404 **                  o: Java object.
   1405 **
   1406 ** Returns:         Last error code.
   1407 **
   1408 *******************************************************************************/
   1409 static jint nfcManager_doGetLastError(JNIEnv*, jobject) {
   1410   DLOG_IF(INFO, nfc_debug_enabled)
   1411       << StringPrintf("%s: last error=%i", __func__, sLastError);
   1412   return sLastError;
   1413 }
   1414 
   1415 /*******************************************************************************
   1416 **
   1417 ** Function:        nfcManager_doDeinitialize
   1418 **
   1419 ** Description:     Turn off NFC.
   1420 **                  e: JVM environment.
   1421 **                  o: Java object.
   1422 **
   1423 ** Returns:         True if ok.
   1424 **
   1425 *******************************************************************************/
   1426 static jboolean nfcManager_doDeinitialize(JNIEnv*, jobject) {
   1427   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
   1428 
   1429   sIsDisabling = true;
   1430 
   1431   pn544InteropAbortNow();
   1432   RoutingManager::getInstance().onNfccShutdown();
   1433   PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
   1434   HciEventManager::getInstance().finalize();
   1435 
   1436   if (sIsNfaEnabled) {
   1437     SyncEventGuard guard(sNfaDisableEvent);
   1438     EXTNS_Close();
   1439     tNFA_STATUS stat = NFA_Disable(TRUE /* graceful */);
   1440     if (stat == NFA_STATUS_OK) {
   1441       DLOG_IF(INFO, nfc_debug_enabled)
   1442           << StringPrintf("%s: wait for completion", __func__);
   1443       sNfaDisableEvent.wait();  // wait for NFA command to finish
   1444       PeerToPeer::getInstance().handleNfcOnOff(false);
   1445     } else {
   1446       LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__,
   1447                                  stat);
   1448     }
   1449   }
   1450   nativeNfcTag_abortWaits();
   1451   NfcTag::getInstance().abort();
   1452   sAbortConnlessWait = true;
   1453   nativeLlcpConnectionlessSocket_abortWait();
   1454   sIsNfaEnabled = false;
   1455   sDiscoveryEnabled = false;
   1456   sPollingEnabled = false;
   1457   sIsDisabling = false;
   1458   sP2pEnabled = false;
   1459   gActivated = false;
   1460   sLfT3tMax = 0;
   1461 
   1462   {
   1463     // unblock NFA_EnablePolling() and NFA_DisablePolling()
   1464     SyncEventGuard guard(sNfaEnableDisablePollingEvent);
   1465     sNfaEnableDisablePollingEvent.notifyOne();
   1466   }
   1467 
   1468   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1469   theInstance.Finalize();
   1470 
   1471   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1472   return JNI_TRUE;
   1473 }
   1474 
   1475 /*******************************************************************************
   1476 **
   1477 ** Function:        nfcManager_doCreateLlcpSocket
   1478 **
   1479 ** Description:     Create a LLCP connection-oriented socket.
   1480 **                  e: JVM environment.
   1481 **                  o: Java object.
   1482 **                  nSap: Service access point.
   1483 **                  miu: Maximum information unit.
   1484 **                  rw: Receive window size.
   1485 **                  linearBufferLength: Max buffer size.
   1486 **
   1487 ** Returns:         NativeLlcpSocket Java object.
   1488 **
   1489 *******************************************************************************/
   1490 static jobject nfcManager_doCreateLlcpSocket(JNIEnv* e, jobject, jint nSap,
   1491                                              jint miu, jint rw,
   1492                                              jint linearBufferLength) {
   1493   DLOG_IF(INFO, nfc_debug_enabled)
   1494       << StringPrintf("%s: enter; sap=%d; miu=%d; rw=%d; buffer len=%d",
   1495                       __func__, nSap, miu, rw, linearBufferLength);
   1496 
   1497   PeerToPeer::tJNI_HANDLE jniHandle =
   1498       PeerToPeer::getInstance().getNewJniHandle();
   1499   PeerToPeer::getInstance().createClient(jniHandle, miu, rw);
   1500 
   1501   /* Create new NativeLlcpSocket object */
   1502   jobject clientSocket = NULL;
   1503   if (nfc_jni_cache_object_local(e, gNativeLlcpSocketClassName,
   1504                                  &(clientSocket)) == -1) {
   1505     LOG(ERROR) << StringPrintf("%s: fail Llcp socket creation", __func__);
   1506     return clientSocket;
   1507   }
   1508 
   1509   /* Get NativeConnectionless class object */
   1510   ScopedLocalRef<jclass> clsNativeLlcpSocket(e,
   1511                                              e->GetObjectClass(clientSocket));
   1512   if (e->ExceptionCheck()) {
   1513     e->ExceptionClear();
   1514     LOG(ERROR) << StringPrintf("%s: fail get class object", __func__);
   1515     return clientSocket;
   1516   }
   1517 
   1518   jfieldID f;
   1519 
   1520   /* Set socket SAP */
   1521   f = e->GetFieldID(clsNativeLlcpSocket.get(), "mSap", "I");
   1522   e->SetIntField(clientSocket, f, (jint)nSap);
   1523 
   1524   /* Set socket handle */
   1525   f = e->GetFieldID(clsNativeLlcpSocket.get(), "mHandle", "I");
   1526   e->SetIntField(clientSocket, f, (jint)jniHandle);
   1527 
   1528   /* Set socket MIU */
   1529   f = e->GetFieldID(clsNativeLlcpSocket.get(), "mLocalMiu", "I");
   1530   e->SetIntField(clientSocket, f, (jint)miu);
   1531 
   1532   /* Set socket RW */
   1533   f = e->GetFieldID(clsNativeLlcpSocket.get(), "mLocalRw", "I");
   1534   e->SetIntField(clientSocket, f, (jint)rw);
   1535 
   1536   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1537   return clientSocket;
   1538 }
   1539 
   1540 /*******************************************************************************
   1541 **
   1542 ** Function:        nfcManager_doCreateLlcpConnectionlessSocket
   1543 **
   1544 ** Description:     Create a connection-less socket.
   1545 **                  e: JVM environment.
   1546 **                  o: Java object.
   1547 **                  nSap: Service access point.
   1548 **                  sn: Service name.
   1549 **
   1550 ** Returns:         NativeLlcpConnectionlessSocket Java object.
   1551 **
   1552 *******************************************************************************/
   1553 static jobject nfcManager_doCreateLlcpConnectionlessSocket(JNIEnv*, jobject,
   1554                                                            jint nSap,
   1555                                                            jstring /*sn*/) {
   1556   DLOG_IF(INFO, nfc_debug_enabled)
   1557       << StringPrintf("%s: nSap=0x%X", __func__, nSap);
   1558   return NULL;
   1559 }
   1560 
   1561 /*******************************************************************************
   1562 **
   1563 ** Function:        isPeerToPeer
   1564 **
   1565 ** Description:     Whether the activation data indicates the peer supports
   1566 *NFC-DEP.
   1567 **                  activated: Activation data.
   1568 **
   1569 ** Returns:         True if the peer supports NFC-DEP.
   1570 **
   1571 *******************************************************************************/
   1572 static bool isPeerToPeer(tNFA_ACTIVATED& activated) {
   1573   return activated.activate_ntf.protocol == NFA_PROTOCOL_NFC_DEP;
   1574 }
   1575 
   1576 /*******************************************************************************
   1577 **
   1578 ** Function:        isListenMode
   1579 **
   1580 ** Description:     Indicates whether the activation data indicates it is
   1581 **                  listen mode.
   1582 **
   1583 ** Returns:         True if this listen mode.
   1584 **
   1585 *******************************************************************************/
   1586 static bool isListenMode(tNFA_ACTIVATED& activated) {
   1587   return ((NFC_DISCOVERY_TYPE_LISTEN_A ==
   1588            activated.activate_ntf.rf_tech_param.mode) ||
   1589           (NFC_DISCOVERY_TYPE_LISTEN_B ==
   1590            activated.activate_ntf.rf_tech_param.mode) ||
   1591           (NFC_DISCOVERY_TYPE_LISTEN_F ==
   1592            activated.activate_ntf.rf_tech_param.mode) ||
   1593           (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE ==
   1594            activated.activate_ntf.rf_tech_param.mode) ||
   1595           (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE ==
   1596            activated.activate_ntf.rf_tech_param.mode) ||
   1597           (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 ==
   1598            activated.activate_ntf.rf_tech_param.mode) ||
   1599           (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME ==
   1600            activated.activate_ntf.rf_tech_param.mode));
   1601 }
   1602 
   1603 /*******************************************************************************
   1604 **
   1605 ** Function:        nfcManager_doCheckLlcp
   1606 **
   1607 ** Description:     Not used.
   1608 **
   1609 ** Returns:         True
   1610 **
   1611 *******************************************************************************/
   1612 static jboolean nfcManager_doCheckLlcp(JNIEnv*, jobject) {
   1613   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
   1614   return JNI_TRUE;
   1615 }
   1616 
   1617 /*******************************************************************************
   1618 **
   1619 ** Function:        nfcManager_doActivateLlcp
   1620 **
   1621 ** Description:     Not used.
   1622 **
   1623 ** Returns:         True
   1624 **
   1625 *******************************************************************************/
   1626 static jboolean nfcManager_doActivateLlcp(JNIEnv*, jobject) {
   1627   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
   1628   return JNI_TRUE;
   1629 }
   1630 
   1631 /*******************************************************************************
   1632 **
   1633 ** Function:        nfcManager_doAbort
   1634 **
   1635 ** Description:     Not used.
   1636 **
   1637 ** Returns:         None
   1638 **
   1639 *******************************************************************************/
   1640 static void nfcManager_doAbort(JNIEnv* e, jobject, jstring msg) {
   1641   ScopedUtfChars message = {e, msg};
   1642   e->FatalError(message.c_str());
   1643   abort();  // <-- Unreachable
   1644 }
   1645 
   1646 /*******************************************************************************
   1647 **
   1648 ** Function:        nfcManager_doDownload
   1649 **
   1650 ** Description:     Download firmware patch files.  Do not turn on NFC.
   1651 **
   1652 ** Returns:         True if ok.
   1653 **
   1654 *******************************************************************************/
   1655 static jboolean nfcManager_doDownload(JNIEnv*, jobject) {
   1656   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
   1657   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1658 
   1659   theInstance.Initialize();  // start GKI, NCI task, NFC task
   1660   theInstance.DownloadFirmware();
   1661   theInstance.Finalize();
   1662   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   1663   return JNI_TRUE;
   1664 }
   1665 
   1666 /*******************************************************************************
   1667 **
   1668 ** Function:        nfcManager_doResetTimeouts
   1669 **
   1670 ** Description:     Not used.
   1671 **
   1672 ** Returns:         None
   1673 **
   1674 *******************************************************************************/
   1675 static void nfcManager_doResetTimeouts(JNIEnv*, jobject) {
   1676   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
   1677   NfcTag::getInstance().resetAllTransceiveTimeouts();
   1678 }
   1679 
   1680 /*******************************************************************************
   1681 **
   1682 ** Function:        nfcManager_doSetTimeout
   1683 **
   1684 ** Description:     Set timeout value.
   1685 **                  e: JVM environment.
   1686 **                  o: Java object.
   1687 **                  tech: technology ID.
   1688 **                  timeout: Timeout value.
   1689 **
   1690 ** Returns:         True if ok.
   1691 **
   1692 *******************************************************************************/
   1693 static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint tech, jint timeout) {
   1694   if (timeout <= 0) {
   1695     LOG(ERROR) << StringPrintf("%s: Timeout must be positive.", __func__);
   1696     return false;
   1697   }
   1698   DLOG_IF(INFO, nfc_debug_enabled)
   1699       << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech, timeout);
   1700   NfcTag::getInstance().setTransceiveTimeout(tech, timeout);
   1701   return true;
   1702 }
   1703 
   1704 /*******************************************************************************
   1705 **
   1706 ** Function:        nfcManager_doGetTimeout
   1707 **
   1708 ** Description:     Get timeout value.
   1709 **                  e: JVM environment.
   1710 **                  o: Java object.
   1711 **                  tech: technology ID.
   1712 **
   1713 ** Returns:         Timeout value.
   1714 **
   1715 *******************************************************************************/
   1716 static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint tech) {
   1717   int timeout = NfcTag::getInstance().getTransceiveTimeout(tech);
   1718   DLOG_IF(INFO, nfc_debug_enabled)
   1719       << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech, timeout);
   1720   return timeout;
   1721 }
   1722 
   1723 /*******************************************************************************
   1724 **
   1725 ** Function:        nfcManager_doDump
   1726 **
   1727 ** Description:     Get libnfc-nci dump
   1728 **                  e: JVM environment.
   1729 **                  obj: Java object.
   1730 **                  fdobj: File descriptor to be used
   1731 **
   1732 ** Returns:         Void
   1733 **
   1734 *******************************************************************************/
   1735 static void nfcManager_doDump(JNIEnv* e, jobject obj, jobject fdobj) {
   1736   int fd = jniGetFDFromFileDescriptor(e, fdobj);
   1737   if (fd < 0) return;
   1738 
   1739   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
   1740   theInstance.Dump(fd);
   1741 }
   1742 
   1743 static jint nfcManager_doGetNciVersion(JNIEnv*, jobject) {
   1744   return NFC_GetNCIVersion();
   1745 }
   1746 
   1747 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
   1748                                         jint screen_state_mask) {
   1749   tNFA_STATUS status = NFA_STATUS_OK;
   1750   uint8_t state = (screen_state_mask & NFA_SCREEN_STATE_MASK);
   1751   uint8_t discovry_param =
   1752       NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
   1753 
   1754   DLOG_IF(INFO, nfc_debug_enabled)
   1755       << StringPrintf("%s: state = %d prevScreenState= %d, discovry_param = %d",
   1756                       __FUNCTION__, state, prevScreenState, discovry_param);
   1757 
   1758   if (sIsDisabling || !sIsNfaEnabled ||
   1759       (NFC_GetNCIVersion() != NCI_VERSION_2_0))
   1760     return;
   1761   if (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED ||
   1762       prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED ||
   1763       prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) {
   1764     SyncEventGuard guard(sNfaSetPowerSubState);
   1765     status = NFA_SetPowerSubStateForScreenState(state);
   1766     if (status != NFA_STATUS_OK) {
   1767       LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
   1768                                  __FUNCTION__, status);
   1769       return;
   1770     } else {
   1771       sNfaSetPowerSubState.wait();
   1772     }
   1773   }
   1774 
   1775   if (state == NFA_SCREEN_STATE_OFF_LOCKED ||
   1776       state == NFA_SCREEN_STATE_OFF_UNLOCKED) {
   1777     // disable both poll and listen on DH 0x02
   1778     discovry_param =
   1779         NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_DISABLE_MASK;
   1780   }
   1781 
   1782   if (state == NFA_SCREEN_STATE_ON_LOCKED) {
   1783     // disable poll and enable listen on DH 0x00
   1784     discovry_param =
   1785         (screen_state_mask & NFA_SCREEN_POLLING_TAG_MASK)
   1786             ? (NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK)
   1787             : (NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_ENABLE_MASK);
   1788   }
   1789 
   1790   if (state == NFA_SCREEN_STATE_ON_UNLOCKED) {
   1791     // enable both poll and listen on DH 0x01
   1792     discovry_param =
   1793         NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
   1794   }
   1795 
   1796   SyncEventGuard guard(sNfaSetConfigEvent);
   1797   status = NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM,
   1798                          NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param);
   1799   if (status == NFA_STATUS_OK) {
   1800     sNfaSetConfigEvent.wait();
   1801   } else {
   1802     LOG(ERROR) << StringPrintf("%s: Failed to update CON_DISCOVER_PARAM",
   1803                                __FUNCTION__);
   1804     return;
   1805   }
   1806 
   1807   if (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) {
   1808     SyncEventGuard guard(sNfaSetPowerSubState);
   1809     status = NFA_SetPowerSubStateForScreenState(state);
   1810     if (status != NFA_STATUS_OK) {
   1811       LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
   1812                                  __FUNCTION__, status);
   1813     } else {
   1814       sNfaSetPowerSubState.wait();
   1815     }
   1816   }
   1817   if ((state == NFA_SCREEN_STATE_OFF_LOCKED ||
   1818        state == NFA_SCREEN_STATE_OFF_UNLOCKED) &&
   1819       prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) {
   1820     // screen turns off, disconnect tag if connected
   1821     nativeNfcTag_doDisconnect(NULL, NULL);
   1822   }
   1823 
   1824   prevScreenState = state;
   1825 }
   1826 /*******************************************************************************
   1827 **
   1828 ** Function:        nfcManager_doSetP2pInitiatorModes
   1829 **
   1830 ** Description:     Set P2P initiator's activation modes.
   1831 **                  e: JVM environment.
   1832 **                  o: Java object.
   1833 **                  modes: Active and/or passive modes.  The values are
   1834 *specified
   1835 **                          in external/libnfc-nxp/inc/phNfcTypes.h.  See
   1836 **                          enum phNfc_eP2PMode_t.
   1837 **
   1838 ** Returns:         None.
   1839 **
   1840 *******************************************************************************/
   1841 static void nfcManager_doSetP2pInitiatorModes(JNIEnv* e, jobject o,
   1842                                               jint modes) {
   1843   DLOG_IF(INFO, nfc_debug_enabled)
   1844       << StringPrintf("%s: modes=0x%X", __func__, modes);
   1845   struct nfc_jni_native_data* nat = getNative(e, o);
   1846 
   1847   tNFA_TECHNOLOGY_MASK mask = 0;
   1848   if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A;
   1849   if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F;
   1850   if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F;
   1851   if (modes & 0x08) mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE;
   1852   if (modes & 0x10) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE;
   1853   if (modes & 0x20) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE;
   1854   nat->tech_mask = mask;
   1855 }
   1856 
   1857 /*******************************************************************************
   1858 **
   1859 ** Function:        nfcManager_doSetP2pTargetModes
   1860 **
   1861 ** Description:     Set P2P target's activation modes.
   1862 **                  e: JVM environment.
   1863 **                  o: Java object.
   1864 **                  modes: Active and/or passive modes.
   1865 **
   1866 ** Returns:         None.
   1867 **
   1868 *******************************************************************************/
   1869 static void nfcManager_doSetP2pTargetModes(JNIEnv*, jobject, jint modes) {
   1870   DLOG_IF(INFO, nfc_debug_enabled)
   1871       << StringPrintf("%s: modes=0x%X", __func__, modes);
   1872   // Map in the right modes
   1873   tNFA_TECHNOLOGY_MASK mask = 0;
   1874   if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A;
   1875   if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F;
   1876   if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F;
   1877   if (modes & 0x08)
   1878     mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE;
   1879 
   1880   PeerToPeer::getInstance().setP2pListenMask(mask);
   1881 }
   1882 
   1883 static void nfcManager_doEnableScreenOffSuspend(JNIEnv* e, jobject o) {
   1884   PowerSwitch::getInstance().setScreenOffPowerState(
   1885       PowerSwitch::POWER_STATE_FULL);
   1886 }
   1887 
   1888 static void nfcManager_doDisableScreenOffSuspend(JNIEnv* e, jobject o) {
   1889   PowerSwitch::getInstance().setScreenOffPowerState(
   1890       PowerSwitch::POWER_STATE_OFF);
   1891 }
   1892 
   1893 /*******************************************************************************
   1894 **
   1895 ** Function:        nfcManager_getIsoDepMaxTransceiveLength
   1896 **
   1897 ** Description:     Get maximum ISO DEP Transceive Length supported by the NFC
   1898 **                  chip. Returns default 261 bytes if the property is not set.
   1899 **
   1900 ** Returns:         max value.
   1901 **
   1902 *******************************************************************************/
   1903 static jint nfcManager_getIsoDepMaxTransceiveLength(JNIEnv*, jobject) {
   1904   /* Check if extended APDU is supported by the chip.
   1905    * If not, default value is returned.
   1906    * The maximum length of a default IsoDep frame consists of:
   1907    * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
   1908    */
   1909   return NfcConfig::getUnsigned(NAME_ISO_DEP_MAX_TRANSCEIVE, 261);
   1910 }
   1911 
   1912 /*****************************************************************************
   1913 **
   1914 ** JNI functions for android-4.0.1_r1
   1915 **
   1916 *****************************************************************************/
   1917 static JNINativeMethod gMethods[] = {
   1918     {"doDownload", "()Z", (void*)nfcManager_doDownload},
   1919 
   1920     {"initializeNativeStructure", "()Z", (void*)nfcManager_initNativeStruc},
   1921 
   1922     {"doInitialize", "()Z", (void*)nfcManager_doInitialize},
   1923 
   1924     {"doDeinitialize", "()Z", (void*)nfcManager_doDeinitialize},
   1925 
   1926     {"sendRawFrame", "([B)Z", (void*)nfcManager_sendRawFrame},
   1927 
   1928     {"routeAid", "([BII)Z", (void*)nfcManager_routeAid},
   1929 
   1930     {"unrouteAid", "([B)Z", (void*)nfcManager_unrouteAid},
   1931 
   1932     {"commitRouting", "()Z", (void*)nfcManager_commitRouting},
   1933 
   1934     {"doRegisterT3tIdentifier", "([B)I",
   1935      (void*)nfcManager_doRegisterT3tIdentifier},
   1936 
   1937     {"doDeregisterT3tIdentifier", "(I)V",
   1938      (void*)nfcManager_doDeregisterT3tIdentifier},
   1939 
   1940     {"getLfT3tMax", "()I", (void*)nfcManager_getLfT3tMax},
   1941 
   1942     {"doEnableDiscovery", "(IZZZZZ)V", (void*)nfcManager_enableDiscovery},
   1943 
   1944     {"doCheckLlcp", "()Z", (void*)nfcManager_doCheckLlcp},
   1945 
   1946     {"doActivateLlcp", "()Z", (void*)nfcManager_doActivateLlcp},
   1947 
   1948     {"doCreateLlcpConnectionlessSocket",
   1949      "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/"
   1950      "NativeLlcpConnectionlessSocket;",
   1951      (void*)nfcManager_doCreateLlcpConnectionlessSocket},
   1952 
   1953     {"doCreateLlcpServiceSocket",
   1954      "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
   1955      (void*)nfcManager_doCreateLlcpServiceSocket},
   1956 
   1957     {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
   1958      (void*)nfcManager_doCreateLlcpSocket},
   1959 
   1960     {"doGetLastError", "()I", (void*)nfcManager_doGetLastError},
   1961 
   1962     {"disableDiscovery", "()V", (void*)nfcManager_disableDiscovery},
   1963 
   1964     {"doSetTimeout", "(II)Z", (void*)nfcManager_doSetTimeout},
   1965 
   1966     {"doGetTimeout", "(I)I", (void*)nfcManager_doGetTimeout},
   1967 
   1968     {"doResetTimeouts", "()V", (void*)nfcManager_doResetTimeouts},
   1969 
   1970     {"doAbort", "(Ljava/lang/String;)V", (void*)nfcManager_doAbort},
   1971 
   1972     {"doSetP2pInitiatorModes", "(I)V",
   1973      (void*)nfcManager_doSetP2pInitiatorModes},
   1974 
   1975     {"doSetP2pTargetModes", "(I)V", (void*)nfcManager_doSetP2pTargetModes},
   1976 
   1977     {"doEnableScreenOffSuspend", "()V",
   1978      (void*)nfcManager_doEnableScreenOffSuspend},
   1979 
   1980     {"doSetScreenState", "(I)V", (void*)nfcManager_doSetScreenState},
   1981 
   1982     {"doDisableScreenOffSuspend", "()V",
   1983      (void*)nfcManager_doDisableScreenOffSuspend},
   1984 
   1985     {"doDump", "(Ljava/io/FileDescriptor;)V", (void*)nfcManager_doDump},
   1986 
   1987     {"getNciVersion", "()I", (void*)nfcManager_doGetNciVersion},
   1988     {"doEnableDtaMode", "()V", (void*)nfcManager_doEnableDtaMode},
   1989     {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode},
   1990     {"doFactoryReset", "()V", (void*)nfcManager_doFactoryReset},
   1991     {"doShutdown", "()V", (void*)nfcManager_doShutdown},
   1992 
   1993     {"getIsoDepMaxTransceiveLength", "()I",
   1994      (void*)nfcManager_getIsoDepMaxTransceiveLength}
   1995 
   1996 };
   1997 
   1998 /*******************************************************************************
   1999 **
   2000 ** Function:        register_com_android_nfc_NativeNfcManager
   2001 **
   2002 ** Description:     Regisgter JNI functions with Java Virtual Machine.
   2003 **                  e: Environment of JVM.
   2004 **
   2005 ** Returns:         Status of registration.
   2006 **
   2007 *******************************************************************************/
   2008 int register_com_android_nfc_NativeNfcManager(JNIEnv* e) {
   2009   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
   2010   PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
   2011   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   2012   return jniRegisterNativeMethods(e, gNativeNfcManagerClassName, gMethods,
   2013                                   NELEM(gMethods));
   2014 }
   2015 
   2016 /*******************************************************************************
   2017 **
   2018 ** Function:        startRfDiscovery
   2019 **
   2020 ** Description:     Ask stack to start polling and listening for devices.
   2021 **                  isStart: Whether to start.
   2022 **
   2023 ** Returns:         None
   2024 **
   2025 *******************************************************************************/
   2026 void startRfDiscovery(bool isStart) {
   2027   tNFA_STATUS status = NFA_STATUS_FAILED;
   2028 
   2029   DLOG_IF(INFO, nfc_debug_enabled)
   2030       << StringPrintf("%s: is start=%d", __func__, isStart);
   2031   nativeNfcTag_acquireRfInterfaceMutexLock();
   2032   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
   2033   status = isStart ? NFA_StartRfDiscovery() : NFA_StopRfDiscovery();
   2034   if (status == NFA_STATUS_OK) {
   2035     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_RF_DISCOVERY_xxxx_EVT
   2036     sRfEnabled = isStart;
   2037   } else {
   2038     LOG(ERROR) << StringPrintf(
   2039         "%s: Failed to start/stop RF discovery; error=0x%X", __func__, status);
   2040   }
   2041   nativeNfcTag_releaseRfInterfaceMutexLock();
   2042 }
   2043 
   2044 /*******************************************************************************
   2045 **
   2046 ** Function:        isDiscoveryStarted
   2047 **
   2048 ** Description:     Indicates whether the discovery is started.
   2049 **
   2050 ** Returns:         True if discovery is started
   2051 **
   2052 *******************************************************************************/
   2053 bool isDiscoveryStarted() { return sRfEnabled; }
   2054 
   2055 /*******************************************************************************
   2056 **
   2057 ** Function:        doStartupConfig
   2058 **
   2059 ** Description:     Configure the NFC controller.
   2060 **
   2061 ** Returns:         None
   2062 **
   2063 *******************************************************************************/
   2064 void doStartupConfig() {
   2065   struct nfc_jni_native_data* nat = getNative(0, 0);
   2066   tNFA_STATUS stat = NFA_STATUS_FAILED;
   2067 
   2068   // If polling for Active mode, set the ordering so that we choose Active over
   2069   // Passive mode first.
   2070   if (nat && (nat->tech_mask &
   2071               (NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE))) {
   2072     uint8_t act_mode_order_param[] = {0x01};
   2073     SyncEventGuard guard(sNfaSetConfigEvent);
   2074     stat = NFA_SetConfig(NCI_PARAM_ID_ACT_ORDER, sizeof(act_mode_order_param),
   2075                          &act_mode_order_param[0]);
   2076     if (stat == NFA_STATUS_OK) sNfaSetConfigEvent.wait();
   2077   }
   2078 
   2079   // configure RF polling frequency for each technology
   2080   static tNFA_DM_DISC_FREQ_CFG nfa_dm_disc_freq_cfg;
   2081   // values in the polling_frequency[] map to members of nfa_dm_disc_freq_cfg
   2082   std::vector<uint8_t> polling_frequency;
   2083   if (NfcConfig::hasKey(NAME_POLL_FREQUENCY))
   2084     polling_frequency = NfcConfig::getBytes(NAME_POLL_FREQUENCY);
   2085   if (polling_frequency.size() == 8) {
   2086     DLOG_IF(INFO, nfc_debug_enabled)
   2087         << StringPrintf("%s: polling frequency", __func__);
   2088     memset(&nfa_dm_disc_freq_cfg, 0, sizeof(nfa_dm_disc_freq_cfg));
   2089     nfa_dm_disc_freq_cfg.pa = polling_frequency[0];
   2090     nfa_dm_disc_freq_cfg.pb = polling_frequency[1];
   2091     nfa_dm_disc_freq_cfg.pf = polling_frequency[2];
   2092     nfa_dm_disc_freq_cfg.pi93 = polling_frequency[3];
   2093     nfa_dm_disc_freq_cfg.pbp = polling_frequency[4];
   2094     nfa_dm_disc_freq_cfg.pk = polling_frequency[5];
   2095     nfa_dm_disc_freq_cfg.paa = polling_frequency[6];
   2096     nfa_dm_disc_freq_cfg.pfa = polling_frequency[7];
   2097     p_nfa_dm_rf_disc_freq_cfg = &nfa_dm_disc_freq_cfg;
   2098   }
   2099 }
   2100 
   2101 /*******************************************************************************
   2102 **
   2103 ** Function:        nfcManager_isNfcActive
   2104 **
   2105 ** Description:     Used externaly to determine if NFC is active or not.
   2106 **
   2107 ** Returns:         'true' if the NFC stack is running, else 'false'.
   2108 **
   2109 *******************************************************************************/
   2110 bool nfcManager_isNfcActive() { return sIsNfaEnabled; }
   2111 
   2112 /*******************************************************************************
   2113 **
   2114 ** Function:        startStopPolling
   2115 **
   2116 ** Description:     Start or stop polling.
   2117 **                  isStartPolling: true to start polling; false to stop
   2118 *polling.
   2119 **
   2120 ** Returns:         None.
   2121 **
   2122 *******************************************************************************/
   2123 void startStopPolling(bool isStartPolling) {
   2124   DLOG_IF(INFO, nfc_debug_enabled)
   2125       << StringPrintf("%s: enter; isStart=%u", __func__, isStartPolling);
   2126   startRfDiscovery(false);
   2127 
   2128   if (isStartPolling)
   2129     startPolling_rfDiscoveryDisabled(0);
   2130   else
   2131     stopPolling_rfDiscoveryDisabled();
   2132 
   2133   startRfDiscovery(true);
   2134   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
   2135 }
   2136 
   2137 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
   2138     tNFA_TECHNOLOGY_MASK tech_mask) {
   2139   tNFA_STATUS stat = NFA_STATUS_FAILED;
   2140 
   2141   if (tech_mask == 0)
   2142     tech_mask =
   2143         NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
   2144 
   2145   nativeNfcTag_acquireRfInterfaceMutexLock();
   2146   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
   2147   DLOG_IF(INFO, nfc_debug_enabled)
   2148       << StringPrintf("%s: enable polling", __func__);
   2149   stat = NFA_EnablePolling(tech_mask);
   2150   if (stat == NFA_STATUS_OK) {
   2151     DLOG_IF(INFO, nfc_debug_enabled)
   2152         << StringPrintf("%s: wait for enable event", __func__);
   2153     sPollingEnabled = true;
   2154     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_POLL_ENABLED_EVT
   2155   } else {
   2156     LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", __func__,
   2157                                stat);
   2158   }
   2159   nativeNfcTag_releaseRfInterfaceMutexLock();
   2160 
   2161   return stat;
   2162 }
   2163 
   2164 static tNFA_STATUS stopPolling_rfDiscoveryDisabled() {
   2165   tNFA_STATUS stat = NFA_STATUS_FAILED;
   2166 
   2167   nativeNfcTag_acquireRfInterfaceMutexLock();
   2168   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
   2169   DLOG_IF(INFO, nfc_debug_enabled)
   2170       << StringPrintf("%s: disable polling", __func__);
   2171   stat = NFA_DisablePolling();
   2172   if (stat == NFA_STATUS_OK) {
   2173     sPollingEnabled = false;
   2174     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_POLL_DISABLED_EVT
   2175   } else {
   2176     LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
   2177                                stat);
   2178   }
   2179   nativeNfcTag_releaseRfInterfaceMutexLock();
   2180 
   2181   return stat;
   2182 }
   2183 
   2184 } /* namespace android */
   2185