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