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