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