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