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/logging.h>
18 #include <android-base/stringprintf.h>
19 #include <cutils/properties.h>
20 #include <errno.h>
21 #include <nativehelper/JNIPlatformHelp.h>
22 #include <nativehelper/ScopedLocalRef.h>
23 #include <nativehelper/ScopedPrimitiveArray.h>
24 #include <nativehelper/ScopedUtfChars.h>
25 #include <semaphore.h>
26 
27 #include "HciEventManager.h"
28 #include "JavaClassConstants.h"
29 #include "NativeWlcManager.h"
30 #include "NfcAdaptation.h"
31 #ifdef DTA_ENABLED
32 #include "NfcDta.h"
33 #endif /* DTA_ENABLED */
34 #include "NativeT4tNfcee.h"
35 #include "NfcJniUtil.h"
36 #include "NfcTag.h"
37 #include "NfceeManager.h"
38 #include "PowerSwitch.h"
39 #include "RoutingManager.h"
40 #include "SyncEvent.h"
41 #include "android_nfc.h"
42 #include "ce_api.h"
43 #include "debug_lmrt.h"
44 #include "nfa_api.h"
45 #include "nfa_ee_api.h"
46 #include "nfa_nfcee_int.h"
47 #include "nfc_brcm_defs.h"
48 #include "nfc_config.h"
49 #include "rw_api.h"
50 
51 using android::base::StringPrintf;
52 
53 extern tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg;  // defined in stack
54 namespace android {
55 extern bool gIsTagDeactivating;
56 extern bool gIsSelectingRfInterface;
57 extern bool gTagJustActivated;
58 extern void nativeNfcTag_doTransceiveStatus(tNFA_STATUS status, uint8_t* buf,
59                                             uint32_t buflen);
60 extern void nativeNfcTag_notifyRfTimeout();
61 extern void nativeNfcTag_doConnectStatus(jboolean is_connect_ok);
62 extern void nativeNfcTag_doDeactivateStatus(int status);
63 extern void nativeNfcTag_doWriteStatus(jboolean is_write_ok);
64 extern jboolean nativeNfcTag_doDisconnect(JNIEnv*, jobject);
65 extern void nativeNfcTag_doCheckNdefResult(tNFA_STATUS status,
66                                            uint32_t max_size,
67                                            uint32_t current_size,
68                                            uint8_t flags);
69 extern void nativeNfcTag_doMakeReadonlyResult(tNFA_STATUS status);
70 extern void nativeNfcTag_doPresenceCheckResult(tNFA_STATUS status);
71 extern void nativeNfcTag_formatStatus(bool is_ok);
72 extern void nativeNfcTag_resetPresenceCheck();
73 extern void nativeNfcTag_doReadCompleted(tNFA_STATUS status);
74 extern void nativeNfcTag_setRfInterface(tNFA_INTF_TYPE rfInterface);
75 extern void nativeNfcTag_setActivatedRfProtocol(tNFA_INTF_TYPE rfProtocol);
76 extern void nativeNfcTag_setActivatedRfMode(uint8_t rfMode);
77 extern void nativeNfcTag_abortWaits();
78 extern void nativeNfcTag_registerNdefTypeHandler();
79 extern void nativeNfcTag_acquireRfInterfaceMutexLock();
80 extern void nativeNfcTag_releaseRfInterfaceMutexLock();
81 extern void updateNfcID0Param(uint8_t* nfcID0);
82 }  // namespace android
83 
84 /*****************************************************************************
85 **
86 ** public variables and functions
87 **
88 *****************************************************************************/
89 bool gActivated = false;
90 SyncEvent gDeactivatedEvent;
91 SyncEvent sNfaSetPowerSubState;
92 int recovery_option = 0;
93 int always_on_nfcee_power_and_link_conf = 0;
94 int disable_always_on_nfcee_power_and_link_conf = 0;
95 
96 namespace android {
97 jmethodID gCachedNfcManagerNotifyNdefMessageListeners;
98 jmethodID gCachedNfcManagerNotifyTransactionListeners;
99 jmethodID gCachedNfcManagerNotifyHostEmuActivated;
100 jmethodID gCachedNfcManagerNotifyHostEmuData;
101 jmethodID gCachedNfcManagerNotifyHostEmuDeactivated;
102 jmethodID gCachedNfcManagerNotifyRfFieldActivated;
103 jmethodID gCachedNfcManagerNotifyRfFieldDeactivated;
104 jmethodID gCachedNfcManagerNotifyEeUpdated;
105 jmethodID gCachedNfcManagerNotifyTagDiscovered;
106 jmethodID gCachedNfcManagerNotifyHwErrorReported;
107 jmethodID gCachedNfcManagerNotifyPollingLoopFrame;
108 jmethodID gCachedNfcManagerNotifyWlcStopped;
109 jmethodID gCachedNfcManagerNotifyVendorSpecificEvent;
110 jmethodID gCachedNfcManagerNotifyCommandTimeout;
111 jmethodID gCachedNfcManagerNotifyObserveModeChanged;
112 jmethodID gCachedNfcManagerNotifyRfDiscoveryEvent;
113 jmethodID gCachedNfcManagerNotifyEeAidSelected;
114 jmethodID gCachedNfcManagerNotifyEeProtocolSelected;
115 jmethodID gCachedNfcManagerNotifyEeTechSelected;
116 jmethodID gCachedNfcManagerNotifyEeListenActivated;
117 const char* gNativeNfcTagClassName = "com/android/nfc/dhimpl/NativeNfcTag";
118 const char* gNativeNfcManagerClassName =
119     "com/android/nfc/dhimpl/NativeNfcManager";
120 const char* gNfcVendorNciResponseClassName =
121     "com/android/nfc/NfcVendorNciResponse";
122 const char* gNativeT4tNfceeClassName =
123     "com/android/nfc/dhimpl/NativeT4tNfceeManager";
124 void doStartupConfig();
125 void startStopPolling(bool isStartPolling);
126 void startRfDiscovery(bool isStart);
127 bool isDiscoveryStarted();
128 }  // namespace android
129 
130 /*****************************************************************************
131 **
132 ** private variables and functions
133 **
134 *****************************************************************************/
135 namespace android {
136 static SyncEvent sNfaEnableEvent;                // event for NFA_Enable()
137 static SyncEvent sNfaDisableEvent;               // event for NFA_Disable()
138 static SyncEvent sNfaEnableDisablePollingEvent;  // event for
139                                                  // NFA_EnablePolling(),
140                                                  // NFA_DisablePolling()
141 SyncEvent gNfaSetConfigEvent;                    // event for Set_Config....
142 SyncEvent gNfaGetConfigEvent;                    // event for Get_Config....
143 SyncEvent gNfaVsCommand;                         // event for VS commands
144 SyncEvent gSendRawVsCmdEvent;  // event for NFA_SendRawVsCommand()
145 static bool sIsNfaEnabled = false;
146 static bool sDiscoveryEnabled = false;  // is polling or listening
147 static bool sPollingEnabled = false;    // is polling for tag?
148 static bool sIsDisabling = false;
149 static bool sRfEnabled = false;   // whether RF discovery is enabled
150 static bool sSeRfActive = false;  // whether RF with SE is likely active
151 static bool sReaderModeEnabled =
152     false;  // whether we're only reading tags, not allowing card emu
153 static bool sAbortConnlessWait = false;
154 static jint sLfT3tMax = 0;
155 static bool sRoutingInitialized = false;
156 static bool sIsRecovering = false;
157 static bool sIsAlwaysPolling = false;
158 static std::vector<uint8_t> sRawVendorCmdResponse;
159 static bool sEnableVendorNciNotifications = false;
160 
161 #define CONFIG_UPDATE_TECH_MASK (1 << 1)
162 #define DEFAULT_TECH_MASK                                                  \
163   (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F | \
164    NFA_TECHNOLOGY_MASK_V | NFA_TECHNOLOGY_MASK_B_PRIME |                   \
165    NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE |           \
166    NFA_TECHNOLOGY_MASK_KOVIO)
167 #define DEFAULT_DISCOVERY_DURATION 500
168 #define READER_MODE_DISCOVERY_DURATION 200
169 #define FLAG_SET_DEFAULT_TECH 0x40000000
170 
171 static void nfaConnectionCallback(uint8_t event, tNFA_CONN_EVT_DATA* eventData);
172 static void nfaDeviceManagementCallback(uint8_t event,
173                                         tNFA_DM_CBACK_DATA* eventData);
174 static bool isListenMode(tNFA_ACTIVATED& activated);
175 static tNFA_STATUS stopPolling_rfDiscoveryDisabled();
176 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
177     tNFA_TECHNOLOGY_MASK tech_mask);
178 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
179                                         jint screen_state_mask,
180                                         jboolean alwaysPoll);
181 static jboolean nfcManager_doSetPowerSavingMode(JNIEnv* e, jobject o,
182                                                 bool flag);
183 static void sendRawVsCmdCallback(uint8_t event, uint16_t param_len,
184                                  uint8_t* p_param);
185 static jbyteArray nfcManager_getProprietaryCaps(JNIEnv* e, jobject o);
186 tNFA_STATUS gVSCmdStatus = NFA_STATUS_OK;
187 uint16_t gCurrentConfigLen;
188 uint8_t gConfig[256];
189 std::vector<uint8_t> gCaps(0);
190 static int prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
191 static int NFA_SCREEN_POLLING_TAG_MASK = 0x10;
192 bool gIsDtaEnabled = false;
193 static bool gObserveModeEnabled = false;
194 static int gPartialInitMode = ENABLE_MODE_DEFAULT;
195 /////////////////////////////////////////////////////////////
196 /////////////////////////////////////////////////////////////
197 
198 namespace {
initializeGlobalDebugEnabledFlag()199 void initializeGlobalDebugEnabledFlag() {
200   bool nfc_debug_enabled =
201       (NfcConfig::getUnsigned(NAME_NFC_DEBUG_ENABLED, 1) != 0) ||
202       property_get_bool("persist.nfc.debug_enabled", true);
203 
204   android::base::SetMinimumLogSeverity(nfc_debug_enabled ? android::base::DEBUG
205                                                          : android::base::INFO);
206 }
207 
initializeRecoveryOption()208 void initializeRecoveryOption() {
209   recovery_option = NfcConfig::getUnsigned(NAME_RECOVERY_OPTION, 0);
210 
211   LOG(DEBUG) << __func__ << ": recovery option=" << recovery_option;
212 }
213 
initializeNfceePowerAndLinkConf()214 void initializeNfceePowerAndLinkConf() {
215   always_on_nfcee_power_and_link_conf =
216       NfcConfig::getUnsigned(NAME_ALWAYS_ON_SET_EE_POWER_AND_LINK_CONF, 0);
217 
218   LOG(DEBUG) << __func__ << ": Always on set NFCEE_POWER_AND_LINK_CONF="
219              << always_on_nfcee_power_and_link_conf;
220 }
221 
initializeDisableAlwaysOnNfceePowerAndLinkConf()222 void initializeDisableAlwaysOnNfceePowerAndLinkConf() {
223   disable_always_on_nfcee_power_and_link_conf = NfcConfig::getUnsigned(
224       NAME_DISABLE_ALWAYS_ON_SET_EE_POWER_AND_LINK_CONF, 0);
225 
226   LOG(DEBUG) << __func__ << ": Always on set NFCEE_POWER_AND_LINK_CONF="
227              << disable_always_on_nfcee_power_and_link_conf;
228 }
229 
230 }  // namespace
231 
232 /*******************************************************************************
233 **
234 ** Function:        getNative
235 **
236 ** Description:     Get native data
237 **
238 ** Returns:         Native data structure.
239 **
240 *******************************************************************************/
getNative(JNIEnv * e,jobject o)241 nfc_jni_native_data* getNative(JNIEnv* e, jobject o) {
242   static struct nfc_jni_native_data* sCachedNat = NULL;
243   if (e) {
244     sCachedNat = nfc_jni_get_nat(e, o);
245   }
246   return sCachedNat;
247 }
248 
249 /*******************************************************************************
250 **
251 ** Function:        handleRfDiscoveryEvent
252 **
253 ** Description:     Handle RF-discovery events from the stack.
254 **                  discoveredDevice: Discovered device.
255 **
256 ** Returns:         None
257 **
258 *******************************************************************************/
handleRfDiscoveryEvent(tNFC_RESULT_DEVT * discoveredDevice)259 static void handleRfDiscoveryEvent(tNFC_RESULT_DEVT* discoveredDevice) {
260   NfcTag& natTag = NfcTag::getInstance();
261 
262   LOG(DEBUG) << StringPrintf("%s: ", __func__);
263 
264   if (discoveredDevice->protocol != NFA_PROTOCOL_NFC_DEP) {
265     natTag.setNumDiscNtf(natTag.getNumDiscNtf() + 1);
266   }
267   if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) {
268     // there is more discovery notification coming
269     return;
270   }
271 
272   if (natTag.getNumDiscNtf() > 1) {
273     natTag.setMultiProtocolTagSupport(true);
274   }
275 
276   natTag.setNumDiscNtf(natTag.getNumDiscNtf() - 1);
277   // select the first of multiple tags that is discovered
278   natTag.selectFirstTag();
279 }
280 
281 /*******************************************************************************
282 **
283 ** Function:        nfaConnectionCallback
284 **
285 ** Description:     Receive connection-related events from stack.
286 **                  connEvent: Event code.
287 **                  eventData: Event data.
288 **
289 ** Returns:         None
290 **
291 *******************************************************************************/
nfaConnectionCallback(uint8_t connEvent,tNFA_CONN_EVT_DATA * eventData)292 static void nfaConnectionCallback(uint8_t connEvent,
293                                   tNFA_CONN_EVT_DATA* eventData) {
294   tNFA_STATUS status = NFA_STATUS_FAILED;
295 
296   switch (connEvent) {
297     case NFA_LISTEN_ENABLED_EVT:  // whether listening successfully started
298     {
299       LOG(DEBUG) << StringPrintf("%s: NFA_LISTEN_ENABLED_EVT:status= %u",
300                                  __func__, eventData->status);
301 
302       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
303       sNfaEnableDisablePollingEvent.notifyOne();
304     } break;
305 
306     case NFA_POLL_ENABLED_EVT:  // whether polling successfully started
307     {
308       LOG(DEBUG) << StringPrintf("%s: NFA_POLL_ENABLED_EVT: status = %u",
309                                  __func__, eventData->status);
310 
311       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
312       sNfaEnableDisablePollingEvent.notifyOne();
313     } break;
314 
315     case NFA_POLL_DISABLED_EVT:  // Listening/Polling stopped
316     {
317       LOG(DEBUG) << StringPrintf("%s: NFA_POLL_DISABLED_EVT: status = %u",
318                                  __func__, eventData->status);
319 
320       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
321       sNfaEnableDisablePollingEvent.notifyOne();
322     } break;
323 
324     case NFA_RF_DISCOVERY_STARTED_EVT:  // RF Discovery started
325     {
326       LOG(DEBUG) << StringPrintf(
327           "%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u", __func__,
328           eventData->status);
329 
330       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
331       sNfaEnableDisablePollingEvent.notifyOne();
332       struct nfc_jni_native_data* nat = getNative(NULL, NULL);
333       if (!nat) {
334         LOG(ERROR) << StringPrintf("cached nat is null");
335         return;
336       }
337       JNIEnv* e = NULL;
338       ScopedAttach attach(nat->vm, &e);
339       if (e == NULL) {
340         LOG(ERROR) << StringPrintf("jni env is null");
341         return;
342       }
343       e->CallVoidMethod(nat->manager,
344                         android::gCachedNfcManagerNotifyRfDiscoveryEvent,
345                         JNI_TRUE);
346     } break;
347 
348     case NFA_RF_DISCOVERY_STOPPED_EVT:  // RF Discovery stopped event
349     {
350       LOG(DEBUG) << StringPrintf(
351           "%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u", __func__,
352           eventData->status);
353 
354       gActivated = false;
355 
356       SyncEventGuard guard(sNfaEnableDisablePollingEvent);
357       sNfaEnableDisablePollingEvent.notifyOne();
358       struct nfc_jni_native_data* nat = getNative(NULL, NULL);
359       if (!nat) {
360         LOG(ERROR) << StringPrintf("cached nat is null");
361         return;
362       }
363       JNIEnv* e = NULL;
364       ScopedAttach attach(nat->vm, &e);
365       if (e == NULL) {
366         LOG(ERROR) << StringPrintf("jni env is null");
367         return;
368       }
369       e->CallVoidMethod(nat->manager,
370                         android::gCachedNfcManagerNotifyRfDiscoveryEvent,
371                         JNI_FALSE);
372     } break;
373 
374     case NFA_DISC_RESULT_EVT:  // NFC link/protocol discovery notificaiton
375       status = eventData->disc_result.status;
376       LOG(DEBUG) << StringPrintf("%s: NFA_DISC_RESULT_EVT: status = %d",
377                                  __func__, status);
378       if (status != NFA_STATUS_OK) {
379         NfcTag::getInstance().setNumDiscNtf(0);
380         LOG(ERROR) << StringPrintf("%s: NFA_DISC_RESULT_EVT error: status = %d",
381                                    __func__, status);
382       } else {
383         NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
384         handleRfDiscoveryEvent(&eventData->disc_result.discovery_ntf);
385       }
386       break;
387 
388     case NFA_SELECT_RESULT_EVT:  // NFC link/protocol discovery select response
389       LOG(DEBUG) << StringPrintf(
390           "%s: NFA_SELECT_RESULT_EVT: status = %d, gIsSelectingRfInterface = "
391           "%d, "
392           "sIsDisabling=%d",
393           __func__, eventData->status, gIsSelectingRfInterface, sIsDisabling);
394 
395       if (sIsDisabling) break;
396 
397       if (eventData->status != NFA_STATUS_OK) {
398         if (gIsSelectingRfInterface) {
399           nativeNfcTag_doConnectStatus(false);
400         }
401 
402         LOG(ERROR) << StringPrintf(
403             "%s: NFA_SELECT_RESULT_EVT error: status = %d", __func__,
404             eventData->status);
405         NFA_Deactivate(FALSE);
406       }
407       break;
408 
409     case NFA_DEACTIVATE_FAIL_EVT:
410       LOG(DEBUG) << StringPrintf("%s: NFA_DEACTIVATE_FAIL_EVT: status = %d",
411                                  __func__, eventData->status);
412       break;
413 
414     case NFA_ACTIVATED_EVT:  // NFC link/protocol activated
415     {
416       LOG(DEBUG) << StringPrintf(
417           "%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d",
418           __func__, gIsSelectingRfInterface, sIsDisabling);
419       uint8_t activatedProtocol =
420           (tNFA_INTF_TYPE)eventData->activated.activate_ntf.protocol;
421       uint8_t activatedMode =
422           eventData->activated.activate_ntf.rf_tech_param.mode;
423       gTagJustActivated = true;
424       if (NFC_PROTOCOL_T5T == activatedProtocol &&
425           NfcTag::getInstance().getNumDiscNtf()) {
426         /* T5T doesn't support multiproto detection logic */
427         NfcTag::getInstance().setNumDiscNtf(0);
428       }
429       if ((eventData->activated.activate_ntf.protocol !=
430            NFA_PROTOCOL_NFC_DEP) &&
431           (!isListenMode(eventData->activated))) {
432         nativeNfcTag_setRfInterface(
433             (tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param.type);
434         nativeNfcTag_setActivatedRfProtocol(activatedProtocol);
435         nativeNfcTag_setActivatedRfMode(activatedMode);
436       }
437       NfcTag::getInstance().setActive(true);
438       if (sIsDisabling || !sIsNfaEnabled) break;
439       gActivated = true;
440 
441       updateNfcID0Param(
442           eventData->activated.activate_ntf.rf_tech_param.param.pb.nfcid0);
443       NfcTag::getInstance().setActivationState();
444       if (gIsSelectingRfInterface) {
445         nativeNfcTag_doConnectStatus(true);
446         break;
447       }
448 
449       nativeNfcTag_resetPresenceCheck();
450       if (!isListenMode(eventData->activated) &&
451           (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED ||
452            prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED)) {
453         if (!sIsAlwaysPolling) {
454           NFA_Deactivate(FALSE);
455         }
456       }
457 
458       NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
459       if (NfcTag::getInstance().getNumDiscNtf()) {
460         /*If its multiprotocol tag, deactivate tag with current selected
461         protocol to sleep . Select tag with next supported protocol after
462         deactivation event is received*/
463         if (((tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param
464                  .type == NFA_INTERFACE_FRAME)) {
465           uint8_t RW_TAG_SLP_REQ[] = {0x50, 0x00};
466           SyncEvent waitSome;
467           SyncEventGuard g(waitSome);
468           NFA_SendRawFrame(RW_TAG_SLP_REQ, sizeof(RW_TAG_SLP_REQ), 0);
469           waitSome.wait(4);
470         }
471         NFA_Deactivate(true);
472       }
473 
474       // If it activated in
475       // listen mode then it is likely for an SE transaction.
476       // Send the RF Event.
477       if (isListenMode(eventData->activated)) {
478         sSeRfActive = true;
479         struct nfc_jni_native_data* nat = getNative(NULL, NULL);
480         if (!nat) {
481           LOG(ERROR) << StringPrintf("cached nat is null");
482           return;
483         }
484         JNIEnv* e = NULL;
485         ScopedAttach attach(nat->vm, &e);
486         if (e == NULL) {
487           LOG(ERROR) << "jni env is null";
488           return;
489         }
490         e->CallVoidMethod(nat->manager,
491                           android::gCachedNfcManagerNotifyEeListenActivated,
492                           JNI_TRUE);
493       }
494     } break;
495     case NFA_DEACTIVATED_EVT:  // NFC link/protocol deactivated
496       LOG(DEBUG) << StringPrintf(
497           "%s: NFA_DEACTIVATED_EVT   Type: %u, gIsTagDeactivating: %d",
498           __func__, eventData->deactivated.type, gIsTagDeactivating);
499       NfcTag::getInstance().setDeactivationState(eventData->deactivated);
500       NfcTag::getInstance().selectNextTagIfExists();
501       if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP) {
502         {
503           SyncEventGuard g(gDeactivatedEvent);
504           gActivated = false;  // guard this variable from multi-threaded access
505           gDeactivatedEvent.notifyOne();
506         }
507         nativeNfcTag_resetPresenceCheck();
508         NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
509         nativeNfcTag_abortWaits();
510         NfcTag::getInstance().abort();
511       } else if (gIsTagDeactivating) {
512         NfcTag::getInstance().setActive(false);
513         nativeNfcTag_doDeactivateStatus(0);
514       }
515 
516       // If RF is activated for what we think is a Secure Element transaction
517       // and it is deactivated to either IDLE or DISCOVERY mode, notify w/event.
518       if ((eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE) ||
519           (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_DISCOVERY)) {
520         if (sSeRfActive) {
521           sSeRfActive = false;
522           struct nfc_jni_native_data* nat = getNative(NULL, NULL);
523           if (!nat) {
524             LOG(ERROR) << StringPrintf("cached nat is null");
525             return;
526           }
527           JNIEnv* e = NULL;
528           ScopedAttach attach(nat->vm, &e);
529           if (e == NULL) {
530             LOG(ERROR) << "jni env is null";
531             return;
532           }
533           e->CallVoidMethod(nat->manager,
534                             android::gCachedNfcManagerNotifyEeListenActivated,
535                             JNI_FALSE);
536         }
537       }
538 
539       break;
540 
541     case NFA_TLV_DETECT_EVT:  // TLV Detection complete
542       status = eventData->tlv_detect.status;
543       LOG(DEBUG) << StringPrintf(
544           "%s: NFA_TLV_DETECT_EVT: status = %d, protocol = %d, num_tlvs = %d, "
545           "num_bytes = %d",
546           __func__, status, eventData->tlv_detect.protocol,
547           eventData->tlv_detect.num_tlvs, eventData->tlv_detect.num_bytes);
548       if (status != NFA_STATUS_OK) {
549         LOG(ERROR) << StringPrintf("%s: NFA_TLV_DETECT_EVT error: status = %d",
550                                    __func__, status);
551       }
552       break;
553 
554     case NFA_NDEF_DETECT_EVT:  // NDEF Detection complete;
555       // if status is failure, it means the tag does not contain any or valid
556       // NDEF data;  pass the failure status to the NFC Service;
557       status = eventData->ndef_detect.status;
558       LOG(DEBUG) << StringPrintf(
559           "%s: NFA_NDEF_DETECT_EVT: status = 0x%X, protocol = %u, "
560           "max_size = %u, cur_size = %u, flags = 0x%X",
561           __func__, status, eventData->ndef_detect.protocol,
562           eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size,
563           eventData->ndef_detect.flags);
564       NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
565       nativeNfcTag_doCheckNdefResult(status, eventData->ndef_detect.max_size,
566                                      eventData->ndef_detect.cur_size,
567                                      eventData->ndef_detect.flags);
568       break;
569 
570     case NFA_DATA_EVT:  // Data message received (for non-NDEF reads)
571       LOG(DEBUG) << StringPrintf("%s: NFA_DATA_EVT: status = 0x%X, len = %d",
572                                  __func__, eventData->status,
573                                  eventData->data.len);
574       nativeNfcTag_doTransceiveStatus(eventData->status, eventData->data.p_data,
575                                       eventData->data.len);
576       break;
577     case NFA_RW_INTF_ERROR_EVT:
578       LOG(DEBUG) << StringPrintf("%s: NFC_RW_INTF_ERROR_EVT", __func__);
579       nativeNfcTag_notifyRfTimeout();
580       nativeNfcTag_doReadCompleted(NFA_STATUS_TIMEOUT);
581       break;
582     case NFA_SELECT_CPLT_EVT:  // Select completed
583       status = eventData->status;
584       LOG(DEBUG) << StringPrintf("%s: NFA_SELECT_CPLT_EVT: status = %d",
585                                  __func__, status);
586       if (status != NFA_STATUS_OK) {
587         LOG(ERROR) << StringPrintf("%s: NFA_SELECT_CPLT_EVT error: status = %d",
588                                    __func__, status);
589       }
590       break;
591 
592     case NFA_READ_CPLT_EVT:  // NDEF-read or tag-specific-read completed
593       LOG(DEBUG) << StringPrintf("%s: NFA_READ_CPLT_EVT: status = 0x%X",
594                                  __func__, eventData->status);
595       nativeNfcTag_doReadCompleted(eventData->status);
596       NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
597       break;
598 
599     case NFA_WRITE_CPLT_EVT:  // Write completed
600       LOG(DEBUG) << StringPrintf("%s: NFA_WRITE_CPLT_EVT: status = %d",
601                                  __func__, eventData->status);
602       nativeNfcTag_doWriteStatus(eventData->status == NFA_STATUS_OK);
603       break;
604 
605     case NFA_SET_TAG_RO_EVT:  // Tag set as Read only
606       LOG(DEBUG) << StringPrintf("%s: NFA_SET_TAG_RO_EVT: status = %d",
607                                  __func__, eventData->status);
608       nativeNfcTag_doMakeReadonlyResult(eventData->status);
609       break;
610 
611     case NFA_CE_NDEF_WRITE_START_EVT:  // NDEF write started
612       LOG(DEBUG) << StringPrintf("%s: NFA_CE_NDEF_WRITE_START_EVT: status: %d",
613                                  __func__, eventData->status);
614 
615       if (eventData->status != NFA_STATUS_OK)
616         LOG(ERROR) << StringPrintf(
617             "%s: NFA_CE_NDEF_WRITE_START_EVT error: status = %d", __func__,
618             eventData->status);
619       break;
620 
621     case NFA_CE_NDEF_WRITE_CPLT_EVT:  // NDEF write completed
622       LOG(DEBUG) << StringPrintf("%s: FA_CE_NDEF_WRITE_CPLT_EVT: len = %u",
623                                  __func__, eventData->ndef_write_cplt.len);
624       break;
625 
626     case NFA_PRESENCE_CHECK_EVT:
627       LOG(DEBUG) << StringPrintf("%s: NFA_PRESENCE_CHECK_EVT", __func__);
628       nativeNfcTag_doPresenceCheckResult(eventData->status);
629       break;
630     case NFA_FORMAT_CPLT_EVT:
631       LOG(DEBUG) << StringPrintf("%s: NFA_FORMAT_CPLT_EVT: status=0x%X",
632                                  __func__, eventData->status);
633       nativeNfcTag_formatStatus(eventData->status == NFA_STATUS_OK);
634       break;
635 
636     case NFA_I93_CMD_CPLT_EVT:
637       LOG(DEBUG) << StringPrintf("%s: NFA_I93_CMD_CPLT_EVT: status=0x%X",
638                                  __func__, eventData->status);
639       break;
640 
641     case NFA_CE_UICC_LISTEN_CONFIGURED_EVT:
642       LOG(DEBUG) << StringPrintf(
643           "%s: NFA_CE_UICC_LISTEN_CONFIGURED_EVT : status=0x%X", __func__,
644           eventData->status);
645       break;
646     case NFA_T4TNFCEE_EVT:
647     case NFA_T4TNFCEE_READ_CPLT_EVT:
648     case NFA_T4TNFCEE_WRITE_CPLT_EVT:
649     case NFA_T4TNFCEE_CLEAR_CPLT_EVT:
650     case NFA_T4TNFCEE_READ_CC_DATA_CPLT_EVT:
651       NativeT4tNfcee::getInstance().eventHandler(connEvent, eventData);
652       break;
653 
654     default:
655       LOG(DEBUG) << StringPrintf("%s: unknown event (%d) ????", __func__,
656                                  connEvent);
657       break;
658   }
659 }
660 
661 /*******************************************************************************
662 **
663 ** Function:        nfcManager_initNativeStruc
664 **
665 ** Description:     Initialize variables.
666 **                  e: JVM environment.
667 **                  o: Java object.
668 **
669 ** Returns:         True if ok.
670 **
671 *******************************************************************************/
nfcManager_initNativeStruc(JNIEnv * e,jobject o)672 static jboolean nfcManager_initNativeStruc(JNIEnv* e, jobject o) {
673   initializeGlobalDebugEnabledFlag();
674   initializeRecoveryOption();
675   initializeNfceePowerAndLinkConf();
676   initializeDisableAlwaysOnNfceePowerAndLinkConf();
677   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
678 
679   nfc_jni_native_data* nat =
680       (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
681   if (nat == NULL) {
682     LOG(ERROR) << StringPrintf("%s: fail allocate native data", __func__);
683     return JNI_FALSE;
684   }
685 
686   memset(nat, 0, sizeof(*nat));
687   e->GetJavaVM(&(nat->vm));
688   nat->env_version = e->GetVersion();
689   nat->manager = e->NewGlobalRef(o);
690 
691   ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
692   jfieldID f = e->GetFieldID(cls.get(), "mNative", "J");
693   e->SetLongField(o, f, (jlong)nat);
694 
695   /* Initialize native cached references */
696   gCachedNfcManagerNotifyNdefMessageListeners =
697       e->GetMethodID(cls.get(), "notifyNdefMessageListeners",
698                      "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
699 
700   gCachedNfcManagerNotifyHostEmuActivated =
701       e->GetMethodID(cls.get(), "notifyHostEmuActivated", "(I)V");
702 
703   gCachedNfcManagerNotifyHostEmuData =
704       e->GetMethodID(cls.get(), "notifyHostEmuData", "(I[B)V");
705 
706   gCachedNfcManagerNotifyHostEmuDeactivated =
707       e->GetMethodID(cls.get(), "notifyHostEmuDeactivated", "(I)V");
708 
709   gCachedNfcManagerNotifyRfFieldActivated =
710       e->GetMethodID(cls.get(), "notifyRfFieldActivated", "()V");
711   gCachedNfcManagerNotifyRfFieldDeactivated =
712       e->GetMethodID(cls.get(), "notifyRfFieldDeactivated", "()V");
713 
714   gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID(
715       cls.get(), "notifyTransactionListeners", "([B[BLjava/lang/String;)V");
716 
717   gCachedNfcManagerNotifyEeUpdated =
718       e->GetMethodID(cls.get(), "notifyEeUpdated", "()V");
719 
720   gCachedNfcManagerNotifyHwErrorReported =
721       e->GetMethodID(cls.get(), "notifyHwErrorReported", "()V");
722 
723   gCachedNfcManagerNotifyPollingLoopFrame =
724       e->GetMethodID(cls.get(), "notifyPollingLoopFrame", "(I[B)V");
725 
726   gCachedNfcManagerNotifyVendorSpecificEvent =
727       e->GetMethodID(cls.get(), "notifyVendorSpecificEvent", "(II[B)V");
728 
729   gCachedNfcManagerNotifyWlcStopped =
730       e->GetMethodID(cls.get(), "notifyWlcStopped", "(I)V");
731 
732   gCachedNfcManagerNotifyTagDiscovered =
733       e->GetMethodID(cls.get(), "notifyTagDiscovered", "(Z)V");
734 
735   gCachedNfcManagerNotifyCommandTimeout =
736       e->GetMethodID(cls.get(), "notifyCommandTimeout", "()V");
737 
738   gCachedNfcManagerNotifyObserveModeChanged =
739       e->GetMethodID(cls.get(), "notifyObserveModeChanged", "(Z)V");
740 
741   gCachedNfcManagerNotifyRfDiscoveryEvent =
742       e->GetMethodID(cls.get(), "notifyRFDiscoveryEvent", "(Z)V");
743 
744   gCachedNfcManagerNotifyEeListenActivated =
745       e->GetMethodID(cls.get(), "notifyEeListenActivated", "(Z)V");
746 
747   gCachedNfcManagerNotifyEeAidSelected = e->GetMethodID(
748       cls.get(), "notifyEeAidSelected", "([BLjava/lang/String;)V");
749 
750   gCachedNfcManagerNotifyEeProtocolSelected = e->GetMethodID(
751       cls.get(), "notifyEeProtocolSelected", "(ILjava/lang/String;)V");
752 
753   gCachedNfcManagerNotifyEeTechSelected = e->GetMethodID(
754       cls.get(), "notifyEeTechSelected", "(ILjava/lang/String;)V");
755 
756   if (nfc_jni_cache_object(e, gNativeNfcTagClassName, &(nat->cached_NfcTag)) ==
757       -1) {
758     LOG(ERROR) << StringPrintf("%s: fail cache NativeNfcTag", __func__);
759     return JNI_FALSE;
760   }
761 
762   // Cache the reference to the manager
763   (void)getNative(e,o);
764 
765   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
766   return JNI_TRUE;
767 }
768 
769 /*******************************************************************************
770 **
771 ** Function:        nfaDeviceManagementCallback
772 **
773 ** Description:     Receive device management events from stack.
774 **                  dmEvent: Device-management event ID.
775 **                  eventData: Data associated with event ID.
776 **
777 ** Returns:         None
778 **
779 *******************************************************************************/
nfaDeviceManagementCallback(uint8_t dmEvent,tNFA_DM_CBACK_DATA * eventData)780 void nfaDeviceManagementCallback(uint8_t dmEvent,
781                                  tNFA_DM_CBACK_DATA* eventData) {
782   LOG(DEBUG) << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent);
783 
784   switch (dmEvent) {
785     case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
786     {
787       SyncEventGuard guard(sNfaEnableEvent);
788       LOG(DEBUG) << StringPrintf("%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__,
789                                  eventData->status);
790       sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
791       sIsDisabling = false;
792       sNfaEnableEvent.notifyOne();
793     } break;
794 
795     case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
796     {
797       SyncEventGuard guard(sNfaDisableEvent);
798       LOG(DEBUG) << StringPrintf("%s: NFA_DM_DISABLE_EVT", __func__);
799       sIsNfaEnabled = false;
800       sIsDisabling = false;
801       sNfaDisableEvent.notifyOne();
802     } break;
803 
804     case NFA_DM_SET_CONFIG_EVT:  // result of NFA_SetConfig
805       LOG(DEBUG) << StringPrintf("%s: NFA_DM_SET_CONFIG_EVT", __func__);
806       {
807         SyncEventGuard guard(gNfaSetConfigEvent);
808         gNfaSetConfigEvent.notifyOne();
809       }
810       break;
811 
812     case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */
813       LOG(DEBUG) << StringPrintf("%s: NFA_DM_GET_CONFIG_EVT", __func__);
814       {
815         SyncEventGuard guard(gNfaGetConfigEvent);
816         if (eventData->status == NFA_STATUS_OK &&
817             eventData->get_config.tlv_size <= sizeof(gConfig)) {
818           gCurrentConfigLen = eventData->get_config.tlv_size;
819           memcpy(gConfig, eventData->get_config.param_tlvs,
820                  eventData->get_config.tlv_size);
821         } else {
822           LOG(ERROR) << StringPrintf("%s: NFA_DM_GET_CONFIG failed", __func__);
823           gCurrentConfigLen = 0;
824         }
825         gNfaGetConfigEvent.notifyOne();
826       }
827       break;
828 
829     case NFA_DM_RF_FIELD_EVT:
830       LOG(DEBUG) << StringPrintf(
831           "%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __func__,
832           eventData->rf_field.status, eventData->rf_field.rf_field_status);
833       if (eventData->rf_field.status == NFA_STATUS_OK) {
834         struct nfc_jni_native_data* nat = getNative(NULL, NULL);
835         if (!nat) {
836           LOG(ERROR) << StringPrintf("cached nat is null");
837           return;
838         }
839         JNIEnv* e = NULL;
840         ScopedAttach attach(nat->vm, &e);
841         if (e == NULL) {
842           LOG(ERROR) << StringPrintf("jni env is null");
843           return;
844         }
845         if (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON)
846           e->CallVoidMethod(nat->manager,
847                             android::gCachedNfcManagerNotifyRfFieldActivated);
848         else
849           e->CallVoidMethod(nat->manager,
850                             android::gCachedNfcManagerNotifyRfFieldDeactivated);
851       }
852       break;
853 
854     case NFA_DM_NFCC_TRANSPORT_ERR_EVT:
855     case NFA_DM_NFCC_TIMEOUT_EVT: {
856       if (dmEvent == NFA_DM_NFCC_TIMEOUT_EVT)
857         LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TIMEOUT_EVT; abort",
858                                    __func__);
859       else if (dmEvent == NFA_DM_NFCC_TRANSPORT_ERR_EVT)
860         LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TRANSPORT_ERR_EVT; abort",
861                                    __func__);
862 
863       struct nfc_jni_native_data* nat = getNative(NULL, NULL);
864       if (recovery_option && nat != NULL) {
865         JNIEnv* e = NULL;
866         ScopedAttach attach(nat->vm, &e);
867         if (e == NULL) {
868           LOG(ERROR) << StringPrintf("jni env is null");
869           return;
870         }
871         LOG(ERROR) << StringPrintf("%s: toggle NFC state to recovery nfc",
872                                    __func__);
873         sIsRecovering = true;
874         e->CallVoidMethod(nat->manager,
875                           android::gCachedNfcManagerNotifyHwErrorReported);
876         {
877           LOG(DEBUG) << StringPrintf(
878               "%s: aborting  sNfaEnableDisablePollingEvent", __func__);
879           SyncEventGuard guard(sNfaEnableDisablePollingEvent);
880           sNfaEnableDisablePollingEvent.notifyOne();
881         }
882         {
883           LOG(DEBUG) << StringPrintf("%s: aborting  sNfaEnableEvent", __func__);
884           SyncEventGuard guard(sNfaEnableEvent);
885           sNfaEnableEvent.notifyOne();
886         }
887         {
888           LOG(DEBUG) << StringPrintf("%s: aborting  sNfaDisableEvent",
889                                      __func__);
890           SyncEventGuard guard(sNfaDisableEvent);
891           sNfaDisableEvent.notifyOne();
892         }
893         {
894           LOG(DEBUG) << StringPrintf("%s: aborting  sNfaSetPowerSubState",
895                                      __func__);
896           SyncEventGuard guard(sNfaSetPowerSubState);
897           sNfaSetPowerSubState.notifyOne();
898         }
899         {
900           LOG(DEBUG) << StringPrintf("%s: aborting gNfaSetConfigEvent",
901                                      __func__);
902           SyncEventGuard guard(gNfaSetConfigEvent);
903           gNfaSetConfigEvent.notifyOne();
904         }
905         {
906           LOG(DEBUG) << StringPrintf("%s: aborting gNfaGetConfigEvent",
907                                      __func__);
908           SyncEventGuard guard(gNfaGetConfigEvent);
909           gNfaGetConfigEvent.notifyOne();
910         }
911         {
912           LOG(DEBUG) << StringPrintf(
913               "%s: aborting RoutingManager::getInstance().mEeUpdateEvent",
914               __func__);
915           SyncEventGuard guard(RoutingManager::getInstance().mEeUpdateEvent);
916           RoutingManager::getInstance().mEeUpdateEvent.notifyOne();
917         }
918       } else {
919         nativeNfcTag_abortWaits();
920         NfcTag::getInstance().abort();
921         sAbortConnlessWait = true;
922         {
923           LOG(DEBUG) << StringPrintf(
924               "%s: aborting  sNfaEnableDisablePollingEvent", __func__);
925           SyncEventGuard guard(sNfaEnableDisablePollingEvent);
926           sNfaEnableDisablePollingEvent.notifyOne();
927         }
928         {
929           LOG(DEBUG) << StringPrintf("%s: aborting  sNfaEnableEvent", __func__);
930           SyncEventGuard guard(sNfaEnableEvent);
931           sNfaEnableEvent.notifyOne();
932         }
933         {
934           LOG(DEBUG) << StringPrintf("%s: aborting  sNfaDisableEvent",
935                                      __func__);
936           SyncEventGuard guard(sNfaDisableEvent);
937           sNfaDisableEvent.notifyOne();
938         }
939         sDiscoveryEnabled = false;
940         sPollingEnabled = false;
941         PowerSwitch::getInstance().abort();
942 
943         if (!sIsDisabling && sIsNfaEnabled) {
944           if (gIsDtaEnabled == true) {
945             LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
946                                        __func__);
947             NFA_DisableDtamode();
948           }
949 
950           NFA_Disable(FALSE);
951           sIsDisabling = true;
952         } else {
953           sIsNfaEnabled = false;
954           sIsDisabling = false;
955         }
956         PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
957         LOG(ERROR) << StringPrintf("%s: crash NFC service", __func__);
958         if (nat != NULL) {
959           JNIEnv* e = NULL;
960           ScopedAttach attach(nat->vm, &e);
961           if (e != NULL) {
962             e->CallVoidMethod(nat->manager,
963                               android::gCachedNfcManagerNotifyCommandTimeout);
964           }
965         }
966         //////////////////////////////////////////////
967         // crash the NFC service process so it can restart automatically
968         abort();
969         //////////////////////////////////////////////
970       }
971     } break;
972 
973     case NFA_DM_PWR_MODE_CHANGE_EVT:
974       PowerSwitch::getInstance().deviceManagementCallback(dmEvent, eventData);
975       break;
976 
977     case NFA_DM_SET_POWER_SUB_STATE_EVT: {
978       LOG(DEBUG) << StringPrintf(
979           "%s: NFA_DM_SET_POWER_SUB_STATE_EVT; status=0x%X", __FUNCTION__,
980           eventData->power_sub_state.status);
981       SyncEventGuard guard(sNfaSetPowerSubState);
982       sNfaSetPowerSubState.notifyOne();
983     } break;
984     default:
985       LOG(DEBUG) << StringPrintf("%s: unhandled event", __func__);
986       break;
987   }
988 }
989 
990 /*******************************************************************************
991 **
992 ** Function:        nfcManager_sendRawFrame
993 **
994 ** Description:     Send a raw frame.
995 **                  e: JVM environment.
996 **                  o: Java object.
997 **
998 ** Returns:         True if ok.
999 **
1000 *******************************************************************************/
nfcManager_sendRawFrame(JNIEnv * e,jobject,jbyteArray data)1001 static jboolean nfcManager_sendRawFrame(JNIEnv* e, jobject, jbyteArray data) {
1002   ScopedByteArrayRO bytes(e, data);
1003   uint8_t* buf =
1004       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1005   size_t bufLen = bytes.size();
1006   tNFA_STATUS status = NFA_SendRawFrame(buf, bufLen, 0);
1007 
1008   return (status == NFA_STATUS_OK);
1009 }
1010 
1011 /*******************************************************************************
1012 **
1013 ** Function:        nfcManager_routeAid
1014 **
1015 ** Description:     Route an AID to an EE
1016 **                  e: JVM environment.
1017 **                  aid: aid to be added to routing table.
1018 **                  route: aid route location. i.e. DH/eSE/UICC
1019 **                  aidInfo: prefix or suffix aid.
1020 **
1021 ** Returns:         True if aid is accpted by NFA Layer.
1022 **
1023 *******************************************************************************/
nfcManager_routeAid(JNIEnv * e,jobject,jbyteArray aid,jint route,jint aidInfo,jint power)1024 static jboolean nfcManager_routeAid(JNIEnv* e, jobject, jbyteArray aid,
1025                                     jint route, jint aidInfo, jint power) {
1026   uint8_t* buf;
1027   size_t bufLen;
1028   if (sIsDisabling || !sIsNfaEnabled) {
1029     return false;
1030   }
1031 
1032   if (aid == NULL) {
1033     buf = NULL;
1034     bufLen = 0;
1035     return RoutingManager::getInstance().addAidRouting(buf, bufLen, route,
1036                                                        aidInfo, power);
1037   }
1038   ScopedByteArrayRO bytes(e, aid);
1039   buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1040   bufLen = bytes.size();
1041   if (NfcConfig::hasKey(NAME_DEFAULT_NDEF_NFCEE_ROUTE)) {
1042     if (route == (int)NfcConfig::getUnsigned(NAME_DEFAULT_NDEF_NFCEE_ROUTE)) {
1043       NativeT4tNfcee::getInstance().checkAndUpdateT4TAid(buf,
1044                                                          (uint8_t*)&bufLen);
1045     }
1046   }
1047   return RoutingManager::getInstance().addAidRouting(buf, bufLen, route,
1048                                                      aidInfo, power);
1049 }
1050 
1051 /*******************************************************************************
1052 **
1053 ** Function:        nfcManager_unrouteAid
1054 **
1055 ** Description:     Remove a AID routing
1056 **                  e: JVM environment.
1057 **                  o: Java object.
1058 **
1059 ** Returns:         True if ok.
1060 **
1061 *******************************************************************************/
nfcManager_unrouteAid(JNIEnv * e,jobject,jbyteArray aid)1062 static jboolean nfcManager_unrouteAid(JNIEnv* e, jobject, jbyteArray aid) {
1063   uint8_t* buf;
1064   size_t bufLen;
1065   if (sIsDisabling || !sIsNfaEnabled) {
1066     return false;
1067   }
1068 
1069   if (aid == NULL) {
1070     buf = NULL;
1071     bufLen = 0;
1072     return RoutingManager::getInstance().removeAidRouting(buf, bufLen);
1073   }
1074   ScopedByteArrayRO bytes(e, aid);
1075   buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1076   bufLen = bytes.size();
1077   return RoutingManager::getInstance().removeAidRouting(buf, bufLen);
1078 }
1079 
1080 /*******************************************************************************
1081 **
1082 ** Function:        nfcManager_commitRouting
1083 **
1084 ** Description:     Sends the AID routing table to the controller
1085 **                  e: JVM environment.
1086 **                  o: Java object.
1087 **
1088 ** Returns:         NFA_STATUS_OK if successfully initiated
1089 **                  NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
1090 **                  NFA_STATUS_FAILED otherwise
1091 **
1092 *******************************************************************************/
nfcManager_commitRouting(JNIEnv * e,jobject)1093 static jint nfcManager_commitRouting(JNIEnv* e, jobject) {
1094   if (sRfEnabled) {
1095     /*Update routing table only in Idle state.*/
1096     startRfDiscovery(false);
1097   }
1098   jint commitStatus = RoutingManager::getInstance().commitRouting();
1099   startRfDiscovery(true);
1100   return commitStatus;
1101 }
1102 
nfaVSCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)1103 void static nfaVSCallback(uint8_t event, uint16_t param_len, uint8_t* p_param) {
1104   switch (event & NCI_OID_MASK) {
1105     case NCI_MSG_PROP_ANDROID: {
1106       uint8_t android_sub_opcode = p_param[3];
1107       switch (android_sub_opcode) {
1108         case NCI_QUERY_ANDROID_PASSIVE_OBSERVE: {
1109           gObserveModeEnabled = p_param[5];
1110           LOG(INFO) << StringPrintf("Query Observe mode state is %s",
1111                                     gObserveModeEnabled ? "TRUE" : "FALSE");
1112         }
1113           FALLTHROUGH_INTENDED;
1114         case NCI_ANDROID_PASSIVE_OBSERVE: {
1115           gVSCmdStatus = p_param[4];
1116           LOG(INFO) << StringPrintf("Observe mode RSP: status: %x",
1117                                     gVSCmdStatus);
1118           SyncEventGuard guard(gNfaVsCommand);
1119           gNfaVsCommand.notifyOne();
1120         } break;
1121         case NCI_ANDROID_GET_CAPS: {
1122           gVSCmdStatus = p_param[4];
1123           SyncEventGuard guard(gNfaVsCommand);
1124           gCaps.assign(p_param + 8, p_param + param_len);
1125           gNfaVsCommand.notifyOne();
1126         } break;
1127         case NCI_ANDROID_POLLING_FRAME_NTF: {
1128           struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1129           if (!nat) {
1130             LOG(ERROR) << StringPrintf("cached nat is null");
1131             return;
1132           }
1133           JNIEnv* e = NULL;
1134           ScopedAttach attach(nat->vm, &e);
1135           if (e == NULL) {
1136             LOG(ERROR) << StringPrintf("jni env is null");
1137             return;
1138           }
1139           ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(param_len));
1140           if (dataJavaArray.get() == NULL) {
1141             LOG(ERROR) << "fail allocate array";
1142             return;
1143           }
1144           e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, param_len,
1145                                 (jbyte*)(p_param));
1146           if (e->ExceptionCheck()) {
1147             e->ExceptionClear();
1148             LOG(ERROR) << "failed to fill array";
1149             return;
1150           }
1151           e->CallVoidMethod(nat->manager,
1152                             android::gCachedNfcManagerNotifyPollingLoopFrame,
1153                             (jint)param_len, dataJavaArray.get());
1154 
1155         } break;
1156         default:
1157           LOG(DEBUG) << StringPrintf("Unknown Android sub opcode %x",
1158                                      android_sub_opcode);
1159       }
1160     } break;
1161     default: {
1162       if (sEnableVendorNciNotifications) {
1163         struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1164         if (!nat) {
1165           LOG(ERROR) << StringPrintf("%s: cached nat is null", __FUNCTION__);
1166           return;
1167         }
1168         JNIEnv* e = NULL;
1169         ScopedAttach attach(nat->vm, &e);
1170         if (e == NULL) {
1171           LOG(ERROR) << StringPrintf("%s: jni env is null", __FUNCTION__);
1172           return;
1173         }
1174         ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(param_len));
1175         if (dataJavaArray.get() == NULL) {
1176           LOG(ERROR) << StringPrintf("%s: fail allocate array", __FUNCTION__);
1177           return;
1178         }
1179         e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, param_len,
1180                               (jbyte*)(p_param));
1181         if (e->ExceptionCheck()) {
1182           e->ExceptionClear();
1183           LOG(ERROR) << StringPrintf("%s failed to fill array", __FUNCTION__);
1184           return;
1185         }
1186         e->CallVoidMethod(nat->manager,
1187                           android::gCachedNfcManagerNotifyVendorSpecificEvent,
1188                           (jint)event, (jint)param_len, dataJavaArray.get());
1189       }
1190     } break;
1191   }
1192 }
1193 
nfcManager_injectNtf(JNIEnv * e,jobject,jbyteArray data)1194 static void nfcManager_injectNtf(JNIEnv* e, jobject, jbyteArray data) {
1195   ScopedByteArrayRO bytes(e, data);
1196   size_t bufLen = bytes.size();
1197   tNFC_HAL_EVT_MSG* p_msg;
1198   p_msg = (tNFC_HAL_EVT_MSG*)GKI_getbuf(sizeof(tNFC_HAL_EVT_MSG) + bufLen + 1);
1199   if (p_msg != NULL) {
1200     p_msg->hdr.len = bufLen + 3;
1201     p_msg->hdr.event = BT_EVT_TO_NFC_NCI;
1202     p_msg->hdr.offset = sizeof(tNFC_HAL_EVT_MSG) - 7;
1203     p_msg->hdr.layer_specific = 0;
1204     memcpy(((uint8_t*)p_msg) + sizeof(tNFC_HAL_EVT_MSG) + 1, bytes.get(),
1205            bufLen);
1206     GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
1207   }
1208 }
1209 
isObserveModeSupported(JNIEnv * e,jobject o)1210 static jboolean isObserveModeSupported(JNIEnv* e, jobject o) {
1211   ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
1212   jmethodID isSupported =
1213       e->GetMethodID(cls.get(), "isObserveModeSupported", "()Z");
1214   return e->CallBooleanMethod(o, isSupported);
1215 }
1216 
nfcManager_isObserveModeEnabled(JNIEnv * e,jobject o)1217 static jboolean nfcManager_isObserveModeEnabled(JNIEnv* e, jobject o) {
1218   if (isObserveModeSupported(e, o) == JNI_FALSE) {
1219     return false;
1220   }
1221 
1222   uint8_t cmd[] = {NCI_QUERY_ANDROID_PASSIVE_OBSERVE};
1223   SyncEventGuard guard(gNfaVsCommand);
1224   tNFA_STATUS status =
1225       NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd), cmd, nfaVSCallback);
1226 
1227   if (status == NFA_STATUS_OK) {
1228     if (!gNfaVsCommand.wait(1000)) {
1229       LOG(ERROR) << StringPrintf(
1230           "%s: Timed out waiting for a response to get observe mode ",
1231           __FUNCTION__);
1232       gVSCmdStatus = NFA_STATUS_FAILED;
1233     }
1234   } else {
1235     LOG(DEBUG) << StringPrintf("%s: Failed to get observe mode ", __FUNCTION__);
1236   }
1237   LOG(DEBUG) << StringPrintf(
1238       "%s: returning %s", __FUNCTION__,
1239       (gObserveModeEnabled != JNI_FALSE ? "TRUE" : "FALSE"));
1240   return gObserveModeEnabled;
1241 }
1242 
nfaSendRawVsCmdCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)1243 static void nfaSendRawVsCmdCallback(uint8_t event, uint16_t param_len,
1244                                     uint8_t* p_param) {
1245   if (param_len == 5) {
1246     gVSCmdStatus = p_param[4];
1247   } else {
1248     gVSCmdStatus = NFA_STATUS_FAILED;
1249   }
1250   SyncEventGuard guard(gNfaVsCommand);
1251   gNfaVsCommand.notifyOne();
1252 }
1253 
isObserveModeSupportedWithoutRfDeactivation(JNIEnv * e,jobject o)1254 bool isObserveModeSupportedWithoutRfDeactivation(JNIEnv* e, jobject o) {
1255   ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
1256   jmethodID isSupported = e->GetMethodID(
1257       cls.get(), "isObserveModeSupportedWithoutRfDeactivation", "()Z");
1258   return e->CallBooleanMethod(o, isSupported);
1259 }
1260 
nfcManager_setObserveMode(JNIEnv * e,jobject o,jboolean enable)1261 static jboolean nfcManager_setObserveMode(JNIEnv* e, jobject o,
1262                                           jboolean enable) {
1263   if (isObserveModeSupported(e, o) == JNI_FALSE) {
1264     return false;
1265   }
1266 
1267   bool needToTurnOffRadio = !isObserveModeSupportedWithoutRfDeactivation(e, o);
1268 
1269   if ((gObserveModeEnabled == enable) &&
1270       ((enable != JNI_FALSE) ==
1271        (nfcManager_isObserveModeEnabled(e, o) != JNI_FALSE))) {
1272     LOG(DEBUG) << StringPrintf(
1273         "%s: called with %s but it is already %s, returning early",
1274         __FUNCTION__, (enable != JNI_FALSE ? "TRUE" : "FALSE"),
1275         (gObserveModeEnabled != JNI_FALSE ? "TRUE" : "FALSE"));
1276     return true;
1277   }
1278   bool reenbleDiscovery = false;
1279   if (sRfEnabled && needToTurnOffRadio) {
1280     startRfDiscovery(false);
1281     reenbleDiscovery = true;
1282   }
1283   uint8_t cmd[] = {
1284       NCI_ANDROID_PASSIVE_OBSERVE,
1285       static_cast<uint8_t>(enable != JNI_FALSE
1286                                ? NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE
1287                                : NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
1288   {
1289     SyncEventGuard guard(gNfaVsCommand);
1290     tNFA_STATUS status = NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd),
1291                                            cmd, nfaVSCallback);
1292 
1293     if (status == NFA_STATUS_OK) {
1294       if (!gNfaVsCommand.wait(1000)) {
1295         LOG(ERROR) << StringPrintf(
1296             "%s: Timed out waiting for a response to set observe mode ",
1297             __FUNCTION__);
1298         gVSCmdStatus = NFA_STATUS_FAILED;
1299       }
1300     } else {
1301       LOG(DEBUG) << StringPrintf("%s: Failed to set observe mode ",
1302                                  __FUNCTION__);
1303       gVSCmdStatus = NFA_STATUS_FAILED;
1304     }
1305   }
1306   if (reenbleDiscovery) {
1307     startRfDiscovery(true);
1308   }
1309 
1310   if (gVSCmdStatus == NFA_STATUS_OK) {
1311     gObserveModeEnabled = enable;
1312   } else {
1313     gObserveModeEnabled = nfcManager_isObserveModeEnabled(e, o);
1314   }
1315 
1316   LOG(DEBUG) << StringPrintf(
1317       "%s: Set observe mode to %s with result %x, observe mode is now %s.",
1318       __FUNCTION__, (enable != JNI_FALSE ? "TRUE" : "FALSE"), gVSCmdStatus,
1319       (gObserveModeEnabled ? "enabled" : "disabled"));
1320   if (gObserveModeEnabled == enable) {
1321     e->CallVoidMethod(o, android::gCachedNfcManagerNotifyObserveModeChanged,
1322                       enable);
1323     return true;
1324   } else {
1325     return false;
1326   }
1327 }
1328 
1329 /*******************************************************************************
1330 **
1331 ** Function:        nfcManager_doRegisterT3tIdentifier
1332 **
1333 ** Description:     Registers LF_T3T_IDENTIFIER for NFC-F.
1334 **                  e: JVM environment.
1335 **                  o: Java object.
1336 **                  t3tIdentifier: LF_T3T_IDENTIFIER value (10 or 18 bytes)
1337 **
1338 ** Returns:         Handle retrieve from RoutingManager.
1339 **
1340 *******************************************************************************/
nfcManager_doRegisterT3tIdentifier(JNIEnv * e,jobject,jbyteArray t3tIdentifier)1341 static jint nfcManager_doRegisterT3tIdentifier(JNIEnv* e, jobject,
1342                                                jbyteArray t3tIdentifier) {
1343   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1344 
1345   ScopedByteArrayRO bytes(e, t3tIdentifier);
1346   uint8_t* buf =
1347       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1348   size_t bufLen = bytes.size();
1349   int handle = RoutingManager::getInstance().registerT3tIdentifier(buf, bufLen);
1350 
1351   LOG(DEBUG) << StringPrintf("%s: handle=%d", __func__, handle);
1352   if (handle != NFA_HANDLE_INVALID)
1353     RoutingManager::getInstance().commitRouting();
1354   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1355 
1356   return handle;
1357 }
1358 
1359 /*******************************************************************************
1360 **
1361 ** Function:        nfcManager_doDeregisterT3tIdentifier
1362 **
1363 ** Description:     Deregisters LF_T3T_IDENTIFIER for NFC-F.
1364 **                  e: JVM environment.
1365 **                  o: Java object.
1366 **                  handle: Handle retrieve from libnfc-nci.
1367 **
1368 ** Returns:         None
1369 **
1370 *******************************************************************************/
nfcManager_doDeregisterT3tIdentifier(JNIEnv *,jobject,jint handle)1371 static void nfcManager_doDeregisterT3tIdentifier(JNIEnv*, jobject,
1372                                                  jint handle) {
1373   LOG(DEBUG) << StringPrintf("%s: enter; handle=%d", __func__, handle);
1374 
1375   RoutingManager::getInstance().deregisterT3tIdentifier(handle);
1376   RoutingManager::getInstance().commitRouting();
1377 
1378   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1379 }
1380 
1381 /*******************************************************************************
1382 **
1383 ** Function:        nfcManager_getLfT3tMax
1384 **
1385 ** Description:     Returns LF_T3T_MAX value.
1386 **                  e: JVM environment.
1387 **                  o: Java object.
1388 **
1389 ** Returns:         LF_T3T_MAX value.
1390 **
1391 *******************************************************************************/
nfcManager_getLfT3tMax(JNIEnv *,jobject)1392 static jint nfcManager_getLfT3tMax(JNIEnv*, jobject) {
1393   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1394   LOG(DEBUG) << StringPrintf("LF_T3T_MAX=%d", sLfT3tMax);
1395   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1396 
1397   return sLfT3tMax;
1398 }
1399 
1400 /*******************************************************************************
1401 **
1402 ** Function:        doPartialInit
1403 **
1404 ** Description:     Partial Nfc initialization based on mode set
1405 **	            ENABLE_MODE_TRANSPARENT : Minimum initialization to allow
1406 **                                 NFCC transport
1407 **	            ENABLE_MODE_EE : Minimum Initialization to allow card
1408 **                                 emulation operation
1409 **
1410 ** Returns:         True if ok.
1411 **
1412 *******************************************************************************/
doPartialInit()1413 static jboolean doPartialInit() {
1414   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1415   tNFA_STATUS stat = NFA_STATUS_OK;
1416 
1417   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1418   theInstance.Initialize();  // start GKI, NCI task, NFC task
1419 
1420   {
1421     SyncEventGuard guard(sNfaEnableEvent);
1422     tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
1423     NFA_Partial_Init(halFuncEntries, gPartialInitMode);
1424     if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1425       LOG(DEBUG) << StringPrintf("%s: register VS callbacks", __func__);
1426       NFA_RegVSCback(true, &nfaVSCallback);
1427     }
1428 
1429     LOG(DEBUG) << StringPrintf("%s: calling enable", __func__);
1430     stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
1431     if (stat == NFA_STATUS_OK) {
1432       sNfaEnableEvent.wait();  // wait for NFA command to finish
1433     }
1434     NFA_SetNfccMode(ENABLE_MODE_DEFAULT);
1435   }
1436 
1437   // sIsNfaEnabled indicates whether stack started successfully
1438   if (!sIsNfaEnabled) {
1439     NFA_Disable(false /* ungraceful */);
1440     theInstance.Finalize();
1441     return JNI_FALSE;
1442   }
1443   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1444   return JNI_TRUE;
1445 }
1446 
1447 /*******************************************************************************
1448 **
1449 ** Function:        nfcManager_doInitialize
1450 **
1451 ** Description:     Turn on NFC.
1452 **                  e: JVM environment.
1453 **                  o: Java object.
1454 **
1455 ** Returns:         True if ok.
1456 **
1457 *******************************************************************************/
nfcManager_doInitialize(JNIEnv * e,jobject o)1458 static jboolean nfcManager_doInitialize(JNIEnv* e, jobject o) {
1459   initializeGlobalDebugEnabledFlag();
1460   tNFA_STATUS stat = NFA_STATUS_OK;
1461   sIsRecovering = false;
1462 
1463   struct nfc_jni_native_data* nat = getNative(e, o);
1464 
1465   PowerSwitch& powerSwitch = PowerSwitch::getInstance();
1466 
1467   if (sIsNfaEnabled) {
1468     LOG(DEBUG) << StringPrintf("%s: already enabled", __func__);
1469     goto TheEnd;
1470   }
1471   if (gPartialInitMode != ENABLE_MODE_DEFAULT) {
1472     return doPartialInit();
1473   }
1474   powerSwitch.initialize(PowerSwitch::FULL_POWER);
1475 
1476   {
1477 
1478     NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1479     theInstance.Initialize();  // start GKI, NCI task, NFC task
1480 
1481     {
1482       SyncEventGuard guard(sNfaEnableEvent);
1483       tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
1484 
1485       NFA_Init(halFuncEntries);
1486 
1487       if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1488         LOG(DEBUG) << StringPrintf("%s: register VS callbacks", __func__);
1489         NFA_RegVSCback(true, &nfaVSCallback);
1490       }
1491 
1492       if (gIsDtaEnabled == true) {
1493         // Allows to set appl_dta_mode_flag
1494         LOG(DEBUG) << StringPrintf("%s: DTA; set dta flag in core stack",
1495                                    __func__);
1496         NFA_EnableDtamode((tNFA_eDtaModes)NFA_DTA_APPL_MODE);
1497       }
1498 
1499       stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
1500       if (stat == NFA_STATUS_OK) {
1501         sNfaEnableEvent.wait();  // wait for NFA command to finish
1502       }
1503     }
1504 
1505     if (stat == NFA_STATUS_OK) {
1506       // sIsNfaEnabled indicates whether stack started successfully
1507       if (sIsNfaEnabled) {
1508         sRoutingInitialized =
1509             RoutingManager::getInstance().initialize(getNative(e, o));
1510         nativeNfcTag_registerNdefTypeHandler();
1511         NfcTag::getInstance().initialize(getNative(e, o));
1512         HciEventManager::getInstance().initialize(getNative(e, o));
1513         NativeWlcManager::getInstance().initialize(getNative(e, o));
1514         NativeT4tNfcee::getInstance().initialize();
1515 
1516         /////////////////////////////////////////////////////////////////////////////////
1517         // Add extra configuration here (work-arounds, etc.)
1518 
1519         if (nat) {
1520           nat->tech_mask =
1521               NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
1522           LOG(DEBUG) << StringPrintf("%s: tag polling tech mask=0x%X", __func__,
1523                                      nat->tech_mask);
1524 
1525           // if this value exists, set polling interval.
1526           nat->discovery_duration = NfcConfig::getUnsigned(
1527               NAME_NFA_DM_DISC_DURATION_POLL, DEFAULT_DISCOVERY_DURATION);
1528           NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1529         } else {
1530           LOG(ERROR) << StringPrintf("nat is null");
1531         }
1532 
1533         // get LF_T3T_MAX
1534         {
1535           SyncEventGuard guard(gNfaGetConfigEvent);
1536           tNFA_PMID configParam[1] = {NCI_PARAM_ID_LF_T3T_MAX};
1537           stat = NFA_GetConfig(1, configParam);
1538           if (stat == NFA_STATUS_OK) {
1539             gNfaGetConfigEvent.wait();
1540             if (gCurrentConfigLen >= 4 ||
1541                 gConfig[1] == NCI_PARAM_ID_LF_T3T_MAX) {
1542               LOG(DEBUG) << StringPrintf("%s: lfT3tMax=%d", __func__,
1543                                          gConfig[3]);
1544               sLfT3tMax = gConfig[3];
1545             }
1546           }
1547         }
1548 
1549         prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
1550 
1551         // Do custom NFCA startup configuration.
1552         doStartupConfig();
1553 #ifdef DTA_ENABLED
1554         NfcDta::getInstance().setNfccConfigParams();
1555 #endif /* DTA_ENABLED */
1556         goto TheEnd;
1557       }
1558     }
1559 
1560     if (gIsDtaEnabled == true) {
1561       LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
1562                                  __func__);
1563       NFA_DisableDtamode();
1564     }
1565 
1566     LOG(ERROR) << StringPrintf("%s: fail nfa enable; error=0x%X", __func__,
1567                                stat);
1568 
1569     if (sIsNfaEnabled) {
1570       stat = NFA_Disable(FALSE /* ungraceful */);
1571     }
1572 
1573     theInstance.Finalize();
1574   }
1575 
1576 TheEnd:
1577   if (sIsNfaEnabled) {
1578     PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER);
1579   }
1580   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1581   return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE;
1582 }
1583 
nfcManager_doSetPartialInitMode(JNIEnv *,jobject,jint mode)1584 static void nfcManager_doSetPartialInitMode(JNIEnv*, jobject, jint mode) {
1585   gPartialInitMode = mode;
1586 }
1587 
nfcManager_doEnableDtaMode(JNIEnv *,jobject)1588 static void nfcManager_doEnableDtaMode(JNIEnv*, jobject) {
1589   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1590   gIsDtaEnabled = true;
1591 }
1592 
nfcManager_doDisableDtaMode(JNIEnv *,jobject)1593 static void nfcManager_doDisableDtaMode(JNIEnv*, jobject) {
1594   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1595   gIsDtaEnabled = false;
1596 }
1597 
nfcManager_doFactoryReset(JNIEnv *,jobject)1598 static void nfcManager_doFactoryReset(JNIEnv*, jobject) {
1599   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1600   theInstance.FactoryReset();
1601 }
1602 
nfcManager_doShutdown(JNIEnv *,jobject)1603 static void nfcManager_doShutdown(JNIEnv*, jobject) {
1604   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1605   NativeT4tNfcee::getInstance().onNfccShutdown();
1606   theInstance.DeviceShutdown();
1607 }
1608 
nfcManager_configNfccConfigControl(bool flag)1609 static void nfcManager_configNfccConfigControl(bool flag) {
1610     // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1611     if (NFC_GetNCIVersion() != NCI_VERSION_1_0) {
1612         uint8_t nfa_set_config[] = { 0x00 };
1613 
1614         nfa_set_config[0] = (flag == true ? 1 : 0);
1615 
1616         tNFA_STATUS status = NFA_SetConfig(NCI_PARAM_ID_NFCC_CONFIG_CONTROL,
1617                                            sizeof(nfa_set_config),
1618                                            &nfa_set_config[0]);
1619         if (status != NFA_STATUS_OK) {
1620             LOG(ERROR) << __func__
1621             << ": Failed to configure NFCC_CONFIG_CONTROL";
1622         }
1623     }
1624 }
1625 
1626 /*******************************************************************************
1627 **
1628 ** Function:        nfcManager_enableDiscovery
1629 **
1630 ** Description:     Start polling and listening for devices.
1631 **                  e: JVM environment.
1632 **                  o: Java object.
1633 **                  technologies_mask: the bitmask of technologies for which to
1634 *enable discovery
1635 **                  enable_lptd: whether to enable low power polling (default:
1636 *false)
1637 **
1638 ** Returns:         None
1639 **
1640 *******************************************************************************/
nfcManager_enableDiscovery(JNIEnv * e,jobject o,jint technologies_mask,jboolean enable_lptd,jboolean reader_mode,jboolean enable_host_routing,jboolean restart)1641 static void nfcManager_enableDiscovery(JNIEnv* e, jobject o,
1642                                        jint technologies_mask,
1643                                        jboolean enable_lptd,
1644                                        jboolean reader_mode,
1645                                        jboolean enable_host_routing,
1646                                        jboolean restart) {
1647   tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
1648   struct nfc_jni_native_data* nat = getNative(e, o);
1649 
1650   if (technologies_mask == -1 && nat)
1651     tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask;
1652   else if (technologies_mask != -1)
1653     tech_mask = (tNFA_TECHNOLOGY_MASK)technologies_mask;
1654   LOG(DEBUG) << StringPrintf("%s: enter; tech_mask = %02x", __func__,
1655                              tech_mask);
1656 
1657   if (sDiscoveryEnabled && !restart) {
1658     LOG(ERROR) << StringPrintf("%s: already discovering", __func__);
1659     return;
1660   }
1661 
1662   PowerSwitch::getInstance().setLevel(PowerSwitch::FULL_POWER);
1663 
1664   if (sRfEnabled) {
1665     // Stop RF discovery to reconfigure
1666     startRfDiscovery(false);
1667   }
1668 
1669   // Check polling configuration
1670   if (tech_mask != 0) {
1671     stopPolling_rfDiscoveryDisabled();
1672     startPolling_rfDiscoveryDisabled(tech_mask);
1673 
1674     if (sPollingEnabled) {
1675       if (reader_mode && !sReaderModeEnabled) {
1676         sReaderModeEnabled = true;
1677         NFA_DisableListening();
1678 
1679         // configure NFCC_CONFIG_CONTROL- NFCC not allowed to manage RF configuration.
1680         nfcManager_configNfccConfigControl(false);
1681 
1682         NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
1683       } else if (!reader_mode && sReaderModeEnabled) {
1684         struct nfc_jni_native_data* nat = getNative(e, o);
1685         sReaderModeEnabled = false;
1686         NFA_EnableListening();
1687 
1688         // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1689         nfcManager_configNfccConfigControl(true);
1690 
1691         if (nat) {
1692           NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1693         } else {
1694           LOG(ERROR) << StringPrintf("nat is null");
1695         }
1696       }
1697     }
1698   } else {
1699     if (!reader_mode && sReaderModeEnabled) {
1700       LOG(DEBUG) << StringPrintf(
1701           "%s: if reader mode disable, enable listen again", __func__);
1702       struct nfc_jni_native_data* nat = getNative(e, o);
1703       sReaderModeEnabled = false;
1704       NFA_EnableListening();
1705 
1706       // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1707       nfcManager_configNfccConfigControl(true);
1708 
1709       if (nat) {
1710         NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1711       } else {
1712         LOG(ERROR) << StringPrintf("nat is null");
1713       }
1714     }
1715     // No technologies configured, stop polling
1716     stopPolling_rfDiscoveryDisabled();
1717   }
1718 
1719   // Check listen configuration
1720   if (enable_host_routing) {
1721     RoutingManager::getInstance().enableRoutingToHost();
1722     RoutingManager::getInstance().commitRouting();
1723   } else {
1724     RoutingManager::getInstance().disableRoutingToHost();
1725     RoutingManager::getInstance().commitRouting();
1726   }
1727   // Actually start discovery.
1728   startRfDiscovery(true);
1729   sDiscoveryEnabled = true;
1730 
1731   PowerSwitch::getInstance().setModeOn(PowerSwitch::DISCOVERY);
1732 
1733   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1734 }
1735 
1736 /*******************************************************************************
1737 **
1738 ** Function:        nfcManager_disableDiscovery
1739 **
1740 ** Description:     Stop polling and listening for devices.
1741 **                  e: JVM environment.
1742 **                  o: Java object.
1743 **
1744 ** Returns:         None
1745 **
1746 *******************************************************************************/
nfcManager_disableDiscovery(JNIEnv * e,jobject o)1747 void nfcManager_disableDiscovery(JNIEnv* e, jobject o) {
1748   tNFA_STATUS status = NFA_STATUS_OK;
1749   LOG(DEBUG) << StringPrintf("%s: enter;", __func__);
1750 
1751   if (sDiscoveryEnabled == false) {
1752     LOG(DEBUG) << StringPrintf("%s: already disabled", __func__);
1753     goto TheEnd;
1754   }
1755 
1756   // Stop RF Discovery.
1757   startRfDiscovery(false);
1758   sDiscoveryEnabled = false;
1759   if (sPollingEnabled) status = stopPolling_rfDiscoveryDisabled();
1760 
1761   // if nothing is active after this, then tell the controller to power down
1762   if (!PowerSwitch::getInstance().setModeOff(PowerSwitch::DISCOVERY))
1763     PowerSwitch::getInstance().setLevel(PowerSwitch::LOW_POWER);
1764 TheEnd:
1765   LOG(DEBUG) << StringPrintf("%s: exit: Status = 0x%X", __func__, status);
1766 }
1767 
1768 /*******************************************************************************
1769 **
1770 ** Function:        doPartialDeinit
1771 **
1772 ** Description:     Partial DeInit for mode TRANSPARENT, CE ..
1773 **
1774 ** Returns:         True if ok.
1775 **
1776 *******************************************************************************/
doPartialDeinit()1777 static jboolean doPartialDeinit() {
1778   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1779   tNFA_STATUS stat = NFA_STATUS_OK;
1780   sIsDisabling = true;
1781   if (sIsNfaEnabled) {
1782     SyncEventGuard guard(sNfaDisableEvent);
1783     stat = NFA_Disable(TRUE /* graceful */);
1784     if (stat == NFA_STATUS_OK) {
1785       LOG(DEBUG) << StringPrintf("%s: wait for completion", __func__);
1786       sNfaDisableEvent.wait();  // wait for NFA command to finish
1787     } else {
1788       LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__,
1789                                  stat);
1790     }
1791   }
1792   sIsDisabling = false;
1793 
1794   if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1795     LOG(DEBUG) << StringPrintf("%s: deregister VS callbacks", __func__);
1796     NFA_RegVSCback(false, &nfaVSCallback);
1797   }
1798 
1799   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1800   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1801   theInstance.Finalize();
1802 
1803   return stat == NFA_STATUS_OK ? JNI_TRUE : JNI_FALSE;
1804 }
1805 
1806 /*******************************************************************************
1807 **
1808 ** Function:        nfcManager_doDeinitialize
1809 **
1810 ** Description:     Turn off NFC.
1811 **                  e: JVM environment.
1812 **                  o: Java object.
1813 **
1814 ** Returns:         True if ok.
1815 **
1816 *******************************************************************************/
nfcManager_doDeinitialize(JNIEnv *,jobject)1817 static jboolean nfcManager_doDeinitialize(JNIEnv*, jobject) {
1818   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1819   if (gPartialInitMode != ENABLE_MODE_DEFAULT) {
1820     return doPartialDeinit();
1821   }
1822   sIsDisabling = true;
1823 
1824   NativeT4tNfcee::getInstance().onNfccShutdown();
1825   if (!recovery_option || !sIsRecovering) {
1826     RoutingManager::getInstance().onNfccShutdown();
1827   }
1828   PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
1829   HciEventManager::getInstance().finalize();
1830 
1831   if (sIsNfaEnabled) {
1832     SyncEventGuard guard(sNfaDisableEvent);
1833 
1834     if (gIsDtaEnabled == true) {
1835       LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
1836                                  __func__);
1837       NFA_DisableDtamode();
1838     }
1839 
1840     tNFA_STATUS stat = NFA_Disable(TRUE /* graceful */);
1841     if (stat == NFA_STATUS_OK) {
1842       LOG(DEBUG) << StringPrintf("%s: wait for completion", __func__);
1843       sNfaDisableEvent.wait();  // wait for NFA command to finish
1844     } else {
1845       LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__,
1846                                  stat);
1847     }
1848   }
1849   nativeNfcTag_abortWaits();
1850   NfcTag::getInstance().abort();
1851   sAbortConnlessWait = true;
1852   sIsNfaEnabled = false;
1853   sRoutingInitialized = false;
1854   sDiscoveryEnabled = false;
1855   sPollingEnabled = false;
1856   sIsDisabling = false;
1857   sReaderModeEnabled = false;
1858   gActivated = false;
1859   sLfT3tMax = 0;
1860 
1861   {
1862     // unblock NFA_EnablePolling() and NFA_DisablePolling()
1863     SyncEventGuard guard(sNfaEnableDisablePollingEvent);
1864     sNfaEnableDisablePollingEvent.notifyOne();
1865   }
1866 
1867   if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1868     LOG(DEBUG) << StringPrintf("%s: deregister VS callbacks", __func__);
1869     NFA_RegVSCback(false, &nfaVSCallback);
1870   }
1871 
1872   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1873   theInstance.Finalize();
1874 
1875   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1876   return JNI_TRUE;
1877 }
1878 
1879 /*******************************************************************************
1880 **
1881 ** Function:        isListenMode
1882 **
1883 ** Description:     Indicates whether the activation data indicates it is
1884 **                  listen mode.
1885 **
1886 ** Returns:         True if this listen mode.
1887 **
1888 *******************************************************************************/
isListenMode(tNFA_ACTIVATED & activated)1889 static bool isListenMode(tNFA_ACTIVATED& activated) {
1890   return (
1891       (NFC_DISCOVERY_TYPE_LISTEN_A ==
1892        activated.activate_ntf.rf_tech_param.mode) ||
1893       (NFC_DISCOVERY_TYPE_LISTEN_B ==
1894        activated.activate_ntf.rf_tech_param.mode) ||
1895       (NFC_DISCOVERY_TYPE_LISTEN_F ==
1896        activated.activate_ntf.rf_tech_param.mode) ||
1897       (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 ==
1898        activated.activate_ntf.rf_tech_param.mode) ||
1899       (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME ==
1900        activated.activate_ntf.rf_tech_param.mode) ||
1901       (NFC_INTERFACE_EE_DIRECT_RF == activated.activate_ntf.intf_param.type));
1902 }
1903 
1904 /*******************************************************************************
1905 **
1906 ** Function:        nfcManager_doAbort
1907 **
1908 ** Description:     Not used.
1909 **
1910 ** Returns:         None
1911 **
1912 *******************************************************************************/
nfcManager_doAbort(JNIEnv * e,jobject,jstring msg)1913 static void nfcManager_doAbort(JNIEnv* e, jobject, jstring msg) {
1914   ScopedUtfChars message = {e, msg};
1915   e->FatalError(message.c_str());
1916   abort();  // <-- Unreachable
1917 }
1918 
1919 /*******************************************************************************
1920 **
1921 ** Function:        nfcManager_doDownload
1922 **
1923 ** Description:     Download firmware patch files.  Do not turn on NFC.
1924 **
1925 ** Returns:         True if ok.
1926 **
1927 *******************************************************************************/
nfcManager_doDownload(JNIEnv *,jobject)1928 static jboolean nfcManager_doDownload(JNIEnv*, jobject) {
1929   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1930   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1931   bool result = JNI_FALSE;
1932   theInstance.Initialize();  // start GKI, NCI task, NFC task
1933   if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1934     tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
1935     NFA_Partial_Init(halFuncEntries, gPartialInitMode);
1936     NFA_RegVSCback(true, &nfaVSCallback);
1937   }
1938   result = theInstance.DownloadFirmware();
1939   if (android_nfc_nfc_read_polling_loop() || android_nfc_nfc_vendor_cmd()) {
1940     NFA_RegVSCback(false, &nfaVSCallback);
1941   }
1942   theInstance.Finalize();
1943   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1944   return result;
1945 }
1946 
1947 /*******************************************************************************
1948 **
1949 ** Function:        nfcManager_doResetTimeouts
1950 **
1951 ** Description:     Not used.
1952 **
1953 ** Returns:         None
1954 **
1955 *******************************************************************************/
nfcManager_doResetTimeouts(JNIEnv *,jobject)1956 static void nfcManager_doResetTimeouts(JNIEnv*, jobject) {
1957   LOG(DEBUG) << StringPrintf("%s", __func__);
1958   NfcTag::getInstance().resetAllTransceiveTimeouts();
1959 }
1960 
1961 /*******************************************************************************
1962 **
1963 ** Function:        nfcManager_doSetTimeout
1964 **
1965 ** Description:     Set timeout value.
1966 **                  e: JVM environment.
1967 **                  o: Java object.
1968 **                  tech: technology ID.
1969 **                  timeout: Timeout value.
1970 **
1971 ** Returns:         True if ok.
1972 **
1973 *******************************************************************************/
nfcManager_doSetTimeout(JNIEnv *,jobject,jint tech,jint timeout)1974 static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint tech, jint timeout) {
1975   if (timeout <= 0) {
1976     LOG(ERROR) << StringPrintf("%s: Timeout must be positive.", __func__);
1977     return false;
1978   }
1979   LOG(DEBUG) << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech,
1980                              timeout);
1981   NfcTag::getInstance().setTransceiveTimeout(tech, timeout);
1982   return true;
1983 }
1984 
1985 /*******************************************************************************
1986 **
1987 ** Function:        nfcManager_doGetTimeout
1988 **
1989 ** Description:     Get timeout value.
1990 **                  e: JVM environment.
1991 **                  o: Java object.
1992 **                  tech: technology ID.
1993 **
1994 ** Returns:         Timeout value.
1995 **
1996 *******************************************************************************/
nfcManager_doGetTimeout(JNIEnv *,jobject,jint tech)1997 static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint tech) {
1998   int timeout = NfcTag::getInstance().getTransceiveTimeout(tech);
1999   LOG(DEBUG) << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech,
2000                              timeout);
2001   return timeout;
2002 }
2003 
2004 /*******************************************************************************
2005 **
2006 ** Function:        nfcManager_doDump
2007 **
2008 ** Description:     Get libnfc-nci dump
2009 **                  e: JVM environment.
2010 **                  obj: Java object.
2011 **                  fdobj: File descriptor to be used
2012 **
2013 ** Returns:         Void
2014 **
2015 *******************************************************************************/
nfcManager_doDump(JNIEnv * e,jobject obj,jobject fdobj)2016 static void nfcManager_doDump(JNIEnv* e, jobject obj, jobject fdobj) {
2017   int fd = jniGetFDFromFileDescriptor(e, fdobj);
2018   if (fd < 0) return;
2019 
2020   NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
2021   theInstance.Dump(fd);
2022 }
2023 
nfcManager_doGetNciVersion(JNIEnv *,jobject)2024 static jint nfcManager_doGetNciVersion(JNIEnv*, jobject) {
2025   return NFC_GetNCIVersion();
2026 }
2027 
nfcManager_doSetScreenState(JNIEnv * e,jobject o,jint screen_state_mask,jboolean alwaysPoll)2028 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
2029                                         jint screen_state_mask,
2030                                         jboolean alwaysPoll) {
2031   tNFA_STATUS status = NFA_STATUS_OK;
2032   uint8_t state = (screen_state_mask & NFA_SCREEN_STATE_MASK);
2033   uint8_t discovry_param =
2034       NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
2035   sIsAlwaysPolling = alwaysPoll;
2036 
2037   LOG(DEBUG) << StringPrintf(
2038       "%s: state = %d prevScreenState= %d, discovry_param = %d", __FUNCTION__,
2039       state, prevScreenState, discovry_param);
2040 
2041   if (prevScreenState == state) {
2042     LOG(DEBUG) << StringPrintf(
2043         "New screen state is same as previous state. No action taken");
2044     return;
2045   }
2046 
2047   if (sIsDisabling || !sIsNfaEnabled ||
2048       (NFC_GetNCIVersion() != NCI_VERSION_2_0)) {
2049     prevScreenState = state;
2050     return;
2051   }
2052 
2053   // skip remaining SetScreenState tasks when trying to silent recover NFCC
2054   if (recovery_option && sIsRecovering) {
2055     prevScreenState = state;
2056     return;
2057   }
2058 
2059   if (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED ||
2060       prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED ||
2061       prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) {
2062     SyncEventGuard guard(sNfaSetPowerSubState);
2063     status = NFA_SetPowerSubStateForScreenState(state);
2064     if (status != NFA_STATUS_OK) {
2065       LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
2066                                  __FUNCTION__, status);
2067       return;
2068     } else {
2069       sNfaSetPowerSubState.wait();
2070     }
2071   }
2072 
2073   // skip remaining SetScreenState tasks when trying to silent recover NFCC
2074   if (recovery_option && sIsRecovering) {
2075     prevScreenState = state;
2076     return;
2077   }
2078 
2079   if (state == NFA_SCREEN_STATE_OFF_LOCKED ||
2080       state == NFA_SCREEN_STATE_OFF_UNLOCKED) {
2081     // disable poll and enable listen on DH 0x00
2082     discovry_param =
2083         NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_ENABLE_MASK;
2084   }
2085 
2086   if (state == NFA_SCREEN_STATE_ON_LOCKED) {
2087     // disable poll and enable listen on DH 0x00
2088     discovry_param =
2089         (screen_state_mask & NFA_SCREEN_POLLING_TAG_MASK)
2090             ? (NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK)
2091             : (NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_ENABLE_MASK);
2092   }
2093 
2094   if (state == NFA_SCREEN_STATE_ON_UNLOCKED) {
2095     // enable both poll and listen on DH 0x01
2096     discovry_param =
2097         NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
2098   }
2099 
2100   if (!sIsAlwaysPolling) {
2101     SyncEventGuard guard(gNfaSetConfigEvent);
2102     status = NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM,
2103                            NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param);
2104     if (status == NFA_STATUS_OK) {
2105       gNfaSetConfigEvent.wait();
2106     } else {
2107       LOG(ERROR) << StringPrintf("%s: Failed to update CON_DISCOVER_PARAM",
2108                                  __FUNCTION__);
2109       return;
2110     }
2111   }
2112   // skip remaining SetScreenState tasks when trying to silent recover NFCC
2113   if (recovery_option && sIsRecovering) {
2114     prevScreenState = state;
2115     return;
2116   }
2117 
2118   if (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) {
2119     SyncEventGuard guard(sNfaSetPowerSubState);
2120     status = NFA_SetPowerSubStateForScreenState(state);
2121     if (status != NFA_STATUS_OK) {
2122       LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
2123                                  __FUNCTION__, status);
2124     } else {
2125       sNfaSetPowerSubState.wait();
2126     }
2127   }
2128 
2129   // skip remaining SetScreenState tasks when trying to silent recover NFCC
2130   if (recovery_option && sIsRecovering) {
2131     prevScreenState = state;
2132     return;
2133   }
2134 
2135   if ((state == NFA_SCREEN_STATE_OFF_LOCKED ||
2136        state == NFA_SCREEN_STATE_OFF_UNLOCKED) &&
2137       (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED ||
2138        prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) &&
2139       (!sSeRfActive)) {
2140     // screen turns off, disconnect tag if connected
2141     nativeNfcTag_doDisconnect(NULL, NULL);
2142   }
2143 
2144   prevScreenState = state;
2145 }
2146 
2147 /*******************************************************************************
2148 **
2149 ** Function:        nfcManager_getIsoDepMaxTransceiveLength
2150 **
2151 ** Description:     Get maximum ISO DEP Transceive Length supported by the NFC
2152 **                  chip. Returns default 261 bytes if the property is not set.
2153 **
2154 ** Returns:         max value.
2155 **
2156 *******************************************************************************/
nfcManager_getIsoDepMaxTransceiveLength(JNIEnv *,jobject)2157 static jint nfcManager_getIsoDepMaxTransceiveLength(JNIEnv*, jobject) {
2158   /* Check if extended APDU is supported by the chip.
2159    * If not, default value is returned.
2160    * The maximum length of a default IsoDep frame consists of:
2161    * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
2162    */
2163   return NfcConfig::getUnsigned(NAME_ISO_DEP_MAX_TRANSCEIVE, 261);
2164 }
2165 
2166 /*******************************************************************************
2167  **
2168  ** Function:        nfcManager_getAidTableSize
2169  ** Description:     Get the maximum supported size for AID routing table.
2170  **
2171  **                  e: JVM environment.
2172  **                  o: Java object.
2173  **
2174  *******************************************************************************/
nfcManager_getAidTableSize(JNIEnv *,jobject)2175 static jint nfcManager_getAidTableSize(JNIEnv*, jobject) {
2176   return NFA_GetAidTableSize();
2177 }
2178 
2179 /*******************************************************************************
2180 **
2181 ** Function:        nfcManager_IsMultiTag
2182 **
2183 ** Description:     Check if it a multi tag case.
2184 **                  e: JVM environment.
2185 **                  o: Java object.
2186 **
2187 ** Returns:         None.
2188 **
2189 *******************************************************************************/
nfcManager_isMultiTag()2190 static bool nfcManager_isMultiTag() {
2191   LOG(DEBUG) << StringPrintf("%s: enter mNumRfDiscId = %d", __func__,
2192                              NfcTag::getInstance().mNumRfDiscId);
2193   bool status = false;
2194   if (NfcTag::getInstance().mNumRfDiscId > 1) status = true;
2195   LOG(DEBUG) << StringPrintf("isMultiTag = %d", status);
2196   return status;
2197 }
2198 
2199 /*******************************************************************************
2200 **
2201 ** Function:        nfcManager_doStartStopPolling
2202 **
2203 ** Description:     Start or stop NFC RF polling
2204 **                  e: JVM environment.
2205 **                  o: Java object.
2206 **                  start: start or stop RF polling
2207 **
2208 ** Returns:         None
2209 **
2210 *******************************************************************************/
nfcManager_doStartStopPolling(JNIEnv * e,jobject o,jboolean start)2211 static void nfcManager_doStartStopPolling(JNIEnv* e, jobject o,
2212                                           jboolean start) {
2213   startStopPolling(start);
2214 }
2215 
2216 /*******************************************************************************
2217 **
2218 ** Function:        nfcManager_doSetNfcSecure
2219 **
2220 ** Description:     Set NfcSecure enable/disable.
2221 **                  e: JVM environment.
2222 **                  o: Java object.
2223 **                  enable: Sets true/false to enable/disable NfcSecure
2224 **                  It only updates the routing table cache without commit to
2225 **                  NFCC.
2226 **
2227 ** Returns:         True always
2228 **
2229 *******************************************************************************/
nfcManager_doSetNfcSecure(JNIEnv * e,jobject o,jboolean enable)2230 static jboolean nfcManager_doSetNfcSecure(JNIEnv* e, jobject o,
2231                                           jboolean enable) {
2232   RoutingManager& routingManager = RoutingManager::getInstance();
2233   routingManager.setNfcSecure(enable);
2234   if (sRoutingInitialized) {
2235     routingManager.disableRoutingToHost();
2236     routingManager.updateRoutingTable();
2237     routingManager.enableRoutingToHost();
2238   }
2239   return true;
2240 }
2241 
nfcManager_doSetNfceePowerAndLinkCtrl(JNIEnv * e,jobject o,jboolean enable)2242 static void nfcManager_doSetNfceePowerAndLinkCtrl(JNIEnv* e, jobject o,
2243                                                   jboolean enable) {
2244   RoutingManager& routingManager = RoutingManager::getInstance();
2245   if (enable) {
2246     routingManager.eeSetPwrAndLinkCtrl(
2247         (uint8_t)always_on_nfcee_power_and_link_conf);
2248   } else {
2249     routingManager.eeSetPwrAndLinkCtrl(
2250         (uint8_t)disable_always_on_nfcee_power_and_link_conf);
2251   }
2252 }
2253 
2254 /*******************************************************************************
2255 **
2256 ** Function:        nfcManager_doGetMaxRoutingTableSize
2257 **
2258 ** Description:     Retrieve the max routing table size from cache
2259 **                  e: JVM environment.
2260 **                  o: Java object.
2261 **
2262 ** Returns:         Max Routing Table size
2263 **
2264 *******************************************************************************/
nfcManager_doGetMaxRoutingTableSize(JNIEnv * e,jobject o)2265 static jint nfcManager_doGetMaxRoutingTableSize(JNIEnv* e, jobject o) {
2266   return lmrt_get_max_size();
2267 }
2268 
2269 /*******************************************************************************
2270 **
2271 ** Function:        nfcManager_doGetRoutingTable
2272 **
2273 ** Description:     Retrieve the committed listen mode routing configuration
2274 **                  e: JVM environment.
2275 **                  o: Java object.
2276 **
2277 ** Returns:         Committed listen mode routing configuration
2278 **
2279 *******************************************************************************/
nfcManager_doGetRoutingTable(JNIEnv * e,jobject o)2280 static jbyteArray nfcManager_doGetRoutingTable(JNIEnv* e, jobject o) {
2281   std::vector<uint8_t>* routingTable = lmrt_get_tlvs();
2282 
2283   CHECK(e);
2284   jbyteArray rtJavaArray = e->NewByteArray((*routingTable).size());
2285   CHECK(rtJavaArray);
2286   e->SetByteArrayRegion(rtJavaArray, 0, (*routingTable).size(),
2287                         (jbyte*)&(*routingTable)[0]);
2288 
2289   return rtJavaArray;
2290 }
2291 
nfcManager_clearRoutingEntry(JNIEnv * e,jobject o,jint clearFlags)2292 static void nfcManager_clearRoutingEntry(JNIEnv* e, jobject o,
2293                                          jint clearFlags) {
2294   LOG(DEBUG) << StringPrintf("%s: clearFlags=0x%X", __func__, clearFlags);
2295   RoutingManager::getInstance().disableRoutingToHost();
2296   RoutingManager::getInstance().clearRoutingEntry(clearFlags);
2297 }
2298 
nfcManager_updateIsoDepProtocolRoute(JNIEnv * e,jobject o,jint route)2299 static void nfcManager_updateIsoDepProtocolRoute(JNIEnv* e, jobject o,
2300                                                  jint route) {
2301   LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2302   RoutingManager::getInstance().updateIsoDepProtocolRoute(route);
2303 }
2304 
nfcManager_updateTechnologyABFRoute(JNIEnv * e,jobject o,jint route,jint felicaRoute)2305 static void nfcManager_updateTechnologyABFRoute(JNIEnv* e, jobject o,
2306                                                 jint route, jint felicaRoute) {
2307   LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2308   RoutingManager::getInstance().updateTechnologyABFRoute(route, felicaRoute);
2309 }
2310 
nfcManager_updateSystemCodeRoute(JNIEnv * e,jobject o,jint route)2311 static void nfcManager_updateSystemCodeRoute(JNIEnv* e, jobject o,
2312                                                 jint route) {
2313   LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2314   RoutingManager::getInstance().updateSystemCodeRoute(route);
2315 }
2316 
2317 /*******************************************************************************
2318 **
2319 ** Function:        nfcManager_setDiscoveryTech
2320 **
2321 ** Description:     Temporarily changes the RF parameter
2322 **                  pollTech: RF tech parameters for poll mode
2323 **                  listenTech: RF tech parameters for listen mode
2324 **
2325 ** Returns:         None.
2326 **
2327 *******************************************************************************/
nfcManager_setDiscoveryTech(JNIEnv * e,jobject o,jint pollTech,jint listenTech)2328 static void nfcManager_setDiscoveryTech(JNIEnv* e, jobject o, jint pollTech,
2329                                         jint listenTech) {
2330   tNFA_STATUS nfaStat;
2331   bool isRevertPoll = false;
2332   bool isRevertListen = false;
2333   bool changeDefaultTech = false;
2334   LOG(DEBUG) << StringPrintf("%s  pollTech = 0x%x, listenTech = 0x%x", __func__,
2335                              pollTech, listenTech);
2336 
2337   if (pollTech < 0) isRevertPoll = true;
2338   if (listenTech < 0) isRevertListen = true;
2339   if (pollTech & FLAG_SET_DEFAULT_TECH || listenTech & FLAG_SET_DEFAULT_TECH)
2340     changeDefaultTech = true;
2341 
2342   // Need listen tech routing update in routing table
2343   // for addition of blocking bit
2344   RoutingManager::getInstance().setEeTechRouteUpdateRequired();
2345 
2346   nativeNfcTag_acquireRfInterfaceMutexLock();
2347   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2348 
2349   nfaStat = NFA_ChangeDiscoveryTech(pollTech, listenTech, isRevertPoll,
2350                                     isRevertListen, changeDefaultTech);
2351 
2352   if (nfaStat == NFA_STATUS_OK) {
2353     // wait for NFA_LISTEN_DISABLED_EVT
2354     sNfaEnableDisablePollingEvent.wait();
2355   } else {
2356     LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
2357                                nfaStat);
2358   }
2359   nativeNfcTag_releaseRfInterfaceMutexLock();
2360 }
2361 
2362 /*******************************************************************************
2363 **
2364 ** Function:        nfcManager_resetDiscoveryTech
2365 **
2366 ** Description:     Restores the RF tech to the state before
2367 **                  nfcManager_setDiscoveryTech was called
2368 **
2369 ** Returns:         None.
2370 **
2371 *******************************************************************************/
nfcManager_resetDiscoveryTech(JNIEnv * e,jobject o)2372 static void nfcManager_resetDiscoveryTech(JNIEnv* e, jobject o) {
2373   tNFA_STATUS nfaStat;
2374   LOG(DEBUG) << StringPrintf("%s : enter", __func__);
2375 
2376   // Need listen tech routing update in routing table
2377   // for addition of blocking bit
2378   RoutingManager::getInstance().setEeTechRouteUpdateRequired();
2379 
2380   nativeNfcTag_acquireRfInterfaceMutexLock();
2381   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2382 
2383   nfaStat = NFA_ChangeDiscoveryTech(0xFF, 0xFF, true, true, false);
2384 
2385   if (nfaStat == NFA_STATUS_OK) {
2386     // wait for NFA_LISTEN_DISABLED_EVT
2387     sNfaEnableDisablePollingEvent.wait();
2388   } else {
2389     LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
2390                                nfaStat);
2391   }
2392   nativeNfcTag_releaseRfInterfaceMutexLock();
2393 }
2394 
ncfManager_nativeEnableVendorNciNotifications(JNIEnv * env,jobject o,jboolean enable)2395 static void ncfManager_nativeEnableVendorNciNotifications(JNIEnv* env,
2396                                                           jobject o,
2397                                                           jboolean enable) {
2398   sEnableVendorNciNotifications = (enable == JNI_TRUE);
2399 }
2400 
nfcManager_dofetchActiveNfceeList(JNIEnv * e,jobject o)2401 static jobject nfcManager_dofetchActiveNfceeList(JNIEnv* e, jobject o) {
2402   (void)o;
2403   return NfceeManager::getInstance().getActiveNfceeList(e);
2404 }
2405 
nfcManager_nativeSendRawVendorCmd(JNIEnv * env,jobject o,jint mt,jint gid,jint oid,jbyteArray payload)2406 static jobject nfcManager_nativeSendRawVendorCmd(JNIEnv* env, jobject o,
2407                                                  jint mt, jint gid, jint oid,
2408                                                  jbyteArray payload) {
2409   LOG(DEBUG) << StringPrintf("%s : enter", __func__);
2410   ScopedByteArrayRO payloaBytes(env, payload);
2411   ScopedLocalRef<jclass> cls(env,
2412                              env->FindClass(gNfcVendorNciResponseClassName));
2413   jmethodID responseConstructor =
2414       env->GetMethodID(cls.get(), "<init>", "(BII[B)V");
2415 
2416   jbyte mStatus = NFA_STATUS_FAILED;
2417   jint resGid = 0;
2418   jint resOid = 0;
2419   jbyteArray resPayload = nullptr;
2420 
2421   sRawVendorCmdResponse.clear();
2422 
2423   std::vector<uint8_t> command;
2424   command.push_back((uint8_t)((mt << NCI_MT_SHIFT) | gid));
2425   command.push_back((uint8_t)oid);
2426   command.push_back((uint8_t)payloaBytes.size());
2427   if (payloaBytes.size() > 0) {
2428     command.insert(command.end(), &payloaBytes[0],
2429                    &payloaBytes[payloaBytes.size()]);
2430   }
2431 
2432   SyncEventGuard guard(gSendRawVsCmdEvent);
2433   mStatus = NFA_SendRawVsCommand(command.size(), command.data(),
2434                                  sendRawVsCmdCallback);
2435   if (mStatus == NFA_STATUS_OK) {
2436     if (gSendRawVsCmdEvent.wait(2000) == false) {
2437       mStatus = NFA_STATUS_FAILED;
2438       LOG(ERROR) << StringPrintf("%s: timeout ", __func__);
2439     }
2440 
2441     if (mStatus == NFA_STATUS_OK && sRawVendorCmdResponse.size() > 2) {
2442       resGid = sRawVendorCmdResponse[0] & NCI_GID_MASK;
2443       resOid = sRawVendorCmdResponse[1];
2444       const jsize len = static_cast<jsize>(sRawVendorCmdResponse[2]);
2445       if (sRawVendorCmdResponse.size() >= (sRawVendorCmdResponse[2] + 3)) {
2446         resPayload = env->NewByteArray(len);
2447         std::vector<uint8_t> payloadVec(sRawVendorCmdResponse.begin() + 3,
2448                                         sRawVendorCmdResponse.end());
2449         env->SetByteArrayRegion(
2450             resPayload, 0, len,
2451             reinterpret_cast<const jbyte*>(payloadVec.data()));
2452       } else {
2453         mStatus = NFA_STATUS_FAILED;
2454         LOG(ERROR) << StringPrintf("%s: invalid payload data", __func__);
2455       }
2456     } else {
2457       mStatus = NFA_STATUS_FAILED;
2458     }
2459   }
2460 
2461   LOG(DEBUG) << StringPrintf("%s : exit", __func__);
2462   return env->NewObject(cls.get(), responseConstructor, mStatus, resGid, resOid,
2463                         resPayload);
2464 }
2465 
sendRawVsCmdCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)2466 static void sendRawVsCmdCallback(uint8_t event, uint16_t param_len,
2467                                  uint8_t* p_param) {
2468   sRawVendorCmdResponse = std::vector<uint8_t>(p_param, p_param + param_len);
2469 
2470   SyncEventGuard guard(gSendRawVsCmdEvent);
2471   gSendRawVsCmdEvent.notifyOne();
2472 } /* namespace android */
2473 
2474 /*****************************************************************************
2475 **
2476 ** JNI functions for android-4.0.1_r1
2477 **
2478 *****************************************************************************/
2479 static JNINativeMethod gMethods[] = {
2480     {"doDownload", "()Z", (void*)nfcManager_doDownload},
2481 
2482     {"initializeNativeStructure", "()Z", (void*)nfcManager_initNativeStruc},
2483 
2484     {"doInitialize", "()Z", (void*)nfcManager_doInitialize},
2485 
2486     {"doSetPartialInitMode", "(I)V", (void*)nfcManager_doSetPartialInitMode},
2487 
2488     {"doDeinitialize", "()Z", (void*)nfcManager_doDeinitialize},
2489 
2490     {"sendRawFrame", "([B)Z", (void*)nfcManager_sendRawFrame},
2491 
2492     {"routeAid", "([BIII)Z", (void*)nfcManager_routeAid},
2493 
2494     {"unrouteAid", "([B)Z", (void*)nfcManager_unrouteAid},
2495 
2496     {"commitRouting", "()I", (void*)nfcManager_commitRouting},
2497 
2498     {"doRegisterT3tIdentifier", "([B)I",
2499      (void*)nfcManager_doRegisterT3tIdentifier},
2500 
2501     {"doDeregisterT3tIdentifier", "(I)V",
2502      (void*)nfcManager_doDeregisterT3tIdentifier},
2503 
2504     {"getLfT3tMax", "()I", (void*)nfcManager_getLfT3tMax},
2505 
2506     {"doEnableDiscovery", "(IZZZZ)V", (void*)nfcManager_enableDiscovery},
2507 
2508     {"doStartStopPolling", "(Z)V", (void*)nfcManager_doStartStopPolling},
2509 
2510     {"disableDiscovery", "()V", (void*)nfcManager_disableDiscovery},
2511 
2512     {"doSetTimeout", "(II)Z", (void*)nfcManager_doSetTimeout},
2513 
2514     {"doGetTimeout", "(I)I", (void*)nfcManager_doGetTimeout},
2515 
2516     {"doResetTimeouts", "()V", (void*)nfcManager_doResetTimeouts},
2517 
2518     {"doAbort", "(Ljava/lang/String;)V", (void*)nfcManager_doAbort},
2519 
2520     {"doSetScreenState", "(IZ)V", (void*)nfcManager_doSetScreenState},
2521 
2522     {"doDump", "(Ljava/io/FileDescriptor;)V", (void*)nfcManager_doDump},
2523 
2524     {"getNciVersion", "()I", (void*)nfcManager_doGetNciVersion},
2525     {"doEnableDtaMode", "()V", (void*)nfcManager_doEnableDtaMode},
2526     {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode},
2527     {"doFactoryReset", "()V", (void*)nfcManager_doFactoryReset},
2528     {"doShutdown", "()V", (void*)nfcManager_doShutdown},
2529 
2530     {"getIsoDepMaxTransceiveLength", "()I",
2531      (void*)nfcManager_getIsoDepMaxTransceiveLength},
2532 
2533     {"getAidTableSize", "()I", (void*)nfcManager_getAidTableSize},
2534 
2535     {"doSetNfcSecure", "(Z)Z", (void*)nfcManager_doSetNfcSecure},
2536 
2537     {"doSetNfceePowerAndLinkCtrl", "(Z)V",
2538      (void*)nfcManager_doSetNfceePowerAndLinkCtrl},
2539 
2540     {"doSetPowerSavingMode", "(Z)Z", (void*)nfcManager_doSetPowerSavingMode},
2541 
2542     {"getRoutingTable", "()[B", (void*)nfcManager_doGetRoutingTable},
2543 
2544     {"getMaxRoutingTableSize", "()I",
2545      (void*)nfcManager_doGetMaxRoutingTableSize},
2546 
2547     {"setObserveMode", "(Z)Z", (void*)nfcManager_setObserveMode},
2548 
2549     {"isObserveModeEnabled", "()Z", (void*)nfcManager_isObserveModeEnabled},
2550 
2551     {"isMultiTag", "()Z", (void*)nfcManager_isMultiTag},
2552 
2553     {"clearRoutingEntry", "(I)V", (void*)nfcManager_clearRoutingEntry},
2554 
2555     {"setIsoDepProtocolRoute", "(I)V",
2556      (void*)nfcManager_updateIsoDepProtocolRoute},
2557 
2558     {"setTechnologyABFRoute", "(II)V",
2559      (void*)nfcManager_updateTechnologyABFRoute},
2560 
2561     {"setSystemCodeRoute", "(I)V", (void*)nfcManager_updateSystemCodeRoute},
2562 
2563     {"setDiscoveryTech", "(II)V", (void*)nfcManager_setDiscoveryTech},
2564 
2565     {"resetDiscoveryTech", "()V", (void*)nfcManager_resetDiscoveryTech},
2566     {"nativeSendRawVendorCmd", "(III[B)Lcom/android/nfc/NfcVendorNciResponse;",
2567      (void*)nfcManager_nativeSendRawVendorCmd},
2568 
2569     {"dofetchActiveNfceeList", "()Ljava/util/Map;",
2570      (void*)nfcManager_dofetchActiveNfceeList},
2571 
2572     {"getProprietaryCaps", "()[B", (void*)nfcManager_getProprietaryCaps},
2573     {"enableVendorNciNotifications", "(Z)V",
2574      (void*)ncfManager_nativeEnableVendorNciNotifications},
2575     {"injectNtf", "([B)V", (void*)nfcManager_injectNtf},
2576 };
2577 
2578 /*******************************************************************************
2579 **
2580 ** Function:        register_com_android_nfc_NativeNfcManager
2581 **
2582 ** Description:     Regisgter JNI functions with Java Virtual Machine.
2583 **                  e: Environment of JVM.
2584 **
2585 ** Returns:         Status of registration.
2586 **
2587 *******************************************************************************/
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2588 int register_com_android_nfc_NativeNfcManager(JNIEnv* e) {
2589   LOG(DEBUG) << StringPrintf("%s: enter", __func__);
2590   PowerSwitch::getInstance().initialize(PowerSwitch::UNKNOWN_LEVEL);
2591   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
2592   return jniRegisterNativeMethods(e, gNativeNfcManagerClassName, gMethods,
2593                                   NELEM(gMethods));
2594 }
2595 
2596 /*******************************************************************************
2597 **
2598 ** Function:        startRfDiscovery
2599 **
2600 ** Description:     Ask stack to start polling and listening for devices.
2601 **                  isStart: Whether to start.
2602 **
2603 ** Returns:         None
2604 **
2605 *******************************************************************************/
startRfDiscovery(bool isStart)2606 void startRfDiscovery(bool isStart) {
2607   tNFA_STATUS status = NFA_STATUS_FAILED;
2608 
2609   LOG(DEBUG) << StringPrintf("%s: is start=%d", __func__, isStart);
2610   nativeNfcTag_acquireRfInterfaceMutexLock();
2611   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2612   status = isStart ? NFA_StartRfDiscovery() : NFA_StopRfDiscovery();
2613   if (status == NFA_STATUS_OK) {
2614     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_RF_DISCOVERY_xxxx_EVT
2615     sRfEnabled = isStart;
2616   } else {
2617     LOG(ERROR) << StringPrintf(
2618         "%s: Failed to start/stop RF discovery; error=0x%X", __func__, status);
2619   }
2620   nativeNfcTag_releaseRfInterfaceMutexLock();
2621 }
2622 
2623 /*******************************************************************************
2624 **
2625 ** Function:        isDiscoveryStarted
2626 **
2627 ** Description:     Indicates whether the discovery is started.
2628 **
2629 ** Returns:         True if discovery is started
2630 **
2631 *******************************************************************************/
isDiscoveryStarted()2632 bool isDiscoveryStarted() { return sRfEnabled; }
2633 
2634 /*******************************************************************************
2635 **
2636 ** Function:        doStartupConfig
2637 **
2638 ** Description:     Configure the NFC controller.
2639 **
2640 ** Returns:         None
2641 **
2642 *******************************************************************************/
doStartupConfig()2643 void doStartupConfig() {
2644   // configure RF polling frequency for each technology
2645   static tNFA_DM_DISC_FREQ_CFG nfa_dm_disc_freq_cfg;
2646   // values in the polling_frequency[] map to members of nfa_dm_disc_freq_cfg
2647   std::vector<uint8_t> polling_frequency;
2648   if (NfcConfig::hasKey(NAME_POLL_FREQUENCY))
2649     polling_frequency = NfcConfig::getBytes(NAME_POLL_FREQUENCY);
2650   if (polling_frequency.size() == 8) {
2651     LOG(DEBUG) << StringPrintf("%s: polling frequency", __func__);
2652     memset(&nfa_dm_disc_freq_cfg, 0, sizeof(nfa_dm_disc_freq_cfg));
2653     nfa_dm_disc_freq_cfg.pa = polling_frequency[0];
2654     nfa_dm_disc_freq_cfg.pb = polling_frequency[1];
2655     nfa_dm_disc_freq_cfg.pf = polling_frequency[2];
2656     nfa_dm_disc_freq_cfg.pi93 = polling_frequency[3];
2657     nfa_dm_disc_freq_cfg.pbp = polling_frequency[4];
2658     nfa_dm_disc_freq_cfg.pk = polling_frequency[5];
2659     nfa_dm_disc_freq_cfg.paa = polling_frequency[6];
2660     nfa_dm_disc_freq_cfg.pfa = polling_frequency[7];
2661     p_nfa_dm_rf_disc_freq_cfg = &nfa_dm_disc_freq_cfg;
2662   }
2663 
2664   // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
2665   nfcManager_configNfccConfigControl(true);
2666 
2667 }
2668 
2669 /*******************************************************************************
2670 **
2671 ** Function:        nfcManager_isNfcActive
2672 **
2673 ** Description:     Used externaly to determine if NFC is active or not.
2674 **
2675 ** Returns:         'true' if the NFC stack is running, else 'false'.
2676 **
2677 *******************************************************************************/
nfcManager_isNfcActive()2678 bool nfcManager_isNfcActive() { return sIsNfaEnabled; }
2679 
2680 /*******************************************************************************
2681 **
2682 ** Function:        startStopPolling
2683 **
2684 ** Description:     Start or stop polling.
2685 **                  isStartPolling: true to start polling; false to stop
2686 *polling.
2687 **
2688 ** Returns:         None.
2689 **
2690 *******************************************************************************/
startStopPolling(bool isStartPolling)2691 void startStopPolling(bool isStartPolling) {
2692   tNFA_STATUS status = NFA_STATUS_FAILED;
2693   uint8_t discovry_param = 0;
2694   LOG(DEBUG) << StringPrintf("%s: enter; isStart=%u", __func__, isStartPolling);
2695 
2696   if (NFC_GetNCIVersion() >= NCI_VERSION_2_0) {
2697     SyncEventGuard guard(gNfaSetConfigEvent);
2698     if (isStartPolling) {
2699       discovry_param =
2700           NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
2701     } else {
2702       discovry_param =
2703           NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_DISABLE_MASK;
2704     }
2705     status = NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM,
2706                            NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param);
2707     if (status == NFA_STATUS_OK) {
2708       gNfaSetConfigEvent.wait();
2709     } else {
2710       LOG(ERROR) << StringPrintf("%s: Failed to update CON_DISCOVER_PARAM",
2711                                  __FUNCTION__);
2712     }
2713   } else {
2714     startRfDiscovery(false);
2715     if (isStartPolling)
2716       startPolling_rfDiscoveryDisabled(0);
2717     else
2718       stopPolling_rfDiscoveryDisabled();
2719     startRfDiscovery(true);
2720   }
2721   LOG(DEBUG) << StringPrintf("%s: exit", __func__);
2722 }
2723 
startPolling_rfDiscoveryDisabled(tNFA_TECHNOLOGY_MASK tech_mask)2724 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
2725     tNFA_TECHNOLOGY_MASK tech_mask) {
2726   tNFA_STATUS stat = NFA_STATUS_FAILED;
2727 
2728   if (tech_mask == 0)
2729     tech_mask =
2730         NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
2731 
2732   nativeNfcTag_acquireRfInterfaceMutexLock();
2733   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2734   LOG(DEBUG) << StringPrintf("%s: enable polling", __func__);
2735   stat = NFA_EnablePolling(tech_mask);
2736   if (stat == NFA_STATUS_OK) {
2737     LOG(DEBUG) << StringPrintf("%s: wait for enable event", __func__);
2738     sPollingEnabled = true;
2739     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_POLL_ENABLED_EVT
2740   } else {
2741     LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", __func__,
2742                                stat);
2743   }
2744   nativeNfcTag_releaseRfInterfaceMutexLock();
2745 
2746   return stat;
2747 }
2748 
stopPolling_rfDiscoveryDisabled()2749 static tNFA_STATUS stopPolling_rfDiscoveryDisabled() {
2750   tNFA_STATUS stat = NFA_STATUS_FAILED;
2751 
2752   nativeNfcTag_acquireRfInterfaceMutexLock();
2753   SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2754   LOG(DEBUG) << StringPrintf("%s: disable polling", __func__);
2755   stat = NFA_DisablePolling();
2756   if (stat == NFA_STATUS_OK) {
2757     sPollingEnabled = false;
2758     sNfaEnableDisablePollingEvent.wait();  // wait for NFA_POLL_DISABLED_EVT
2759   } else {
2760     LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
2761                                stat);
2762   }
2763   nativeNfcTag_releaseRfInterfaceMutexLock();
2764 
2765   return stat;
2766 }
2767 
nfcManager_doSetPowerSavingMode(JNIEnv * e,jobject o,bool flag)2768 static jboolean nfcManager_doSetPowerSavingMode(JNIEnv* e, jobject o,
2769                                                 bool flag) {
2770   LOG(DEBUG) << StringPrintf("%s: enter; ", __func__);
2771   uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP,
2772                    NCI_MSG_PROP_ANDROID, NCI_ANDROID_POWER_SAVING_PARAM_SIZE,
2773                    NCI_ANDROID_POWER_SAVING,
2774                    NCI_ANDROID_POWER_SAVING_PARAM_DISABLE};
2775   cmd[4] = flag ? NCI_ANDROID_POWER_SAVING_PARAM_ENABLE
2776                 : NCI_ANDROID_POWER_SAVING_PARAM_DISABLE;
2777 
2778   SyncEventGuard guard(gNfaVsCommand);
2779   tNFA_STATUS status =
2780       NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaSendRawVsCmdCallback);
2781   if (status == NFA_STATUS_OK) {
2782     gNfaVsCommand.wait();
2783   } else {
2784     LOG(ERROR) << StringPrintf("%s: Failed to set power-saving mode", __func__);
2785     gVSCmdStatus = NFA_STATUS_FAILED;
2786   }
2787   return gVSCmdStatus == NFA_STATUS_OK;
2788 }
2789 
nfcManager_getProprietaryCaps(JNIEnv * e,jobject o)2790 static jbyteArray nfcManager_getProprietaryCaps(JNIEnv* e, jobject o) {
2791   LOG(DEBUG) << StringPrintf("%s: enter; ", __func__);
2792   uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP,
2793                    NCI_MSG_PROP_ANDROID, NCI_ANDROID_GET_CAPS_PARAM_SIZE,
2794                    NCI_ANDROID_GET_CAPS};
2795   SyncEventGuard guard(gNfaVsCommand);
2796 
2797   tNFA_STATUS status = NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaVSCallback);
2798   if (status == NFA_STATUS_OK) {
2799     if (!gNfaVsCommand.wait(1000)) {
2800       LOG(ERROR) << StringPrintf(
2801           "%s: Timed out waiting for a response to get caps ",
2802           __FUNCTION__);
2803       gVSCmdStatus = NFA_STATUS_FAILED;
2804     }
2805   } else {
2806     LOG(ERROR) << StringPrintf("%s: Failed to get caps", __func__);
2807     gVSCmdStatus = NFA_STATUS_FAILED;
2808   }
2809   CHECK(e);
2810   jbyteArray rtJavaArray = e->NewByteArray(gCaps.size());
2811   CHECK(rtJavaArray);
2812   e->SetByteArrayRegion(rtJavaArray, 0, gCaps.size(), (jbyte*)gCaps.data());
2813   return rtJavaArray;
2814 }
2815 
2816 } /* namespace android */
2817