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