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