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