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