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/logging.h>
18 #include <android-base/stringprintf.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 "NativeWlcManager.h"
30 #include "NfcAdaptation.h"
31 #ifdef DTA_ENABLED
32 #include "NfcDta.h"
33 #endif /* DTA_ENABLED */
34 #include "NativeT4tNfcee.h"
35 #include "NfcJniUtil.h"
36 #include "NfcTag.h"
37 #include "NfceeManager.h"
38 #include "RoutingManager.h"
39 #include "SyncEvent.h"
40 #include "android_nfc.h"
41 #include "ce_api.h"
42 #include "com_android_nfc_module_flags.h"
43 #include "debug_lmrt.h"
44 #include "nfa_api.h"
45 #include "nfa_ee_api.h"
46 #include "nfa_nfcee_int.h"
47 #include "nfc_brcm_defs.h"
48 #include "nfc_config.h"
49 #include "rw_api.h"
50
51 using android::base::StringPrintf;
52
53 using com::android::nfc::module::flags::reader_mode_ignore_frame;
54
55 extern tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg; // defined in stack
56 namespace android {
57 extern bool gIsTagDeactivating;
58 extern bool gIsSelectingRfInterface;
59 extern bool gTagJustActivated;
60 extern void nativeNfcTag_doTransceiveStatus(tNFA_STATUS status, uint8_t* buf,
61 uint32_t buflen);
62 extern void nativeNfcTag_notifyRfTimeout();
63 extern void nativeNfcTag_doConnectStatus(jboolean is_connect_ok);
64 extern void nativeNfcTag_doDeactivateStatus(int status);
65 extern void nativeNfcTag_doWriteStatus(jboolean is_write_ok);
66 extern jboolean nativeNfcTag_doDisconnect(JNIEnv*, jobject);
67 extern void nativeNfcTag_doCheckNdefResult(tNFA_STATUS status,
68 uint32_t max_size,
69 uint32_t current_size,
70 uint8_t flags);
71 extern void nativeNfcTag_doMakeReadonlyResult(tNFA_STATUS status);
72 extern void nativeNfcTag_doPresenceCheckResult(tNFA_STATUS status);
73 extern void nativeNfcTag_formatStatus(bool is_ok);
74 extern void nativeNfcTag_resetPresenceCheck();
75 extern void nativeNfcTag_doReadCompleted(tNFA_STATUS status);
76 extern void nativeNfcTag_setRfInterface(tNFA_INTF_TYPE rfInterface);
77 extern void nativeNfcTag_setActivatedRfProtocol(tNFA_INTF_TYPE rfProtocol);
78 extern void nativeNfcTag_setActivatedRfMode(uint8_t rfMode);
79 extern void nativeNfcTag_abortWaits();
80 extern void nativeNfcTag_registerNdefTypeHandler();
81 extern void nativeNfcTag_acquireRfInterfaceMutexLock();
82 extern void nativeNfcTag_releaseRfInterfaceMutexLock();
83 extern void updateNfcID0Param(uint8_t* nfcID0);
84 } // namespace android
85
86 /*****************************************************************************
87 **
88 ** public variables and functions
89 **
90 *****************************************************************************/
91 bool gActivated = false;
92 SyncEvent gDeactivatedEvent;
93 SyncEvent sNfaSetPowerSubState;
94 int recovery_option = 0;
95 int always_on_nfcee_power_and_link_conf = 0;
96 int disable_always_on_nfcee_power_and_link_conf = 0;
97
98 namespace android {
99 jmethodID gCachedNfcManagerNotifyNdefMessageListeners;
100 jmethodID gCachedNfcManagerNotifyTransactionListeners;
101 jmethodID gCachedNfcManagerNotifyHostEmuActivated;
102 jmethodID gCachedNfcManagerNotifyHostEmuData;
103 jmethodID gCachedNfcManagerNotifyHostEmuDeactivated;
104 jmethodID gCachedNfcManagerNotifyRfFieldActivated;
105 jmethodID gCachedNfcManagerNotifyRfFieldDeactivated;
106 jmethodID gCachedNfcManagerNotifyEeUpdated;
107 jmethodID gCachedNfcManagerNotifyTagDiscovered;
108 jmethodID gCachedNfcManagerNotifyHwErrorReported;
109 jmethodID gCachedNfcManagerNotifyPollingLoopFrame;
110 jmethodID gCachedNfcManagerNotifyWlcStopped;
111 jmethodID gCachedNfcManagerNotifyVendorSpecificEvent;
112 jmethodID gCachedNfcManagerNotifyCommandTimeout;
113 jmethodID gCachedNfcManagerNotifyObserveModeChanged;
114 jmethodID gCachedNfcManagerNotifyRfDiscoveryEvent;
115 jmethodID gCachedNfcManagerNotifyEeAidSelected;
116 jmethodID gCachedNfcManagerNotifyEeProtocolSelected;
117 jmethodID gCachedNfcManagerNotifyEeTechSelected;
118 jmethodID gCachedNfcManagerNotifyEeListenActivated;
119 jmethodID gCachedNfcManagerOnRestartRfDiscovery;
120 jmethodID gCachedNfcManagerOnObserveModeDisabledInFirmware;
121 jmethodID gCachedNfcManagerOnObserveModeEnabledInFirmware;
122 jmethodID gCachedNfcManagerNotifyEndpointRemoved;
123
124 const char* gNativeNfcTagClassName = "com/android/nfc/dhimpl/NativeNfcTag";
125 const char* gNativeNfcManagerClassName =
126 "com/android/nfc/dhimpl/NativeNfcManager";
127 const char* gNfcVendorNciResponseClassName =
128 "com/android/nfc/NfcVendorNciResponse";
129 const char* gNativeT4tNfceeClassName =
130 "com/android/nfc/dhimpl/NativeT4tNfceeManager";
131 void doStartupConfig();
132 void startStopPolling(bool isStartPolling);
133 void startRfDiscovery(bool isStart);
134 bool isDiscoveryStarted();
135 } // namespace android
136
137 /*****************************************************************************
138 **
139 ** private variables and functions
140 **
141 *****************************************************************************/
142 namespace android {
143 static SyncEvent sNfaEnableEvent; // event for NFA_Enable()
144 static SyncEvent sNfaDisableEvent; // event for NFA_Disable()
145 static SyncEvent sNfaEnableDisablePollingEvent; // event for
146 // NFA_EnablePolling(),
147 // NFA_DisablePolling()
148 SyncEvent gNfaSetConfigEvent; // event for Set_Config....
149 SyncEvent gNfaGetConfigEvent; // event for Get_Config....
150 SyncEvent gNfaVsCommand; // event for VS commands
151 SyncEvent gSendRawVsCmdEvent; // event for NFA_SendRawVsCommand()
152 SyncEvent gNfaRemoveEpEvent; // event for StartRemoval....
153 static bool sIsEpDetectStarted = false;
154 static bool sIsNfaEnabled = false;
155 static bool sDiscoveryEnabled = false; // is polling or listening
156 static bool sPollingEnabled = false; // is polling for tag?
157 bool sIsDisabling = false;
158 static bool sRfEnabled = false; // whether RF discovery is enabled
159 static bool sSeRfActive = false; // whether RF with SE is likely active
160 static bool sReaderModeEnabled = false; // whether we're only reading tags, not allowing card emu
161 static bool sAbortConnlessWait = false;
162 static jint sLfT3tMax = 0;
163 static bool sRoutingInitialized = false;
164 static bool sIsRecovering = false;
165 static bool sIsAlwaysPolling = false;
166 static std::vector<uint8_t> sRawVendorCmdResponse;
167 static bool sEnableVendorNciNotifications = false;
168 static bool sIsShuttingDown = false;
169
170 #define CONFIG_UPDATE_TECH_MASK (1 << 1)
171 #define DEFAULT_TECH_MASK \
172 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F | \
173 NFA_TECHNOLOGY_MASK_V | NFA_TECHNOLOGY_MASK_B_PRIME | \
174 NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE | \
175 NFA_TECHNOLOGY_MASK_KOVIO)
176 #define DEFAULT_DISCOVERY_DURATION 500
177 #define READER_MODE_DISCOVERY_DURATION 200
178 #define FLAG_SET_DEFAULT_TECH 0x40000000
179
180 static void nfaConnectionCallback(uint8_t event, tNFA_CONN_EVT_DATA* eventData);
181 static void nfaDeviceManagementCallback(uint8_t event,
182 tNFA_DM_CBACK_DATA* eventData);
183 static bool isListenMode(tNFA_ACTIVATED& activated);
184 static tNFA_STATUS stopPolling_rfDiscoveryDisabled();
185 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
186 tNFA_TECHNOLOGY_MASK tech_mask);
187 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
188 jint screen_state_mask,
189 jboolean alwaysPoll);
190 static jboolean nfcManager_doSetPowerSavingMode(JNIEnv* e, jobject o,
191 bool flag);
192 static void sendRawVsCmdCallback(uint8_t event, uint16_t param_len,
193 uint8_t* p_param);
194 static jbyteArray nfcManager_getProprietaryCaps(JNIEnv* e, jobject o);
195 static jboolean nfcManager_setFirmwareExitFrameTable(JNIEnv* env, jobject o,
196 jobjectArray exit_frames,
197 jbyteArray timeout_ms);
198 static void nfcManager_restartRfDiscovery(JNIEnv* e, jobject o);
199 tNFA_STATUS gVSCmdStatus = NFA_STATUS_OK;
200 uint16_t gCurrentConfigLen;
201 uint8_t gConfig[256];
202 std::vector<uint8_t> gCaps(0);
203 static int prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
204 static int NFA_SCREEN_POLLING_TAG_MASK = 0x10;
205 bool gIsDtaEnabled = false;
206 static bool gObserveModeEnabled = false;
207 static int gPartialInitMode = ENABLE_MODE_DEFAULT;
208 /////////////////////////////////////////////////////////////
209 /////////////////////////////////////////////////////////////
210
211 namespace {
initializeGlobalDebugEnabledFlag()212 void initializeGlobalDebugEnabledFlag() {
213 bool nfc_debug_enabled =
214 (NfcConfig::getUnsigned(NAME_NFC_DEBUG_ENABLED, 1) != 0) ||
215 property_get_bool("persist.nfc.debug_enabled", true);
216
217 android::base::SetMinimumLogSeverity(nfc_debug_enabled ? android::base::DEBUG
218 : android::base::INFO);
219 }
220
initializeRecoveryOption()221 void initializeRecoveryOption() {
222 recovery_option = NfcConfig::getUnsigned(NAME_RECOVERY_OPTION, 0);
223
224 LOG(DEBUG) << __func__ << ": recovery option=" << recovery_option;
225 }
226
initializeNfceePowerAndLinkConf()227 void initializeNfceePowerAndLinkConf() {
228 always_on_nfcee_power_and_link_conf =
229 NfcConfig::getUnsigned(NAME_ALWAYS_ON_SET_EE_POWER_AND_LINK_CONF, 0);
230
231 LOG(DEBUG) << __func__ << ": Always on set NFCEE_POWER_AND_LINK_CONF="
232 << always_on_nfcee_power_and_link_conf;
233 }
234
initializeDisableAlwaysOnNfceePowerAndLinkConf()235 void initializeDisableAlwaysOnNfceePowerAndLinkConf() {
236 disable_always_on_nfcee_power_and_link_conf = NfcConfig::getUnsigned(
237 NAME_DISABLE_ALWAYS_ON_SET_EE_POWER_AND_LINK_CONF, 0);
238
239 LOG(DEBUG) << __func__ << ": Always on set NFCEE_POWER_AND_LINK_CONF="
240 << disable_always_on_nfcee_power_and_link_conf;
241 }
242
243 } // namespace
244
245 /*******************************************************************************
246 **
247 ** Function: getNative
248 **
249 ** Description: Get native data
250 **
251 ** Returns: Native data structure.
252 **
253 *******************************************************************************/
getNative(JNIEnv * e,jobject o)254 nfc_jni_native_data* getNative(JNIEnv* e, jobject o) {
255 static struct nfc_jni_native_data* sCachedNat = NULL;
256 if (e) {
257 sCachedNat = nfc_jni_get_nat(e, o);
258 }
259 return sCachedNat;
260 }
261
262 /*******************************************************************************
263 **
264 ** Function: handleRfDiscoveryEvent
265 **
266 ** Description: Handle RF-discovery events from the stack.
267 ** discoveredDevice: Discovered device.
268 **
269 ** Returns: None
270 **
271 *******************************************************************************/
handleRfDiscoveryEvent(tNFC_RESULT_DEVT * discoveredDevice)272 static void handleRfDiscoveryEvent(tNFC_RESULT_DEVT* discoveredDevice) {
273 NfcTag& natTag = NfcTag::getInstance();
274
275 LOG(DEBUG) << StringPrintf("%s: ", __func__);
276
277 if (gIsSelectingRfInterface && !natTag.getMultiProtocolTagSupport()) {
278 if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) return;
279 LOG(WARNING) << StringPrintf(
280 "%s: reselecting, mismatch in nb of detected interfaces, "
281 "restarting discovery",
282 __func__);
283 nativeNfcTag_doConnectStatus(false);
284 natTag.setReselect(false);
285 NFA_Deactivate(FALSE);
286 }
287 if (discoveredDevice->protocol != NFA_PROTOCOL_NFC_DEP) {
288 natTag.setNumDiscNtf(natTag.getNumDiscNtf() + 1);
289 }
290 if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) {
291 // there is more discovery notification coming
292 return;
293 }
294
295 if (natTag.getNumDiscNtf() > 1) {
296 natTag.setMultiProtocolTagSupport(true);
297 }
298
299 natTag.setNumDiscNtf(natTag.getNumDiscNtf() - 1);
300 // select the first of multiple tags that is discovered
301 natTag.selectFirstTag();
302 }
303
304 /*******************************************************************************
305 **
306 ** Function: nfaConnectionCallback
307 **
308 ** Description: Receive connection-related events from stack.
309 ** connEvent: Event code.
310 ** eventData: Event data.
311 **
312 ** Returns: None
313 **
314 *******************************************************************************/
nfaConnectionCallback(uint8_t connEvent,tNFA_CONN_EVT_DATA * eventData)315 static void nfaConnectionCallback(uint8_t connEvent,
316 tNFA_CONN_EVT_DATA* eventData) {
317 tNFA_STATUS status = NFA_STATUS_FAILED;
318
319 switch (connEvent) {
320 case NFA_LISTEN_ENABLED_EVT: // whether listening successfully started
321 {
322 LOG(DEBUG) << StringPrintf("%s: NFA_LISTEN_ENABLED_EVT:status= %u",
323 __func__, eventData->status);
324
325 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
326 sNfaEnableDisablePollingEvent.notifyOne();
327 } break;
328
329 case NFA_POLL_ENABLED_EVT: // whether polling successfully started
330 {
331 LOG(DEBUG) << StringPrintf("%s: NFA_POLL_ENABLED_EVT: status = %u",
332 __func__, eventData->status);
333
334 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
335 sNfaEnableDisablePollingEvent.notifyOne();
336 } break;
337
338 case NFA_POLL_DISABLED_EVT: // Listening/Polling stopped
339 {
340 LOG(DEBUG) << StringPrintf("%s: NFA_POLL_DISABLED_EVT: status = %u",
341 __func__, eventData->status);
342
343 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
344 sNfaEnableDisablePollingEvent.notifyOne();
345 } break;
346
347 case NFA_RF_DISCOVERY_STARTED_EVT: // RF Discovery started
348 {
349 LOG(DEBUG) << StringPrintf(
350 "%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u", __func__,
351 eventData->status);
352
353 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
354 sNfaEnableDisablePollingEvent.notifyOne();
355 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
356 if (!nat) {
357 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
358 return;
359 }
360 JNIEnv* e = NULL;
361 ScopedAttach attach(nat->vm, &e);
362 if (e == NULL) {
363 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
364 return;
365 }
366 e->CallVoidMethod(nat->manager,
367 android::gCachedNfcManagerNotifyRfDiscoveryEvent,
368 JNI_TRUE);
369 } break;
370
371 case NFA_RF_DISCOVERY_STOPPED_EVT: // RF Discovery stopped event
372 {
373 LOG(DEBUG) << StringPrintf(
374 "%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u", __func__,
375 eventData->status);
376
377 gActivated = false;
378
379 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
380 sNfaEnableDisablePollingEvent.notifyOne();
381 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
382 if (!nat) {
383 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
384 return;
385 }
386 JNIEnv* e = NULL;
387 ScopedAttach attach(nat->vm, &e);
388 if (e == NULL) {
389 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
390 return;
391 }
392 e->CallVoidMethod(nat->manager,
393 android::gCachedNfcManagerNotifyRfDiscoveryEvent,
394 JNI_FALSE);
395 } break;
396
397 case NFA_DISC_RESULT_EVT: // NFC link/protocol discovery notificaiton
398 status = eventData->disc_result.status;
399 LOG(DEBUG) << StringPrintf("%s: NFA_DISC_RESULT_EVT: status = %d",
400 __func__, status);
401 if (status != NFA_STATUS_OK) {
402 NfcTag::getInstance().setNumDiscNtf(0);
403 LOG(ERROR) << StringPrintf("%s: NFA_DISC_RESULT_EVT error: status = %d",
404 __func__, status);
405 } else {
406 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
407 handleRfDiscoveryEvent(&eventData->disc_result.discovery_ntf);
408 }
409 break;
410
411 case NFA_SELECT_RESULT_EVT: // NFC link/protocol discovery select response
412 LOG(DEBUG) << StringPrintf(
413 "%s: NFA_SELECT_RESULT_EVT: status = %d, gIsSelectingRfInterface = "
414 "%d, "
415 "sIsDisabling=%d",
416 __func__, eventData->status, gIsSelectingRfInterface, sIsDisabling);
417
418 if (sIsDisabling) break;
419
420 if (eventData->status != NFA_STATUS_OK) {
421 if (gIsSelectingRfInterface) {
422 nativeNfcTag_doConnectStatus(false);
423 }
424
425 LOG(ERROR) << StringPrintf(
426 "%s: NFA_SELECT_RESULT_EVT error: status = %d", __func__,
427 eventData->status);
428 if (NfcTag::getInstance().retrySelect() == NFA_STATUS_OK) {
429 break;
430 }
431 NFA_Deactivate(FALSE);
432 }
433 break;
434
435 case NFA_DEACTIVATE_FAIL_EVT:
436 LOG(DEBUG) << StringPrintf("%s: NFA_DEACTIVATE_FAIL_EVT: status = %d",
437 __func__, eventData->status);
438 break;
439
440 case NFA_ACTIVATED_EVT: // NFC link/protocol activated
441 {
442 bool notListen = !isListenMode(eventData->activated);
443 LOG(DEBUG) << StringPrintf(
444 "%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d",
445 __func__, gIsSelectingRfInterface, sIsDisabling);
446 uint8_t activatedProtocol =
447 (tNFA_INTF_TYPE)eventData->activated.activate_ntf.protocol;
448 uint8_t activatedMode =
449 eventData->activated.activate_ntf.rf_tech_param.mode;
450 gTagJustActivated = true;
451 if (NFC_PROTOCOL_T5T == activatedProtocol &&
452 NfcTag::getInstance().getNumDiscNtf()) {
453 /* T5T doesn't support multiproto detection logic */
454 NfcTag::getInstance().setNumDiscNtf(0);
455 }
456 NfcTag::getInstance().clearSelectRetryCount();
457 if ((eventData->activated.activate_ntf.protocol !=
458 NFA_PROTOCOL_NFC_DEP) &&
459 (!isListenMode(eventData->activated))) {
460 nativeNfcTag_setRfInterface(
461 (tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param.type);
462 nativeNfcTag_setActivatedRfProtocol(activatedProtocol);
463 nativeNfcTag_setActivatedRfMode(activatedMode);
464 }
465 NfcTag::getInstance().setActive(notListen);
466 if (sIsDisabling || !sIsNfaEnabled) break;
467 gActivated = true;
468
469 if (notListen) {
470 updateNfcID0Param(
471 eventData->activated.activate_ntf.rf_tech_param.param.pb.nfcid0);
472 NfcTag::getInstance().setActivationState();
473 if (gIsSelectingRfInterface) {
474 nativeNfcTag_doConnectStatus(true);
475 break;
476 }
477
478 nativeNfcTag_resetPresenceCheck();
479 if (!isListenMode(eventData->activated) &&
480 (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED ||
481 prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED)) {
482 if (!sIsAlwaysPolling) {
483 NFA_Deactivate(FALSE);
484 }
485 }
486
487 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
488 if (NfcTag::getInstance().getNumDiscNtf()) {
489 /*If its multiprotocol tag, deactivate tag with current selected
490 protocol to sleep . Select tag with next supported protocol after
491 deactivation event is received*/
492 if (((tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param
493 .type == NFA_INTERFACE_FRAME)) {
494 uint8_t RW_TAG_SLP_REQ[] = {0x50, 0x00};
495 SyncEvent waitSome;
496 SyncEventGuard g(waitSome);
497 NFA_SendRawFrame(RW_TAG_SLP_REQ, sizeof(RW_TAG_SLP_REQ), 0);
498 waitSome.wait(4);
499 }
500 NFA_Deactivate(true);
501 }
502
503 } else {
504 // If it activated in
505 // listen mode then it is likely for an SE transaction.
506 // Send the RF Event.
507 sSeRfActive = true;
508 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
509 if (!nat) {
510 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
511 return;
512 }
513 JNIEnv* e = NULL;
514 ScopedAttach attach(nat->vm, &e);
515 if (e == NULL) {
516 LOG(ERROR) << __func__ << ": jni env is null";
517 return;
518 }
519 e->CallVoidMethod(nat->manager,
520 android::gCachedNfcManagerNotifyEeListenActivated,
521 JNI_TRUE);
522 }
523 } break;
524 case NFA_DEACTIVATED_EVT: // NFC link/protocol deactivated
525 LOG(DEBUG) << StringPrintf(
526 "%s: NFA_DEACTIVATED_EVT Type=%u, gIsTagDeactivating=%d", __func__,
527 eventData->deactivated.type, gIsTagDeactivating);
528 NfcTag::getInstance().setDeactivationState(eventData->deactivated);
529
530 if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP) {
531 {
532 SyncEventGuard g(gDeactivatedEvent);
533 gActivated = false; // guard this variable from multi-threaded access
534 gDeactivatedEvent.notifyOne();
535 }
536 nativeNfcTag_resetPresenceCheck();
537 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
538 nativeNfcTag_abortWaits();
539 NfcTag::getInstance().abort();
540 } else if (gIsTagDeactivating) {
541 NfcTag::getInstance().setActive(false);
542 nativeNfcTag_doDeactivateStatus(0);
543 } else if (!sIsDisabling) {
544 NfcTag::getInstance().selectNextTagIfExists();
545 }
546
547 // If RF is activated for what we think is a Secure Element transaction
548 // and it is deactivated to either IDLE or DISCOVERY mode, notify w/event.
549 if ((eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE) ||
550 (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_DISCOVERY)) {
551 if (sSeRfActive) {
552 sSeRfActive = false;
553 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
554 if (!nat) {
555 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
556 return;
557 }
558 JNIEnv* e = NULL;
559 ScopedAttach attach(nat->vm, &e);
560 if (e == NULL) {
561 LOG(ERROR) << __func__ << ": jni env is null";
562 return;
563 }
564 e->CallVoidMethod(nat->manager,
565 android::gCachedNfcManagerNotifyEeListenActivated,
566 JNI_FALSE);
567 }
568 }
569
570 break;
571
572 case NFA_DETECT_REMOVAL_STARTED_EVT: { // whether EP Removal Detection
573 // successfully started
574 LOG(DEBUG) << StringPrintf(
575 "%s: NFA_DETECT_REMOVAL_STARTED_EVT: status = %d", __func__, status);
576
577 sIsEpDetectStarted = eventData->status == NFA_STATUS_OK;
578 SyncEventGuard guard(gNfaRemoveEpEvent);
579 gNfaRemoveEpEvent.notifyOne();
580 } break;
581
582 case NFA_DETECT_REMOVAL_RESULT_EVT: { // Removal Detection complete
583 LOG(DEBUG) << StringPrintf(
584 "%s: NFA_DETECT_REMOVAL_RESULT_EVT: status = %d, reason = %d",
585 __func__, status, eventData->removal_detect.reason);
586
587 /* Return REMOVAL_DETECTION deactivation reason to service */
588 {
589 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
590 if (!nat) {
591 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
592 return;
593 }
594 JNIEnv* e = NULL;
595 ScopedAttach attach(nat->vm, &e);
596 if (e == NULL) {
597 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
598 return;
599 }
600 e->CallVoidMethod(nat->manager,
601 android::gCachedNfcManagerNotifyEndpointRemoved,
602 (int)eventData->removal_detect.reason);
603 if (e->ExceptionCheck()) {
604 e->ExceptionClear();
605 LOG(ERROR) << StringPrintf("%s: fail notify", __func__);
606 }
607 }
608 } break;
609
610 case NFA_TLV_DETECT_EVT: // TLV Detection complete
611 status = eventData->tlv_detect.status;
612 LOG(DEBUG) << StringPrintf(
613 "%s: NFA_TLV_DETECT_EVT: status = %d, protocol = %d, num_tlvs = %d, "
614 "num_bytes = %d",
615 __func__, status, eventData->tlv_detect.protocol,
616 eventData->tlv_detect.num_tlvs, eventData->tlv_detect.num_bytes);
617 if (status != NFA_STATUS_OK) {
618 LOG(ERROR) << StringPrintf("%s: NFA_TLV_DETECT_EVT error: status = %d",
619 __func__, status);
620 }
621 break;
622
623 case NFA_NDEF_DETECT_EVT: // NDEF Detection complete;
624 // if status is failure, it means the tag does not contain any or valid
625 // NDEF data; pass the failure status to the NFC Service;
626 status = eventData->ndef_detect.status;
627 LOG(DEBUG) << StringPrintf(
628 "%s: NFA_NDEF_DETECT_EVT: status = 0x%X, protocol = %u, "
629 "max_size = %u, cur_size = %u, flags = 0x%X",
630 __func__, status, eventData->ndef_detect.protocol,
631 eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size,
632 eventData->ndef_detect.flags);
633 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
634 nativeNfcTag_doCheckNdefResult(status, eventData->ndef_detect.max_size,
635 eventData->ndef_detect.cur_size,
636 eventData->ndef_detect.flags);
637 break;
638
639 case NFA_DATA_EVT: // Data message received (for non-NDEF reads)
640 LOG(DEBUG) << StringPrintf("%s: NFA_DATA_EVT: status = 0x%X, len = %d",
641 __func__, eventData->status,
642 eventData->data.len);
643 nativeNfcTag_doTransceiveStatus(eventData->status, eventData->data.p_data,
644 eventData->data.len);
645 break;
646 case NFA_RW_INTF_ERROR_EVT:
647 LOG(DEBUG) << StringPrintf("%s: NFC_RW_INTF_ERROR_EVT", __func__);
648 nativeNfcTag_notifyRfTimeout();
649 nativeNfcTag_doReadCompleted(NFA_STATUS_TIMEOUT);
650 break;
651 case NFA_SELECT_CPLT_EVT: // Select completed
652 status = eventData->status;
653 LOG(DEBUG) << StringPrintf("%s: NFA_SELECT_CPLT_EVT: status = %d",
654 __func__, status);
655 if (status != NFA_STATUS_OK) {
656 LOG(ERROR) << StringPrintf("%s: NFA_SELECT_CPLT_EVT error: status = %d",
657 __func__, status);
658 }
659 break;
660
661 case NFA_READ_CPLT_EVT: // NDEF-read or tag-specific-read completed
662 LOG(DEBUG) << StringPrintf("%s: NFA_READ_CPLT_EVT: status = 0x%X",
663 __func__, eventData->status);
664 nativeNfcTag_doReadCompleted(eventData->status);
665 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
666 break;
667
668 case NFA_WRITE_CPLT_EVT: // Write completed
669 LOG(DEBUG) << StringPrintf("%s: NFA_WRITE_CPLT_EVT: status = %d",
670 __func__, eventData->status);
671 nativeNfcTag_doWriteStatus(eventData->status == NFA_STATUS_OK);
672 break;
673
674 case NFA_SET_TAG_RO_EVT: // Tag set as Read only
675 LOG(DEBUG) << StringPrintf("%s: NFA_SET_TAG_RO_EVT: status = %d",
676 __func__, eventData->status);
677 nativeNfcTag_doMakeReadonlyResult(eventData->status);
678 break;
679
680 case NFA_CE_NDEF_WRITE_START_EVT: // NDEF write started
681 LOG(DEBUG) << StringPrintf("%s: NFA_CE_NDEF_WRITE_START_EVT: status=%d",
682 __func__, eventData->status);
683
684 if (eventData->status != NFA_STATUS_OK)
685 LOG(ERROR) << StringPrintf(
686 "%s: NFA_CE_NDEF_WRITE_START_EVT error: status = %d", __func__,
687 eventData->status);
688 break;
689
690 case NFA_CE_NDEF_WRITE_CPLT_EVT: // NDEF write completed
691 LOG(DEBUG) << StringPrintf("%s: FA_CE_NDEF_WRITE_CPLT_EVT: len = %u",
692 __func__, eventData->ndef_write_cplt.len);
693 break;
694
695 case NFA_PRESENCE_CHECK_EVT:
696 LOG(DEBUG) << StringPrintf("%s: NFA_PRESENCE_CHECK_EVT", __func__);
697 nativeNfcTag_doPresenceCheckResult(eventData->status);
698 break;
699 case NFA_FORMAT_CPLT_EVT:
700 LOG(DEBUG) << StringPrintf("%s: NFA_FORMAT_CPLT_EVT: status=0x%X",
701 __func__, eventData->status);
702 nativeNfcTag_formatStatus(eventData->status == NFA_STATUS_OK);
703 break;
704
705 case NFA_I93_CMD_CPLT_EVT:
706 LOG(DEBUG) << StringPrintf("%s: NFA_I93_CMD_CPLT_EVT: status=0x%X",
707 __func__, eventData->status);
708 break;
709
710 case NFA_CE_UICC_LISTEN_CONFIGURED_EVT:
711 LOG(DEBUG) << StringPrintf(
712 "%s: NFA_CE_UICC_LISTEN_CONFIGURED_EVT : status=0x%X", __func__,
713 eventData->status);
714 break;
715 case NFA_T4TNFCEE_EVT:
716 case NFA_T4TNFCEE_READ_CPLT_EVT:
717 case NFA_T4TNFCEE_WRITE_CPLT_EVT:
718 case NFA_T4TNFCEE_CLEAR_CPLT_EVT:
719 case NFA_T4TNFCEE_READ_CC_DATA_CPLT_EVT:
720 NativeT4tNfcee::getInstance().eventHandler(connEvent, eventData);
721 break;
722
723 default:
724 LOG(DEBUG) << StringPrintf("%s: unknown event (%d) ????", __func__,
725 connEvent);
726 break;
727 }
728 }
729
730 /*******************************************************************************
731 **
732 ** Function: nfcManager_initNativeStruc
733 **
734 ** Description: Initialize variables.
735 ** e: JVM environment.
736 ** o: Java object.
737 **
738 ** Returns: True if ok.
739 **
740 *******************************************************************************/
nfcManager_initNativeStruc(JNIEnv * e,jobject o)741 static jboolean nfcManager_initNativeStruc(JNIEnv* e, jobject o) {
742 if (sIsShuttingDown) return false;
743 initializeGlobalDebugEnabledFlag();
744 initializeRecoveryOption();
745 initializeNfceePowerAndLinkConf();
746 initializeDisableAlwaysOnNfceePowerAndLinkConf();
747 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
748
749 nfc_jni_native_data* nat =
750 (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
751 if (nat == NULL) {
752 LOG(ERROR) << StringPrintf("%s: fail allocate native data", __func__);
753 return JNI_FALSE;
754 }
755
756 memset(nat, 0, sizeof(*nat));
757 e->GetJavaVM(&(nat->vm));
758 nat->env_version = e->GetVersion();
759 nat->manager = e->NewGlobalRef(o);
760
761 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
762 jfieldID f = e->GetFieldID(cls.get(), "mNative", "J");
763 e->SetLongField(o, f, (jlong)nat);
764
765 /* Initialize native cached references */
766 gCachedNfcManagerNotifyNdefMessageListeners =
767 e->GetMethodID(cls.get(), "notifyNdefMessageListeners",
768 "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
769
770 gCachedNfcManagerNotifyHostEmuActivated =
771 e->GetMethodID(cls.get(), "notifyHostEmuActivated", "(I)V");
772
773 gCachedNfcManagerNotifyHostEmuData =
774 e->GetMethodID(cls.get(), "notifyHostEmuData", "(I[B)V");
775
776 gCachedNfcManagerNotifyHostEmuDeactivated =
777 e->GetMethodID(cls.get(), "notifyHostEmuDeactivated", "(I)V");
778
779 gCachedNfcManagerNotifyRfFieldActivated =
780 e->GetMethodID(cls.get(), "notifyRfFieldActivated", "()V");
781 gCachedNfcManagerNotifyRfFieldDeactivated =
782 e->GetMethodID(cls.get(), "notifyRfFieldDeactivated", "()V");
783
784 gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID(
785 cls.get(), "notifyTransactionListeners", "([B[BLjava/lang/String;)V");
786
787 gCachedNfcManagerNotifyEeUpdated =
788 e->GetMethodID(cls.get(), "notifyEeUpdated", "()V");
789
790 gCachedNfcManagerNotifyHwErrorReported =
791 e->GetMethodID(cls.get(), "notifyHwErrorReported", "()V");
792
793 gCachedNfcManagerNotifyPollingLoopFrame =
794 e->GetMethodID(cls.get(), "notifyPollingLoopFrame", "(I[B)V");
795
796 gCachedNfcManagerNotifyVendorSpecificEvent =
797 e->GetMethodID(cls.get(), "notifyVendorSpecificEvent", "(II[B)V");
798
799 gCachedNfcManagerNotifyWlcStopped =
800 e->GetMethodID(cls.get(), "notifyWlcStopped", "(I)V");
801
802 gCachedNfcManagerNotifyTagDiscovered =
803 e->GetMethodID(cls.get(), "notifyTagDiscovered", "(Z)V");
804
805 gCachedNfcManagerNotifyCommandTimeout =
806 e->GetMethodID(cls.get(), "notifyCommandTimeout", "()V");
807
808 gCachedNfcManagerNotifyObserveModeChanged =
809 e->GetMethodID(cls.get(), "notifyObserveModeChanged", "(Z)V");
810
811 gCachedNfcManagerNotifyRfDiscoveryEvent =
812 e->GetMethodID(cls.get(), "notifyRFDiscoveryEvent", "(Z)V");
813
814 gCachedNfcManagerNotifyEeListenActivated =
815 e->GetMethodID(cls.get(), "notifyEeListenActivated", "(Z)V");
816
817 gCachedNfcManagerNotifyEeAidSelected = e->GetMethodID(
818 cls.get(), "notifyEeAidSelected", "([BLjava/lang/String;)V");
819
820 gCachedNfcManagerNotifyEeProtocolSelected = e->GetMethodID(
821 cls.get(), "notifyEeProtocolSelected", "(ILjava/lang/String;)V");
822
823 gCachedNfcManagerNotifyEeTechSelected = e->GetMethodID(
824 cls.get(), "notifyEeTechSelected", "(ILjava/lang/String;)V");
825
826 gCachedNfcManagerNotifyEndpointRemoved =
827 e->GetMethodID(cls.get(), "notifyEndpointRemoved", "(I)V");
828
829 gCachedNfcManagerOnRestartRfDiscovery =
830 e->GetMethodID(cls.get(), "onRestartRfDiscovery", "()V");
831
832 gCachedNfcManagerOnObserveModeDisabledInFirmware =
833 e->GetMethodID(cls.get(), "onObserveModeDisabledInFirmware", "(I[B)V");
834
835 gCachedNfcManagerOnObserveModeEnabledInFirmware =
836 e->GetMethodID(cls.get(), "onObserveModeEnabledInFirmware", "()V");
837
838 if (nfc_jni_cache_object(e, gNativeNfcTagClassName, &(nat->cached_NfcTag)) ==
839 -1) {
840 LOG(ERROR) << StringPrintf("%s: fail cache NativeNfcTag", __func__);
841 return JNI_FALSE;
842 }
843
844 // Cache the reference to the manager
845 (void)getNative(e,o);
846
847 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
848 return JNI_TRUE;
849 }
850
851 /*******************************************************************************
852 **
853 ** Function: nfaDeviceManagementCallback
854 **
855 ** Description: Receive device management events from stack.
856 ** dmEvent: Device-management event ID.
857 ** eventData: Data associated with event ID.
858 **
859 ** Returns: None
860 **
861 *******************************************************************************/
nfaDeviceManagementCallback(uint8_t dmEvent,tNFA_DM_CBACK_DATA * eventData)862 void nfaDeviceManagementCallback(uint8_t dmEvent,
863 tNFA_DM_CBACK_DATA* eventData) {
864 LOG(DEBUG) << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent);
865
866 switch (dmEvent) {
867 case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
868 {
869 SyncEventGuard guard(sNfaEnableEvent);
870 LOG(DEBUG) << StringPrintf("%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__,
871 eventData->status);
872 sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
873 sIsDisabling = false;
874 sNfaEnableEvent.notifyOne();
875 } break;
876
877 case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
878 {
879 SyncEventGuard guard(sNfaDisableEvent);
880 LOG(DEBUG) << StringPrintf("%s: NFA_DM_DISABLE_EVT", __func__);
881 sIsNfaEnabled = false;
882 sIsDisabling = false;
883 sNfaDisableEvent.notifyOne();
884 } break;
885
886 case NFA_DM_SET_CONFIG_EVT: // result of NFA_SetConfig
887 LOG(DEBUG) << StringPrintf("%s: NFA_DM_SET_CONFIG_EVT", __func__);
888 {
889 SyncEventGuard guard(gNfaSetConfigEvent);
890 gNfaSetConfigEvent.notifyOne();
891 }
892 break;
893
894 case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */
895 LOG(DEBUG) << StringPrintf("%s: NFA_DM_GET_CONFIG_EVT", __func__);
896 {
897 SyncEventGuard guard(gNfaGetConfigEvent);
898 if (eventData->status == NFA_STATUS_OK &&
899 eventData->get_config.tlv_size <= sizeof(gConfig)) {
900 gCurrentConfigLen = eventData->get_config.tlv_size;
901 memcpy(gConfig, eventData->get_config.param_tlvs,
902 eventData->get_config.tlv_size);
903 } else {
904 LOG(ERROR) << StringPrintf("%s: NFA_DM_GET_CONFIG failed", __func__);
905 gCurrentConfigLen = 0;
906 }
907 gNfaGetConfigEvent.notifyOne();
908 }
909 break;
910
911 case NFA_DM_RF_FIELD_EVT:
912 LOG(DEBUG) << StringPrintf(
913 "%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __func__,
914 eventData->rf_field.status, eventData->rf_field.rf_field_status);
915 if (eventData->rf_field.status == NFA_STATUS_OK) {
916 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
917 if (!nat) {
918 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
919 return;
920 }
921 JNIEnv* e = NULL;
922 ScopedAttach attach(nat->vm, &e);
923 if (e == NULL) {
924 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
925 return;
926 }
927 if (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON)
928 e->CallVoidMethod(nat->manager,
929 android::gCachedNfcManagerNotifyRfFieldActivated);
930 else
931 e->CallVoidMethod(nat->manager,
932 android::gCachedNfcManagerNotifyRfFieldDeactivated);
933 }
934 break;
935
936 case NFA_DM_NFCC_TRANSPORT_ERR_EVT:
937 case NFA_DM_NFCC_TIMEOUT_EVT: {
938 if (dmEvent == NFA_DM_NFCC_TIMEOUT_EVT)
939 LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TIMEOUT_EVT; abort",
940 __func__);
941 else if (dmEvent == NFA_DM_NFCC_TRANSPORT_ERR_EVT)
942 LOG(ERROR) << StringPrintf("%s: NFA_DM_NFCC_TRANSPORT_ERR_EVT; abort",
943 __func__);
944
945 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
946 if (recovery_option && nat != NULL) {
947 JNIEnv* e = NULL;
948 ScopedAttach attach(nat->vm, &e);
949 if (e == NULL) {
950 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
951 return;
952 }
953 LOG(ERROR) << StringPrintf("%s: toggle NFC state to recovery nfc",
954 __func__);
955 sIsRecovering = true;
956 e->CallVoidMethod(nat->manager,
957 android::gCachedNfcManagerNotifyHwErrorReported);
958 {
959 LOG(DEBUG) << StringPrintf(
960 "%s: aborting sNfaEnableDisablePollingEvent", __func__);
961 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
962 sNfaEnableDisablePollingEvent.notifyOne();
963 }
964 {
965 LOG(DEBUG) << StringPrintf("%s: aborting sNfaEnableEvent", __func__);
966 SyncEventGuard guard(sNfaEnableEvent);
967 sNfaEnableEvent.notifyOne();
968 }
969 {
970 LOG(DEBUG) << StringPrintf("%s: aborting sNfaDisableEvent",
971 __func__);
972 SyncEventGuard guard(sNfaDisableEvent);
973 sNfaDisableEvent.notifyOne();
974 }
975 {
976 LOG(DEBUG) << StringPrintf("%s: aborting sNfaSetPowerSubState",
977 __func__);
978 SyncEventGuard guard(sNfaSetPowerSubState);
979 sNfaSetPowerSubState.notifyOne();
980 }
981 {
982 LOG(DEBUG) << StringPrintf("%s: aborting gNfaSetConfigEvent",
983 __func__);
984 SyncEventGuard guard(gNfaSetConfigEvent);
985 gNfaSetConfigEvent.notifyOne();
986 }
987 {
988 LOG(DEBUG) << StringPrintf("%s: aborting gNfaGetConfigEvent",
989 __func__);
990 SyncEventGuard guard(gNfaGetConfigEvent);
991 gNfaGetConfigEvent.notifyOne();
992 }
993 {
994 LOG(DEBUG) << StringPrintf(
995 "%s: aborting RoutingManager::getInstance().mEeUpdateEvent",
996 __func__);
997 SyncEventGuard guard(RoutingManager::getInstance().mEeUpdateEvent);
998 RoutingManager::getInstance().mEeUpdateEvent.notifyOne();
999 }
1000 } else {
1001 nativeNfcTag_abortWaits();
1002 NfcTag::getInstance().abort();
1003 sAbortConnlessWait = true;
1004 {
1005 LOG(DEBUG) << StringPrintf(
1006 "%s: aborting sNfaEnableDisablePollingEvent", __func__);
1007 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
1008 sNfaEnableDisablePollingEvent.notifyOne();
1009 }
1010 {
1011 LOG(DEBUG) << StringPrintf("%s: aborting sNfaEnableEvent", __func__);
1012 SyncEventGuard guard(sNfaEnableEvent);
1013 sNfaEnableEvent.notifyOne();
1014 }
1015 {
1016 LOG(DEBUG) << StringPrintf("%s: aborting sNfaDisableEvent",
1017 __func__);
1018 SyncEventGuard guard(sNfaDisableEvent);
1019 sNfaDisableEvent.notifyOne();
1020 }
1021 sDiscoveryEnabled = false;
1022 sPollingEnabled = false;
1023
1024 if (!sIsDisabling && sIsNfaEnabled) {
1025 if (gIsDtaEnabled == true) {
1026 LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
1027 __func__);
1028 NFA_DisableDtamode();
1029 }
1030
1031 NFA_Disable(FALSE);
1032 sIsDisabling = true;
1033 } else {
1034 sIsNfaEnabled = false;
1035 sIsDisabling = false;
1036 }
1037 LOG(ERROR) << StringPrintf("%s: crash NFC service", __func__);
1038 if (nat != NULL) {
1039 JNIEnv* e = NULL;
1040 ScopedAttach attach(nat->vm, &e);
1041 if (e != NULL) {
1042 e->CallVoidMethod(nat->manager,
1043 android::gCachedNfcManagerNotifyCommandTimeout);
1044 }
1045 }
1046 //////////////////////////////////////////////
1047 // crash the NFC service process so it can restart automatically
1048 abort();
1049 //////////////////////////////////////////////
1050 }
1051 } break;
1052
1053 case NFA_DM_SET_POWER_SUB_STATE_EVT: {
1054 LOG(DEBUG) << StringPrintf(
1055 "%s: NFA_DM_SET_POWER_SUB_STATE_EVT; status=0x%X", __FUNCTION__,
1056 eventData->power_sub_state.status);
1057 SyncEventGuard guard(sNfaSetPowerSubState);
1058 sNfaSetPowerSubState.notifyOne();
1059 } break;
1060 default:
1061 LOG(DEBUG) << StringPrintf("%s: unhandled event", __func__);
1062 break;
1063 }
1064 }
1065
1066 /*******************************************************************************
1067 **
1068 ** Function: nfcManager_sendRawFrame
1069 **
1070 ** Description: Send a raw frame.
1071 ** e: JVM environment.
1072 ** o: Java object.
1073 **
1074 ** Returns: True if ok.
1075 **
1076 *******************************************************************************/
nfcManager_sendRawFrame(JNIEnv * e,jobject,jbyteArray data)1077 static jboolean nfcManager_sendRawFrame(JNIEnv* e, jobject, jbyteArray data) {
1078 if (sIsShuttingDown) return false;
1079 ScopedByteArrayRO bytes(e, data);
1080 uint8_t* buf =
1081 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1082 size_t bufLen = bytes.size();
1083 tNFA_STATUS status = NFA_SendRawFrame(buf, bufLen, 0);
1084
1085 return (status == NFA_STATUS_OK);
1086 }
1087
1088 /*******************************************************************************
1089 **
1090 ** Function: nfcManager_routeAid
1091 **
1092 ** Description: Route an AID to an EE
1093 ** e: JVM environment.
1094 ** aid: aid to be added to routing table.
1095 ** route: aid route location. i.e. DH/eSE/UICC
1096 ** aidInfo: prefix or suffix aid.
1097 **
1098 ** Returns: True if aid is accpted by NFA Layer.
1099 **
1100 *******************************************************************************/
nfcManager_routeAid(JNIEnv * e,jobject,jbyteArray aid,jint route,jint aidInfo,jint power)1101 static jboolean nfcManager_routeAid(JNIEnv* e, jobject, jbyteArray aid,
1102 jint route, jint aidInfo, jint power) {
1103 if (sIsShuttingDown) return false;
1104 uint8_t* buf;
1105 size_t bufLen;
1106 if (sIsDisabling || !sIsNfaEnabled) {
1107 return false;
1108 }
1109
1110 if (aid == NULL) {
1111 buf = NULL;
1112 bufLen = 0;
1113 return RoutingManager::getInstance().addAidRouting(buf, bufLen, route,
1114 aidInfo, power);
1115 }
1116 ScopedByteArrayRO bytes(e, aid);
1117 buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1118 bufLen = bytes.size();
1119 if (NfcConfig::hasKey(NAME_DEFAULT_NDEF_NFCEE_ROUTE)) {
1120 if (route == (int)NfcConfig::getUnsigned(NAME_DEFAULT_NDEF_NFCEE_ROUTE)) {
1121 NativeT4tNfcee::getInstance().checkAndUpdateT4TAid(buf,
1122 (uint8_t*)&bufLen);
1123 }
1124 }
1125 return RoutingManager::getInstance().addAidRouting(buf, bufLen, route,
1126 aidInfo, power);
1127 }
1128
1129 /*******************************************************************************
1130 **
1131 ** Function: nfcManager_unrouteAid
1132 **
1133 ** Description: Remove a AID routing
1134 ** e: JVM environment.
1135 ** o: Java object.
1136 **
1137 ** Returns: True if ok.
1138 **
1139 *******************************************************************************/
nfcManager_unrouteAid(JNIEnv * e,jobject,jbyteArray aid)1140 static jboolean nfcManager_unrouteAid(JNIEnv* e, jobject, jbyteArray aid) {
1141 if (sIsShuttingDown) return false;
1142 uint8_t* buf;
1143 size_t bufLen;
1144 if (sIsDisabling || !sIsNfaEnabled) {
1145 return false;
1146 }
1147
1148 if (aid == NULL) {
1149 buf = NULL;
1150 bufLen = 0;
1151 return RoutingManager::getInstance().removeAidRouting(buf, bufLen);
1152 }
1153 ScopedByteArrayRO bytes(e, aid);
1154 buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1155 bufLen = bytes.size();
1156 return RoutingManager::getInstance().removeAidRouting(buf, bufLen);
1157 }
1158
1159 /*******************************************************************************
1160 **
1161 ** Function: nfcManager_commitRouting
1162 **
1163 ** Description: Sends the AID routing table to the controller
1164 ** e: JVM environment.
1165 ** o: Java object.
1166 **
1167 ** Returns: NFA_STATUS_OK if successfully initiated
1168 ** NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
1169 ** NFA_STATUS_FAILED otherwise
1170 **
1171 *******************************************************************************/
nfcManager_commitRouting(JNIEnv * e,jobject)1172 static jint nfcManager_commitRouting(JNIEnv* e, jobject) {
1173 if (sIsShuttingDown) return -1;
1174 if (sRfEnabled) {
1175 /*Update routing table only in Idle state.*/
1176 startRfDiscovery(false);
1177 }
1178 jint commitStatus = RoutingManager::getInstance().commitRouting();
1179 startRfDiscovery(true);
1180 return commitStatus;
1181 }
1182
nfaVSCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)1183 void static nfaVSCallback(uint8_t event, uint16_t param_len, uint8_t* p_param) {
1184 switch (event & NCI_OID_MASK) {
1185 case NCI_MSG_PROP_ANDROID: {
1186 uint8_t android_sub_opcode = p_param[3];
1187 switch (android_sub_opcode) {
1188 case NCI_QUERY_ANDROID_PASSIVE_OBSERVE: {
1189 gObserveModeEnabled = p_param[5];
1190 LOG(INFO) << StringPrintf("%s: Query Observe mode state is %s",
1191 __func__,
1192 gObserveModeEnabled ? "TRUE" : "FALSE");
1193 }
1194 FALLTHROUGH_INTENDED;
1195 case NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH:
1196 case NCI_ANDROID_PASSIVE_OBSERVE:
1197 case NCI_ANDROID_SET_TECH_A_POLLING_LOOP_ANNOTATION:
1198 case NCI_ANDROID_SET_PASSIVE_OBSERVER_EXIT_FRAME: {
1199 gVSCmdStatus = p_param[4];
1200 LOG(INFO) << StringPrintf(
1201 "%s: RSP status: %x to Android proprietary cmd %x", __func__,
1202 gVSCmdStatus, android_sub_opcode);
1203 SyncEventGuard guard(gNfaVsCommand);
1204 gNfaVsCommand.notifyOne();
1205 } break;
1206 case NCI_ANDROID_GET_CAPS: {
1207 gVSCmdStatus = p_param[4];
1208 SyncEventGuard guard(gNfaVsCommand);
1209 if (param_len > 8) {
1210 gCaps.assign(p_param + 8, p_param + param_len);
1211 }
1212 gNfaVsCommand.notifyOne();
1213 } break;
1214 case NCI_ANDROID_POLLING_FRAME_NTF: {
1215 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1216 if (!nat) {
1217 LOG(ERROR) << StringPrintf("%s: cached nat is null", __func__);
1218 return;
1219 }
1220 JNIEnv* e = NULL;
1221 ScopedAttach attach(nat->vm, &e);
1222 if (e == NULL) {
1223 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
1224 return;
1225 }
1226 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(param_len));
1227 if (dataJavaArray.get() == NULL) {
1228 LOG(ERROR) << __func__ << ": fail allocate array";
1229 return;
1230 }
1231 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, param_len,
1232 (jbyte*)(p_param));
1233 if (e->ExceptionCheck()) {
1234 e->ExceptionClear();
1235 LOG(ERROR) << __func__ << ": failed to fill array";
1236 return;
1237 }
1238 e->CallVoidMethod(nat->manager,
1239 android::gCachedNfcManagerNotifyPollingLoopFrame,
1240 (jint)param_len, dataJavaArray.get());
1241 } break;
1242 case NCI_ANDROID_PASSIVE_OBSERVER_SUSPENDED_NTF: {
1243 LOG(INFO) << "Observe mode suspended NTF received";
1244 gObserveModeEnabled = false;
1245 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1246 if (!nat) {
1247 LOG(ERROR) << StringPrintf("cached nat is null");
1248 return;
1249 }
1250 JNIEnv* e = NULL;
1251 ScopedAttach attach(nat->vm, &e);
1252 if (e == NULL) {
1253 LOG(ERROR) << StringPrintf("jni env is null");
1254 return;
1255 }
1256 if (param_len <= 2) {
1257 LOG(ERROR) <<
1258 "Cannot parse exit frame from NCI_ANDROID_PASSIVE_OBSERVER_SUSPENDED_NTF";
1259 return;
1260 }
1261 jint exit_frame_type = (jint) p_param[4];
1262 uint16_t exit_frame_len = p_param[5];
1263 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(exit_frame_len));
1264 if (dataJavaArray.get() == NULL) {
1265 LOG(ERROR) << "fail allocate array";
1266 return;
1267 }
1268 if (exit_frame_len > 0) {
1269 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, exit_frame_len,
1270 (jbyte*)(p_param + 6));
1271 if (e->ExceptionCheck()) {
1272 e->ExceptionClear();
1273 LOG(ERROR) << "failed to fill array";
1274 return;
1275 }
1276 }
1277 e->CallVoidMethod(nat->manager,
1278 android::gCachedNfcManagerOnObserveModeDisabledInFirmware,
1279 exit_frame_type, dataJavaArray.get());
1280 return;
1281 } break;
1282 case NCI_ANDROID_PASSIVE_OBSERVER_RESUMED_NTF: {
1283 LOG(INFO) << "Observe mode resumed NTF received";
1284 gObserveModeEnabled = true;
1285 struct nfc_jni_native_data *nat = getNative(NULL, NULL);
1286 if (!nat) {
1287 LOG(ERROR) << StringPrintf("cached nat is null");
1288 return;
1289 }
1290 JNIEnv *e = NULL;
1291 ScopedAttach attach(nat->vm, &e);
1292 if (e == NULL) {
1293 LOG(ERROR) << StringPrintf("jni env is null");
1294 return;
1295 }
1296 e->CallVoidMethod(nat->manager,
1297 android::gCachedNfcManagerOnObserveModeEnabledInFirmware);
1298 return;
1299 } break;
1300 case NCI_ANDROID_RESTART_RF_DISCOVERY_REQUEST_NTF: {
1301 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1302 if (!nat) {
1303 LOG(ERROR)
1304 << StringPrintf("%s: cached nat is null", __func__);
1305 return;
1306 }
1307 JNIEnv* e = NULL;
1308 ScopedAttach attach(nat->vm, &e);
1309 if (e == NULL) {
1310 LOG(ERROR) << StringPrintf("%s: jni env is null", __func__);
1311 return;
1312 }
1313 e->CallVoidMethod(nat->manager,
1314 android::gCachedNfcManagerOnRestartRfDiscovery);
1315 } break;
1316 default:
1317 LOG(DEBUG) << StringPrintf("%s: Unknown Android sub opcode %x",
1318 __func__, android_sub_opcode);
1319 }
1320 } break;
1321 default: {
1322 if (sEnableVendorNciNotifications) {
1323 struct nfc_jni_native_data* nat = getNative(NULL, NULL);
1324 if (!nat) {
1325 LOG(ERROR) << StringPrintf("%s: cached nat is null", __FUNCTION__);
1326 return;
1327 }
1328 JNIEnv* e = NULL;
1329 ScopedAttach attach(nat->vm, &e);
1330 if (e == NULL) {
1331 LOG(ERROR) << StringPrintf("%s: jni env is null", __FUNCTION__);
1332 return;
1333 }
1334 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(param_len));
1335 if (dataJavaArray.get() == NULL) {
1336 LOG(ERROR) << StringPrintf("%s: fail allocate array", __FUNCTION__);
1337 return;
1338 }
1339 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, param_len,
1340 (jbyte*)(p_param));
1341 if (e->ExceptionCheck()) {
1342 e->ExceptionClear();
1343 LOG(ERROR) << StringPrintf("%s failed to fill array", __FUNCTION__);
1344 return;
1345 }
1346 e->CallVoidMethod(nat->manager,
1347 android::gCachedNfcManagerNotifyVendorSpecificEvent,
1348 (jint)event, (jint)param_len, dataJavaArray.get());
1349 }
1350 } break;
1351 }
1352 }
1353
nfcManager_injectNtf(JNIEnv * e,jobject,jbyteArray data)1354 static void nfcManager_injectNtf(JNIEnv* e, jobject, jbyteArray data) {
1355 if (sIsShuttingDown) return;
1356 ScopedByteArrayRO bytes(e, data);
1357 size_t bufLen = bytes.size();
1358 tNFC_HAL_EVT_MSG* p_msg;
1359 p_msg = (tNFC_HAL_EVT_MSG*)GKI_getbuf(sizeof(tNFC_HAL_EVT_MSG) + bufLen + 1);
1360 if (p_msg != NULL) {
1361 p_msg->hdr.len = bufLen + 3;
1362 p_msg->hdr.event = BT_EVT_TO_NFC_NCI;
1363 p_msg->hdr.offset = sizeof(tNFC_HAL_EVT_MSG) - 7;
1364 p_msg->hdr.layer_specific = 0;
1365 memcpy(((uint8_t*)p_msg) + sizeof(tNFC_HAL_EVT_MSG) + 1, bytes.get(),
1366 bufLen);
1367 GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
1368 }
1369 }
1370
isObserveModeSupported(JNIEnv * e,jobject o)1371 static jboolean isObserveModeSupported(JNIEnv* e, jobject o) {
1372 if (sIsShuttingDown) return false;
1373 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
1374 jmethodID isSupported =
1375 e->GetMethodID(cls.get(), "isObserveModeSupported", "()Z");
1376 return e->CallBooleanMethod(o, isSupported);
1377 }
1378
nfcManager_isObserveModeEnabled(JNIEnv * e,jobject o)1379 static jboolean nfcManager_isObserveModeEnabled(JNIEnv* e, jobject o) {
1380 if (sIsShuttingDown) return false;
1381 if (isObserveModeSupported(e, o) == JNI_FALSE) {
1382 return false;
1383 }
1384
1385 uint8_t cmd[] = {NCI_QUERY_ANDROID_PASSIVE_OBSERVE};
1386 SyncEventGuard guard(gNfaVsCommand);
1387 tNFA_STATUS status =
1388 NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd), cmd, nfaVSCallback);
1389
1390 if (status == NFA_STATUS_OK) {
1391 if (!gNfaVsCommand.wait(1000)) {
1392 LOG(ERROR) << StringPrintf(
1393 "%s: Timed out waiting for a response to get observe mode ",
1394 __FUNCTION__);
1395 gVSCmdStatus = NFA_STATUS_FAILED;
1396 }
1397 } else {
1398 LOG(DEBUG) << StringPrintf("%s: Failed to get observe mode ", __FUNCTION__);
1399 }
1400 LOG(DEBUG) << StringPrintf(
1401 "%s: returning %s", __FUNCTION__,
1402 (gObserveModeEnabled != JNI_FALSE ? "TRUE" : "FALSE"));
1403 return gObserveModeEnabled;
1404 }
1405
nfaSendRawVsCmdCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)1406 static void nfaSendRawVsCmdCallback(uint8_t event, uint16_t param_len,
1407 uint8_t* p_param) {
1408 if (param_len == 5) {
1409 gVSCmdStatus = p_param[4];
1410 } else {
1411 gVSCmdStatus = NFA_STATUS_FAILED;
1412 }
1413 SyncEventGuard guard(gNfaVsCommand);
1414 gNfaVsCommand.notifyOne();
1415 }
1416
isObserveModeSupportedWithoutRfDeactivation(JNIEnv * e,jobject o)1417 bool isObserveModeSupportedWithoutRfDeactivation(JNIEnv* e, jobject o) {
1418 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
1419 jmethodID isSupported = e->GetMethodID(
1420 cls.get(), "isObserveModeSupportedWithoutRfDeactivation", "()Z");
1421 return e->CallBooleanMethod(o, isSupported);
1422 }
1423
nfcManager_setObserveMode(JNIEnv * e,jobject o,jboolean enable)1424 static jboolean nfcManager_setObserveMode(JNIEnv* e, jobject o,
1425 jboolean enable) {
1426 if (sIsShuttingDown) return false;
1427 if (isObserveModeSupported(e, o) == JNI_FALSE) {
1428 LOG(DEBUG) << "setObserveMode called when it isn't supported, returning false";
1429 return false;
1430 }
1431
1432 if (isObserveModeSupportedWithoutRfDeactivation(e, o) == JNI_FALSE) {
1433 LOG(DEBUG) << "setObserveMode called when it requires RF off/on, returning false";
1434 return false;
1435 }
1436
1437 if ((gObserveModeEnabled == enable) &&
1438 ((enable != JNI_FALSE) ==
1439 (nfcManager_isObserveModeEnabled(e, o) != JNI_FALSE))) {
1440 LOG(DEBUG) << StringPrintf(
1441 "%s: called with %s but it is already %s, returning early",
1442 __FUNCTION__, (enable != JNI_FALSE ? "TRUE" : "FALSE"),
1443 (gObserveModeEnabled != JNI_FALSE ? "TRUE" : "FALSE"));
1444 return true;
1445 }
1446 uint8_t cmd[] = {
1447 static_cast<uint8_t>(NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH),
1448 static_cast<uint8_t>(
1449 enable != JNI_FALSE
1450 ? (NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_A |
1451 NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_B |
1452 NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_V)
1453 : NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
1454 {
1455 SyncEventGuard guard(gNfaVsCommand);
1456 tNFA_STATUS status = NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd),
1457 cmd, nfaVSCallback);
1458
1459 if (status == NFA_STATUS_OK) {
1460 if (!gNfaVsCommand.wait(1000)) {
1461 LOG(ERROR) << StringPrintf(
1462 "%s: Timed out waiting for a response to set observe mode ",
1463 __FUNCTION__);
1464 gVSCmdStatus = NFA_STATUS_FAILED;
1465 }
1466 } else {
1467 LOG(DEBUG) << StringPrintf("%s: Failed to set observe mode ",
1468 __FUNCTION__);
1469 gVSCmdStatus = NFA_STATUS_FAILED;
1470 }
1471 }
1472
1473 if (gVSCmdStatus == NFA_STATUS_OK) {
1474 gObserveModeEnabled = enable;
1475 } else {
1476 gObserveModeEnabled = nfcManager_isObserveModeEnabled(e, o);
1477 }
1478
1479 LOG(DEBUG) << StringPrintf(
1480 "%s: Set observe mode to %s with result %x, observe mode is now %s.",
1481 __FUNCTION__, (enable != JNI_FALSE ? "TRUE" : "FALSE"), gVSCmdStatus,
1482 (gObserveModeEnabled ? "enabled" : "disabled"));
1483 if (gObserveModeEnabled == enable) {
1484 e->CallVoidMethod(o, android::gCachedNfcManagerNotifyObserveModeChanged,
1485 enable);
1486 return true;
1487 } else {
1488 return false;
1489 }
1490 }
1491
1492 /*******************************************************************************
1493 **
1494 ** Function: nfcManager_doRegisterT3tIdentifier
1495 **
1496 ** Description: Registers LF_T3T_IDENTIFIER for NFC-F.
1497 ** e: JVM environment.
1498 ** o: Java object.
1499 ** t3tIdentifier: LF_T3T_IDENTIFIER value (10 or 18 bytes)
1500 **
1501 ** Returns: Handle retrieve from RoutingManager.
1502 **
1503 *******************************************************************************/
nfcManager_doRegisterT3tIdentifier(JNIEnv * e,jobject,jbyteArray t3tIdentifier)1504 static jint nfcManager_doRegisterT3tIdentifier(JNIEnv* e, jobject,
1505 jbyteArray t3tIdentifier) {
1506 if (sIsShuttingDown) return -1;
1507 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1508
1509 ScopedByteArrayRO bytes(e, t3tIdentifier);
1510 uint8_t* buf =
1511 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0]));
1512 size_t bufLen = bytes.size();
1513 int handle = RoutingManager::getInstance().registerT3tIdentifier(buf, bufLen);
1514
1515 LOG(DEBUG) << StringPrintf("%s: handle=%d", __func__, handle);
1516 if (handle != NFA_HANDLE_INVALID)
1517 RoutingManager::getInstance().commitRouting();
1518 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1519
1520 return handle;
1521 }
1522
1523 /*******************************************************************************
1524 **
1525 ** Function: nfcManager_doDeregisterT3tIdentifier
1526 **
1527 ** Description: Deregisters LF_T3T_IDENTIFIER for NFC-F.
1528 ** e: JVM environment.
1529 ** o: Java object.
1530 ** handle: Handle retrieve from libnfc-nci.
1531 **
1532 ** Returns: None
1533 **
1534 *******************************************************************************/
nfcManager_doDeregisterT3tIdentifier(JNIEnv *,jobject,jint handle)1535 static void nfcManager_doDeregisterT3tIdentifier(JNIEnv*, jobject,
1536 jint handle) {
1537 if (sIsShuttingDown) return;
1538 LOG(DEBUG) << StringPrintf("%s: enter; handle=%d", __func__, handle);
1539
1540 RoutingManager::getInstance().deregisterT3tIdentifier(handle);
1541 RoutingManager::getInstance().commitRouting();
1542
1543 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1544 }
1545
1546 /*******************************************************************************
1547 **
1548 ** Function: nfcManager_getLfT3tMax
1549 **
1550 ** Description: Returns LF_T3T_MAX value.
1551 ** e: JVM environment.
1552 ** o: Java object.
1553 **
1554 ** Returns: LF_T3T_MAX value.
1555 **
1556 *******************************************************************************/
nfcManager_getLfT3tMax(JNIEnv *,jobject)1557 static jint nfcManager_getLfT3tMax(JNIEnv*, jobject) {
1558 if (sIsShuttingDown) return -1;
1559 LOG(DEBUG) << StringPrintf("%s: LF_T3T_MAX=%d", __func__, sLfT3tMax);
1560 return sLfT3tMax;
1561 }
1562
1563 /*******************************************************************************
1564 **
1565 ** Function: doPartialInit
1566 **
1567 ** Description: Partial Nfc initialization based on mode set
1568 ** ENABLE_MODE_TRANSPARENT : Minimum initialization to allow
1569 ** NFCC transport
1570 ** ENABLE_MODE_EE : Minimum Initialization to allow card
1571 ** emulation operation
1572 **
1573 ** Returns: True if ok.
1574 **
1575 *******************************************************************************/
doPartialInit()1576 static jboolean doPartialInit() {
1577 if (sIsShuttingDown) return false;
1578 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1579 tNFA_STATUS stat = NFA_STATUS_OK;
1580
1581 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1582 theInstance.Initialize(); // start GKI, NCI task, NFC task
1583
1584 {
1585 SyncEventGuard guard(sNfaEnableEvent);
1586 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
1587 NFA_Partial_Init(halFuncEntries, gPartialInitMode);
1588 LOG(DEBUG) << StringPrintf("%s: register VS callbacks", __func__);
1589 NFA_RegVSCback(true, &nfaVSCallback);
1590
1591 LOG(DEBUG) << StringPrintf("%s: calling enable", __func__);
1592 stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
1593 if (stat == NFA_STATUS_OK) {
1594 sNfaEnableEvent.wait(); // wait for NFA command to finish
1595 }
1596 NFA_SetNfccMode(ENABLE_MODE_DEFAULT);
1597 }
1598
1599 // sIsNfaEnabled indicates whether stack started successfully
1600 if (!sIsNfaEnabled) {
1601 NFA_Disable(false /* ungraceful */);
1602 theInstance.Finalize();
1603 return JNI_FALSE;
1604 }
1605 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1606 return JNI_TRUE;
1607 }
1608
1609 /*******************************************************************************
1610 **
1611 ** Function: nfcManager_doInitialize
1612 **
1613 ** Description: Turn on NFC.
1614 ** e: JVM environment.
1615 ** o: Java object.
1616 **
1617 ** Returns: True if ok.
1618 **
1619 *******************************************************************************/
nfcManager_doInitialize(JNIEnv * e,jobject o)1620 static jboolean nfcManager_doInitialize(JNIEnv* e, jobject o) {
1621 if (sIsShuttingDown) return false;
1622 initializeGlobalDebugEnabledFlag();
1623 tNFA_STATUS stat = NFA_STATUS_OK;
1624 sIsRecovering = false;
1625
1626 struct nfc_jni_native_data* nat = getNative(e, o);
1627
1628 if (sIsNfaEnabled) {
1629 LOG(DEBUG) << StringPrintf("%s: already enabled", __func__);
1630 goto TheEnd;
1631 }
1632 if (gPartialInitMode != ENABLE_MODE_DEFAULT) {
1633 return doPartialInit();
1634 }
1635
1636 {
1637
1638 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1639 theInstance.Initialize(); // start GKI, NCI task, NFC task
1640
1641 {
1642 SyncEventGuard guard(sNfaEnableEvent);
1643 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
1644
1645 NFA_Init(halFuncEntries);
1646
1647 LOG(DEBUG) << StringPrintf("%s: register VS callbacks", __func__);
1648 NFA_RegVSCback(true, &nfaVSCallback);
1649
1650 if (gIsDtaEnabled == true) {
1651 // Allows to set appl_dta_mode_flag
1652 LOG(DEBUG) << StringPrintf("%s: DTA; set dta flag in core stack",
1653 __func__);
1654 NFA_EnableDtamode((tNFA_eDtaModes)NFA_DTA_APPL_MODE);
1655 }
1656
1657 stat = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
1658 if (stat == NFA_STATUS_OK) {
1659 sNfaEnableEvent.wait(); // wait for NFA command to finish
1660 }
1661 }
1662
1663 if (stat == NFA_STATUS_OK) {
1664 // sIsNfaEnabled indicates whether stack started successfully
1665 if (sIsNfaEnabled) {
1666 sRoutingInitialized =
1667 RoutingManager::getInstance().initialize(getNative(e, o));
1668 nativeNfcTag_registerNdefTypeHandler();
1669 NfcTag::getInstance().initialize(getNative(e, o));
1670 HciEventManager::getInstance().initialize(getNative(e, o));
1671 NativeWlcManager::getInstance().initialize(getNative(e, o));
1672 NativeT4tNfcee::getInstance().initialize();
1673
1674 /////////////////////////////////////////////////////////////////////////////////
1675 // Add extra configuration here (work-arounds, etc.)
1676
1677 if (nat) {
1678 nat->tech_mask =
1679 NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
1680 LOG(DEBUG) << StringPrintf("%s: tag polling tech mask=0x%X", __func__,
1681 nat->tech_mask);
1682
1683 // if this value exists, set polling interval.
1684 nat->discovery_duration = NfcConfig::getUnsigned(
1685 NAME_NFA_DM_DISC_DURATION_POLL, DEFAULT_DISCOVERY_DURATION);
1686 NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1687 } else {
1688 LOG(ERROR) << StringPrintf("nat is null");
1689 }
1690
1691 // get LF_T3T_MAX
1692 {
1693 SyncEventGuard guard(gNfaGetConfigEvent);
1694 tNFA_PMID configParam[1] = {NCI_PARAM_ID_LF_T3T_MAX};
1695 stat = NFA_GetConfig(1, configParam);
1696 if (stat == NFA_STATUS_OK) {
1697 gNfaGetConfigEvent.wait();
1698 if (gCurrentConfigLen >= 4 ||
1699 gConfig[1] == NCI_PARAM_ID_LF_T3T_MAX) {
1700 LOG(DEBUG) << StringPrintf("%s: lfT3tMax=%d", __func__,
1701 gConfig[3]);
1702 sLfT3tMax = gConfig[3];
1703 }
1704 }
1705 }
1706
1707 prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED;
1708
1709 // Do custom NFCA startup configuration.
1710 doStartupConfig();
1711 #ifdef DTA_ENABLED
1712 NfcDta::getInstance().setNfccConfigParams();
1713 #endif /* DTA_ENABLED */
1714 goto TheEnd;
1715 }
1716 }
1717
1718 if (gIsDtaEnabled == true) {
1719 LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
1720 __func__);
1721 NFA_DisableDtamode();
1722 }
1723
1724 LOG(ERROR) << StringPrintf("%s: fail nfa enable; error=0x%X", __func__,
1725 stat);
1726
1727 if (sIsNfaEnabled) {
1728 stat = NFA_Disable(FALSE /* ungraceful */);
1729 }
1730
1731 theInstance.Finalize();
1732 }
1733
1734 TheEnd:
1735 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1736 return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE;
1737 }
1738
nfcManager_doSetPartialInitMode(JNIEnv *,jobject,jint mode)1739 static void nfcManager_doSetPartialInitMode(JNIEnv*, jobject, jint mode) {
1740 if (sIsShuttingDown) return;
1741 gPartialInitMode = mode;
1742 }
1743
nfcManager_doEnableDtaMode(JNIEnv *,jobject)1744 static void nfcManager_doEnableDtaMode(JNIEnv*, jobject) {
1745 if (sIsShuttingDown) return;
1746 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1747 gIsDtaEnabled = true;
1748 }
1749
nfcManager_doDisableDtaMode(JNIEnv *,jobject)1750 static void nfcManager_doDisableDtaMode(JNIEnv*, jobject) {
1751 if (sIsShuttingDown) return;
1752 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1753 gIsDtaEnabled = false;
1754 }
1755
nfcManager_doFactoryReset(JNIEnv *,jobject)1756 static void nfcManager_doFactoryReset(JNIEnv*, jobject) {
1757 if (sIsShuttingDown) return;
1758 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1759 theInstance.FactoryReset();
1760 }
1761
nfcManager_doShutdown(JNIEnv *,jobject)1762 static void nfcManager_doShutdown(JNIEnv*, jobject) {
1763 if (sIsShuttingDown) return;
1764 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1765 NativeT4tNfcee::getInstance().onNfccShutdown();
1766 theInstance.DeviceShutdown();
1767 sIsShuttingDown = true;
1768 }
1769
nfcManager_configNfccConfigControl(bool flag)1770 static void nfcManager_configNfccConfigControl(bool flag) {
1771 // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1772 if (NFC_GetNCIVersion() != NCI_VERSION_1_0) {
1773 uint8_t nfa_set_config[] = { 0x00 };
1774
1775 nfa_set_config[0] = (flag == true ? 1 : 0);
1776
1777 tNFA_STATUS status = NFA_SetConfig(NCI_PARAM_ID_NFCC_CONFIG_CONTROL,
1778 sizeof(nfa_set_config),
1779 &nfa_set_config[0]);
1780 if (status != NFA_STATUS_OK) {
1781 LOG(ERROR) << __func__
1782 << ": Failed to configure NFCC_CONFIG_CONTROL";
1783 }
1784 }
1785 }
1786
isReaderModeAnnotationSupported(JNIEnv * e,jobject o)1787 static bool isReaderModeAnnotationSupported(JNIEnv* e, jobject o) {
1788 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
1789 jmethodID isSupported =
1790 e->GetMethodID(cls.get(), "isReaderModeAnnotationSupportedCaps", "()Z");
1791 return e->CallBooleanMethod(o, isSupported);
1792 }
1793
setTechAPollingLoopAnnotation(JNIEnv * env,jobject o,const uint8_t * annotation_data,size_t annotation_size)1794 static tNFA_STATUS setTechAPollingLoopAnnotation(JNIEnv* env, jobject o,
1795 const uint8_t* annotation_data,
1796 size_t annotation_size) {
1797 std::vector<uint8_t> command;
1798 command.push_back(NCI_ANDROID_SET_TECH_A_POLLING_LOOP_ANNOTATION);
1799 if (annotation_data == NULL || annotation_size == 0) {
1800 // Annotation is null or size is 0, setting 0 annotations
1801 command.push_back(0x00);
1802 } else {
1803 command.push_back(0x01); // Number of frame entries.
1804 command.push_back(0x21); // Position and type.
1805 command.push_back(annotation_size + 3); // Length
1806 command.push_back(0x0a); // Waiting time
1807 command.insert(command.end(), annotation_data, annotation_data + annotation_size);
1808 command.push_back(0x00);
1809 command.push_back(0x00);
1810 }
1811 SyncEventGuard guard(gNfaVsCommand);
1812 tNFA_STATUS status =
1813 NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, command.size(), command.data(), nfaVSCallback);
1814 if (status == NFA_STATUS_OK) {
1815 if (!gNfaVsCommand.wait(1000)) {
1816 LOG(ERROR) << StringPrintf(
1817 "%s: Timed out waiting for a response to setting a polling loop annotation ",
1818 __FUNCTION__);
1819 gVSCmdStatus = NFA_STATUS_FAILED;
1820 }
1821 } else {
1822 gVSCmdStatus = status;
1823 }
1824 return gVSCmdStatus;
1825 }
1826
1827 /*******************************************************************************
1828 **
1829 ** Function: nfcManager_enableDiscovery
1830 **
1831 ** Description: Start polling and listening for devices.
1832 ** e: JVM environment.
1833 ** o: Java object.
1834 ** technologies_mask: the bitmask of technologies for which to
1835 *enable discovery
1836 ** enable_lptd: whether to enable low power polling (default:
1837 *false)
1838 **
1839 ** Returns: None
1840 **
1841 *******************************************************************************/
nfcManager_enableDiscovery(JNIEnv * e,jobject o,jint technologies_mask,jboolean enable_lptd,jboolean reader_mode,jboolean enable_host_routing,jbyteArray tech_a_polling_loop_annotation,jboolean restart)1842 static void nfcManager_enableDiscovery(JNIEnv* e, jobject o,
1843 jint technologies_mask,
1844 jboolean enable_lptd,
1845 jboolean reader_mode,
1846 jboolean enable_host_routing,
1847 jbyteArray tech_a_polling_loop_annotation,
1848 jboolean restart) {
1849 if (sIsShuttingDown) return;
1850 tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
1851 struct nfc_jni_native_data* nat = getNative(e, o);
1852
1853 if (technologies_mask == -1 && nat)
1854 tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask;
1855 else if (technologies_mask != -1)
1856 tech_mask = (tNFA_TECHNOLOGY_MASK)technologies_mask;
1857 LOG(DEBUG) << StringPrintf("%s: enter; tech_mask = %02x", __func__,
1858 tech_mask);
1859
1860 if (sDiscoveryEnabled && !restart) {
1861 LOG(ERROR) << StringPrintf("%s: already discovering", __func__);
1862 return;
1863 }
1864
1865 if (sRfEnabled) {
1866 // Stop RF discovery to reconfigure
1867 startRfDiscovery(false);
1868 }
1869
1870 // Check polling configuration
1871 if (tech_mask != 0) {
1872 stopPolling_rfDiscoveryDisabled();
1873 if (isReaderModeAnnotationSupported(e, o)) {
1874 if (reader_mode) {
1875 if (tech_a_polling_loop_annotation == NULL) {
1876 setTechAPollingLoopAnnotation(e, o, NULL, 0);
1877 } else {
1878 ScopedByteArrayRO annotationBytes(e, tech_a_polling_loop_annotation);
1879 setTechAPollingLoopAnnotation(e, o,
1880 (const uint8_t*)annotationBytes.get(),
1881 annotationBytes.size());
1882 }
1883 } else if (reader_mode_ignore_frame()) {
1884 uint8_t ignoreFrame[] = {0x6a, 0x01, 0xcf, 0x00, 0x00};
1885 setTechAPollingLoopAnnotation(e, 0, ignoreFrame, 5);
1886 }
1887 }
1888
1889 startPolling_rfDiscoveryDisabled(tech_mask);
1890
1891 if (sPollingEnabled) {
1892 if (reader_mode && !sReaderModeEnabled) {
1893 sReaderModeEnabled = true;
1894 NFA_DisableListening();
1895
1896 // configure NFCC_CONFIG_CONTROL- NFCC not allowed to manage RF configuration.
1897 nfcManager_configNfccConfigControl(false);
1898
1899 NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
1900 } else if (!reader_mode && sReaderModeEnabled) {
1901 struct nfc_jni_native_data* nat = getNative(e, o);
1902 sReaderModeEnabled = false;
1903 NFA_EnableListening();
1904
1905 // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1906 nfcManager_configNfccConfigControl(true);
1907
1908 if (nat) {
1909 NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1910 } else {
1911 LOG(ERROR) << StringPrintf("%s: nat is null", __func__);
1912 }
1913 }
1914 }
1915 } else {
1916 if (!reader_mode && sReaderModeEnabled) {
1917 LOG(DEBUG) << StringPrintf(
1918 "%s: if reader mode disable, enable listen again", __func__);
1919 struct nfc_jni_native_data* nat = getNative(e, o);
1920 sReaderModeEnabled = false;
1921 NFA_EnableListening();
1922
1923 // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
1924 nfcManager_configNfccConfigControl(true);
1925
1926 if (nat) {
1927 NFA_SetRfDiscoveryDuration(nat->discovery_duration);
1928 } else {
1929 LOG(ERROR) << StringPrintf("%s: nat is null", __func__);
1930 }
1931 }
1932 // No technologies configured, stop polling
1933 stopPolling_rfDiscoveryDisabled();
1934 }
1935
1936 // Checking if RT should be updated
1937 RoutingManager::getInstance().commitRouting();
1938
1939 // Actually start discovery.
1940 startRfDiscovery(true);
1941 sDiscoveryEnabled = true;
1942
1943 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
1944 }
1945
1946 /*******************************************************************************
1947 **
1948 ** Function: nfcManager_disableDiscovery
1949 **
1950 ** Description: Stop polling and listening for devices.
1951 ** e: JVM environment.
1952 ** o: Java object.
1953 **
1954 ** Returns: None
1955 **
1956 *******************************************************************************/
nfcManager_disableDiscovery(JNIEnv * e,jobject o)1957 void nfcManager_disableDiscovery(JNIEnv* e, jobject o) {
1958 if (sIsShuttingDown) return;
1959 tNFA_STATUS status = NFA_STATUS_OK;
1960 LOG(DEBUG) << StringPrintf("%s: enter;", __func__);
1961
1962 if (sDiscoveryEnabled == false) {
1963 LOG(DEBUG) << StringPrintf("%s: already disabled", __func__);
1964 goto TheEnd;
1965 }
1966
1967 // Stop RF Discovery.
1968 startRfDiscovery(false);
1969 sDiscoveryEnabled = false;
1970 if (sPollingEnabled) status = stopPolling_rfDiscoveryDisabled();
1971
1972 TheEnd:
1973 LOG(DEBUG) << StringPrintf("%s: exit: Status = 0x%X", __func__, status);
1974 }
1975
1976 /*******************************************************************************
1977 **
1978 ** Function: doPartialDeinit
1979 **
1980 ** Description: Partial DeInit for mode TRANSPARENT, CE ..
1981 **
1982 ** Returns: True if ok.
1983 **
1984 *******************************************************************************/
doPartialDeinit()1985 static jboolean doPartialDeinit() {
1986 if (sIsShuttingDown) return false;
1987 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
1988 tNFA_STATUS stat = NFA_STATUS_OK;
1989 sIsDisabling = true;
1990 if (sIsNfaEnabled) {
1991 SyncEventGuard guard(sNfaDisableEvent);
1992 stat = NFA_Disable(TRUE /* graceful */);
1993 if (stat == NFA_STATUS_OK) {
1994 LOG(DEBUG) << StringPrintf("%s: wait for completion", __func__);
1995 sNfaDisableEvent.wait(); // wait for NFA command to finish
1996 } else {
1997 LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__,
1998 stat);
1999 }
2000 }
2001 sIsDisabling = false;
2002
2003 LOG(DEBUG) << StringPrintf("%s: deregister VS callbacks", __func__);
2004 NFA_RegVSCback(false, &nfaVSCallback);
2005
2006 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
2007 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
2008 theInstance.Finalize();
2009
2010 return stat == NFA_STATUS_OK ? JNI_TRUE : JNI_FALSE;
2011 }
2012
2013 /*******************************************************************************
2014 **
2015 ** Function: nfcManager_doDeinitialize
2016 **
2017 ** Description: Turn off NFC.
2018 ** e: JVM environment.
2019 ** o: Java object.
2020 **
2021 ** Returns: True if ok.
2022 **
2023 *******************************************************************************/
nfcManager_doDeinitialize(JNIEnv *,jobject)2024 static jboolean nfcManager_doDeinitialize(JNIEnv*, jobject) {
2025 if (sIsShuttingDown) return false;
2026 LOG(DEBUG) << StringPrintf("%s: enter, sIsRecovering=%d", __func__,
2027 sIsRecovering);
2028 if (gPartialInitMode != ENABLE_MODE_DEFAULT) {
2029 return doPartialDeinit();
2030 }
2031 sIsDisabling = true;
2032
2033 NativeT4tNfcee::getInstance().onNfccShutdown();
2034 if (!recovery_option || !sIsRecovering) {
2035 RoutingManager::getInstance().onNfccShutdown();
2036 }
2037 HciEventManager::getInstance().finalize();
2038
2039 if (sIsNfaEnabled) {
2040 SyncEventGuard guard(sNfaDisableEvent);
2041
2042 if (gIsDtaEnabled == true) {
2043 LOG(DEBUG) << StringPrintf("%s: DTA; unset dta flag in core stack",
2044 __func__);
2045 NFA_DisableDtamode();
2046 }
2047
2048 tNFA_STATUS stat = NFA_Disable(!sIsRecovering);
2049 if (stat == NFA_STATUS_OK) {
2050 LOG(DEBUG) << StringPrintf("%s: wait for completion", __func__);
2051 if (!sNfaDisableEvent.wait(5000)) {
2052 LOG(ERROR) << StringPrintf(
2053 "%s: NFA_Disable() timeout, keep disabling anyway", __func__);
2054 }
2055 } else {
2056 LOG(ERROR) << StringPrintf("%s: fail disable; error=0x%X", __func__,
2057 stat);
2058 }
2059 }
2060 nativeNfcTag_abortWaits();
2061 NfcTag::getInstance().abort();
2062 sAbortConnlessWait = true;
2063 sIsNfaEnabled = false;
2064 sRoutingInitialized = false;
2065 sDiscoveryEnabled = false;
2066 sPollingEnabled = false;
2067 sIsDisabling = false;
2068 sReaderModeEnabled = false;
2069 gActivated = false;
2070 sRfEnabled = false;
2071 sLfT3tMax = 0;
2072
2073 {
2074 // unblock NFA_EnablePolling() and NFA_DisablePolling()
2075 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2076 sNfaEnableDisablePollingEvent.notifyOne();
2077 }
2078
2079 LOG(DEBUG) << StringPrintf("%s: deregister VS callbacks", __func__);
2080 NFA_RegVSCback(false, &nfaVSCallback);
2081 // abort any active waits
2082 {
2083 SyncEventGuard guard(sNfaSetPowerSubState);
2084 sNfaSetPowerSubState.notifyOne();
2085 }
2086 {
2087 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2088 sNfaEnableDisablePollingEvent.notifyOne();
2089 }
2090 {
2091 SyncEventGuard guard(gNfaSetConfigEvent);
2092 gNfaSetConfigEvent.notifyOne();
2093 }
2094 {
2095 SyncEventGuard guard(gNfaGetConfigEvent);
2096 gNfaGetConfigEvent.notifyOne();
2097 }
2098 {
2099 SyncEventGuard guard(gNfaVsCommand);
2100 gNfaVsCommand.notifyOne();
2101 }
2102 {
2103 SyncEventGuard guard(gSendRawVsCmdEvent);
2104 gSendRawVsCmdEvent.notifyOne();
2105 }
2106 {
2107 SyncEventGuard guard(gNfaRemoveEpEvent);
2108 gNfaRemoveEpEvent.notifyOne();
2109 }
2110
2111 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
2112 theInstance.Finalize();
2113
2114 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
2115 return JNI_TRUE;
2116 }
2117
2118 /*******************************************************************************
2119 **
2120 ** Function: isListenMode
2121 **
2122 ** Description: Indicates whether the activation data indicates it is
2123 ** listen mode.
2124 **
2125 ** Returns: True if this listen mode.
2126 **
2127 *******************************************************************************/
isListenMode(tNFA_ACTIVATED & activated)2128 static bool isListenMode(tNFA_ACTIVATED& activated) {
2129 return (
2130 (NFC_DISCOVERY_TYPE_LISTEN_A ==
2131 activated.activate_ntf.rf_tech_param.mode) ||
2132 (NFC_DISCOVERY_TYPE_LISTEN_B ==
2133 activated.activate_ntf.rf_tech_param.mode) ||
2134 (NFC_DISCOVERY_TYPE_LISTEN_F ==
2135 activated.activate_ntf.rf_tech_param.mode) ||
2136 (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 ==
2137 activated.activate_ntf.rf_tech_param.mode) ||
2138 (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME ==
2139 activated.activate_ntf.rf_tech_param.mode) ||
2140 (NFC_INTERFACE_EE_DIRECT_RF == activated.activate_ntf.intf_param.type));
2141 }
2142
2143 /*******************************************************************************
2144 **
2145 ** Function: nfcManager_doAbort
2146 **
2147 ** Description: Not used.
2148 **
2149 ** Returns: None
2150 **
2151 *******************************************************************************/
nfcManager_doAbort(JNIEnv * e,jobject,jstring msg)2152 static void nfcManager_doAbort(JNIEnv* e, jobject, jstring msg) {
2153 ScopedUtfChars message = {e, msg};
2154 e->FatalError(message.c_str());
2155 abort(); // <-- Unreachable
2156 }
2157
2158 /*******************************************************************************
2159 **
2160 ** Function: nfcManager_doDownload
2161 **
2162 ** Description: Download firmware patch files. Do not turn on NFC.
2163 **
2164 ** Returns: True if ok.
2165 **
2166 *******************************************************************************/
nfcManager_doDownload(JNIEnv *,jobject)2167 static jboolean nfcManager_doDownload(JNIEnv*, jobject) {
2168 if (sIsShuttingDown) return false;
2169 LOG(DEBUG) << StringPrintf("%s: enter", __func__);
2170 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
2171 bool result = JNI_FALSE;
2172 theInstance.Initialize(); // start GKI, NCI task, NFC task
2173 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
2174 NFA_Partial_Init(halFuncEntries, ENABLE_MODE_TRANSPARENT);
2175 NFA_RegVSCback(true, &nfaVSCallback);
2176 result = theInstance.DownloadFirmware();
2177 NFA_RegVSCback(false, &nfaVSCallback);
2178 theInstance.Finalize();
2179 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
2180 return result;
2181 }
2182
2183 /*******************************************************************************
2184 **
2185 ** Function: nfcManager_doResetTimeouts
2186 **
2187 ** Description: Not used.
2188 **
2189 ** Returns: None
2190 **
2191 *******************************************************************************/
nfcManager_doResetTimeouts(JNIEnv *,jobject)2192 static void nfcManager_doResetTimeouts(JNIEnv*, jobject) {
2193 if (sIsShuttingDown) return;
2194 LOG(DEBUG) << StringPrintf("%s", __func__);
2195 NfcTag::getInstance().resetAllTransceiveTimeouts(true);
2196 }
2197
2198 /*******************************************************************************
2199 **
2200 ** Function: nfcManager_doSetTimeout
2201 **
2202 ** Description: Set timeout value.
2203 ** e: JVM environment.
2204 ** o: Java object.
2205 ** tech: technology ID.
2206 ** timeout: Timeout value.
2207 **
2208 ** Returns: True if ok.
2209 **
2210 *******************************************************************************/
nfcManager_doSetTimeout(JNIEnv *,jobject,jint tech,jint timeout)2211 static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint tech, jint timeout) {
2212 if (sIsShuttingDown) return false;
2213 if (timeout <= 0) {
2214 LOG(ERROR) << StringPrintf("%s: Timeout must be positive.", __func__);
2215 return false;
2216 }
2217 LOG(DEBUG) << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech,
2218 timeout);
2219 NfcTag::getInstance().setTransceiveTimeout(tech, timeout);
2220 return true;
2221 }
2222
2223 /*******************************************************************************
2224 **
2225 ** Function: nfcManager_doGetTimeout
2226 **
2227 ** Description: Get timeout value.
2228 ** e: JVM environment.
2229 ** o: Java object.
2230 ** tech: technology ID.
2231 **
2232 ** Returns: Timeout value.
2233 **
2234 *******************************************************************************/
nfcManager_doGetTimeout(JNIEnv *,jobject,jint tech)2235 static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint tech) {
2236 if (sIsShuttingDown) return -1;
2237 int timeout = NfcTag::getInstance().getTransceiveTimeout(tech);
2238 LOG(DEBUG) << StringPrintf("%s: tech=%d, timeout=%d", __func__, tech,
2239 timeout);
2240 return timeout;
2241 }
2242
2243 /*******************************************************************************
2244 **
2245 ** Function: nfcManager_doDump
2246 **
2247 ** Description: Get libnfc-nci dump
2248 ** e: JVM environment.
2249 ** obj: Java object.
2250 ** fdobj: File descriptor to be used
2251 **
2252 ** Returns: Void
2253 **
2254 *******************************************************************************/
nfcManager_doDump(JNIEnv * e,jobject obj,jobject fdobj)2255 static void nfcManager_doDump(JNIEnv* e, jobject obj, jobject fdobj) {
2256 if (sIsShuttingDown) return;
2257 int fd = jniGetFDFromFileDescriptor(e, fdobj);
2258 if (fd < 0) return;
2259
2260 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
2261 theInstance.Dump(fd);
2262 }
2263
nfcManager_doGetNciVersion(JNIEnv *,jobject)2264 static jint nfcManager_doGetNciVersion(JNIEnv*, jobject) {
2265 if (sIsShuttingDown) return -1;
2266 return NFC_GetNCIVersion();
2267 }
2268
nfcManager_doSetScreenState(JNIEnv * e,jobject o,jint screen_state_mask,jboolean alwaysPoll)2269 static void nfcManager_doSetScreenState(JNIEnv* e, jobject o,
2270 jint screen_state_mask,
2271 jboolean alwaysPoll) {
2272 if (sIsShuttingDown) return;
2273 tNFA_STATUS status = NFA_STATUS_OK;
2274 uint8_t state = (screen_state_mask & NFA_SCREEN_STATE_MASK);
2275 uint8_t discovry_param =
2276 NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
2277 sIsAlwaysPolling = alwaysPoll;
2278
2279 LOG(DEBUG) << StringPrintf(
2280 "%s: state = %d prevScreenState= %d, discovry_param = %d", __FUNCTION__,
2281 state, prevScreenState, discovry_param);
2282
2283 if (prevScreenState == state) {
2284 LOG(DEBUG) << StringPrintf(
2285 "%s: New screen state is same as previous state. No action taken",
2286 __func__);
2287 return;
2288 }
2289
2290 if (sIsDisabling || !sIsNfaEnabled ||
2291 (NFC_GetNCIVersion() != NCI_VERSION_2_0)) {
2292 prevScreenState = state;
2293 return;
2294 }
2295
2296 // skip remaining SetScreenState tasks when trying to silent recover NFCC
2297 if (recovery_option && sIsRecovering) {
2298 prevScreenState = state;
2299 return;
2300 }
2301
2302 if (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED ||
2303 prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED ||
2304 prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) {
2305 SyncEventGuard guard(sNfaSetPowerSubState);
2306 status = NFA_SetPowerSubStateForScreenState(state);
2307 if (status != NFA_STATUS_OK) {
2308 LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
2309 __FUNCTION__, status);
2310 return;
2311 } else {
2312 sNfaSetPowerSubState.wait();
2313 }
2314 }
2315
2316 // skip remaining SetScreenState tasks when trying to silent recover NFCC
2317 if (recovery_option && sIsRecovering) {
2318 prevScreenState = state;
2319 return;
2320 }
2321
2322 if (state == NFA_SCREEN_STATE_OFF_LOCKED ||
2323 state == NFA_SCREEN_STATE_OFF_UNLOCKED) {
2324 // disable poll and enable listen on DH 0x00
2325 discovry_param =
2326 NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_ENABLE_MASK;
2327 }
2328
2329 if (state == NFA_SCREEN_STATE_ON_LOCKED) {
2330 // disable poll and enable listen on DH 0x00
2331 discovry_param =
2332 (screen_state_mask & NFA_SCREEN_POLLING_TAG_MASK)
2333 ? (NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK)
2334 : (NCI_POLLING_DH_DISABLE_MASK | NCI_LISTEN_DH_NFCEE_ENABLE_MASK);
2335 }
2336
2337 if (state == NFA_SCREEN_STATE_ON_UNLOCKED) {
2338 // enable both poll and listen on DH 0x01
2339 discovry_param =
2340 NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
2341 }
2342
2343 if (!sIsAlwaysPolling) {
2344 SyncEventGuard guard(gNfaSetConfigEvent);
2345 status = NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM,
2346 NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param);
2347 if (status == NFA_STATUS_OK) {
2348 gNfaSetConfigEvent.wait();
2349 } else {
2350 LOG(ERROR) << StringPrintf("%s: Failed to update CON_DISCOVER_PARAM",
2351 __FUNCTION__);
2352 return;
2353 }
2354 }
2355 // skip remaining SetScreenState tasks when trying to silent recover NFCC
2356 if (recovery_option && sIsRecovering) {
2357 prevScreenState = state;
2358 return;
2359 }
2360
2361 if (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) {
2362 SyncEventGuard guard(sNfaSetPowerSubState);
2363 status = NFA_SetPowerSubStateForScreenState(state);
2364 if (status != NFA_STATUS_OK) {
2365 LOG(ERROR) << StringPrintf("%s: fail enable SetScreenState; error=0x%X",
2366 __FUNCTION__, status);
2367 } else {
2368 sNfaSetPowerSubState.wait();
2369 }
2370 }
2371
2372 // skip remaining SetScreenState tasks when trying to silent recover NFCC
2373 if (recovery_option && sIsRecovering) {
2374 prevScreenState = state;
2375 return;
2376 }
2377
2378 if ((state == NFA_SCREEN_STATE_OFF_LOCKED ||
2379 state == NFA_SCREEN_STATE_OFF_UNLOCKED) &&
2380 (prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED ||
2381 prevScreenState == NFA_SCREEN_STATE_ON_LOCKED) &&
2382 (!sSeRfActive)) {
2383 // screen turns off, disconnect tag if connected
2384 nativeNfcTag_doDisconnect(NULL, NULL);
2385 }
2386
2387 prevScreenState = state;
2388 }
2389
2390 /*******************************************************************************
2391 **
2392 ** Function: nfcManager_getIsoDepMaxTransceiveLength
2393 **
2394 ** Description: Get maximum ISO DEP Transceive Length supported by the NFC
2395 ** chip. Returns default 261 bytes if the property is not set.
2396 **
2397 ** Returns: max value.
2398 **
2399 *******************************************************************************/
nfcManager_getIsoDepMaxTransceiveLength(JNIEnv *,jobject)2400 static jint nfcManager_getIsoDepMaxTransceiveLength(JNIEnv*, jobject) {
2401 if (sIsShuttingDown) return -1;
2402 /* Check if extended APDU is supported by the chip.
2403 * If not, default value is returned.
2404 * The maximum length of a default IsoDep frame consists of:
2405 * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
2406 */
2407 return NfcConfig::getUnsigned(NAME_ISO_DEP_MAX_TRANSCEIVE, 261);
2408 }
2409
2410 /*******************************************************************************
2411 **
2412 ** Function: nfcManager_getAidTableSize
2413 ** Description: Get the maximum supported size for AID routing table.
2414 **
2415 ** e: JVM environment.
2416 ** o: Java object.
2417 **
2418 *******************************************************************************/
nfcManager_getAidTableSize(JNIEnv *,jobject)2419 static jint nfcManager_getAidTableSize(JNIEnv*, jobject) {
2420 if (sIsShuttingDown) return -1;
2421 return NFA_GetAidTableSize();
2422 }
2423
2424 /*******************************************************************************
2425 **
2426 ** Function: nfcManager_IsMultiTag
2427 **
2428 ** Description: Check if it a multi tag case.
2429 ** e: JVM environment.
2430 ** o: Java object.
2431 **
2432 ** Returns: None.
2433 **
2434 *******************************************************************************/
nfcManager_isMultiTag()2435 static bool nfcManager_isMultiTag() {
2436 if (sIsShuttingDown) return false;
2437 LOG(DEBUG) << StringPrintf("%s: enter mNumRfDiscId = %d", __func__,
2438 NfcTag::getInstance().mNumRfDiscId);
2439 bool status = false;
2440 if (NfcTag::getInstance().mNumRfDiscId > 1) status = true;
2441 LOG(DEBUG) << StringPrintf("isMultiTag = %d", status);
2442 return status;
2443 }
2444
2445 /*******************************************************************************
2446 **
2447 ** Function: nfcManager_doStartStopPolling
2448 **
2449 ** Description: Start or stop NFC RF polling
2450 ** e: JVM environment.
2451 ** o: Java object.
2452 ** start: start or stop RF polling
2453 **
2454 ** Returns: None
2455 **
2456 *******************************************************************************/
nfcManager_doStartStopPolling(JNIEnv * e,jobject o,jboolean start)2457 static void nfcManager_doStartStopPolling(JNIEnv* e, jobject o,
2458 jboolean start) {
2459 if (sIsShuttingDown) return;
2460 startStopPolling(start);
2461 }
2462
2463 /*******************************************************************************
2464 **
2465 ** Function: nfcManager_doSetNfcSecure
2466 **
2467 ** Description: Set NfcSecure enable/disable.
2468 ** e: JVM environment.
2469 ** o: Java object.
2470 ** enable: Sets true/false to enable/disable NfcSecure
2471 ** It only updates the routing table cache without commit to
2472 ** NFCC.
2473 **
2474 ** Returns: True always
2475 **
2476 *******************************************************************************/
nfcManager_doSetNfcSecure(JNIEnv * e,jobject o,jboolean enable)2477 static jboolean nfcManager_doSetNfcSecure(JNIEnv* e, jobject o,
2478 jboolean enable) {
2479 if (sIsShuttingDown) return false;
2480 RoutingManager& routingManager = RoutingManager::getInstance();
2481 routingManager.setNfcSecure(enable);
2482 if (sRoutingInitialized) {
2483 routingManager.setEeTechRouteUpdateRequired();
2484 }
2485 return true;
2486 }
2487
nfcManager_doSetNfceePowerAndLinkCtrl(JNIEnv * e,jobject o,jboolean enable)2488 static void nfcManager_doSetNfceePowerAndLinkCtrl(JNIEnv* e, jobject o,
2489 jboolean enable) {
2490 if (sIsShuttingDown) return;
2491 RoutingManager& routingManager = RoutingManager::getInstance();
2492 if (enable) {
2493 routingManager.eeSetPwrAndLinkCtrl(
2494 (uint8_t)always_on_nfcee_power_and_link_conf);
2495 } else {
2496 routingManager.eeSetPwrAndLinkCtrl(
2497 (uint8_t)disable_always_on_nfcee_power_and_link_conf);
2498 }
2499 }
2500
2501 /*******************************************************************************
2502 **
2503 ** Function: nfcManager_doGetMaxRoutingTableSize
2504 **
2505 ** Description: Retrieve the max routing table size from cache
2506 ** e: JVM environment.
2507 ** o: Java object.
2508 **
2509 ** Returns: Max Routing Table size
2510 **
2511 *******************************************************************************/
nfcManager_doGetMaxRoutingTableSize(JNIEnv * e,jobject o)2512 static jint nfcManager_doGetMaxRoutingTableSize(JNIEnv* e, jobject o) {
2513 if (sIsShuttingDown) return -1;
2514 return lmrt_get_max_size();
2515 }
2516
2517 /*******************************************************************************
2518 **
2519 ** Function: nfcManager_doGetRoutingTable
2520 **
2521 ** Description: Retrieve the committed listen mode routing configuration
2522 ** e: JVM environment.
2523 ** o: Java object.
2524 **
2525 ** Returns: Committed listen mode routing configuration
2526 **
2527 *******************************************************************************/
nfcManager_doGetRoutingTable(JNIEnv * e,jobject o)2528 static jbyteArray nfcManager_doGetRoutingTable(JNIEnv* e, jobject o) {
2529 if (sIsShuttingDown) return nullptr;
2530 std::vector<uint8_t>* routingTable = lmrt_get_tlvs();
2531
2532 CHECK(e);
2533 jbyteArray rtJavaArray = e->NewByteArray((*routingTable).size());
2534 CHECK(rtJavaArray);
2535 e->SetByteArrayRegion(rtJavaArray, 0, (*routingTable).size(),
2536 (jbyte*)&(*routingTable)[0]);
2537
2538 return rtJavaArray;
2539 }
2540
nfcManager_clearRoutingEntry(JNIEnv * e,jobject o,jint clearFlags)2541 static void nfcManager_clearRoutingEntry(JNIEnv* e, jobject o,
2542 jint clearFlags) {
2543 if (sIsShuttingDown) return;
2544 LOG(DEBUG) << StringPrintf("%s: clearFlags=0x%X", __func__, clearFlags);
2545 RoutingManager::getInstance().clearRoutingEntry(clearFlags);
2546 }
2547
2548 /*******************************************************************************
2549 **
2550 ** Function: nfcManager_doDetectEpRemoval
2551 **
2552 ** Description: Start detection of WLC Listener removal
2553 ** e: JVM environment.
2554 ** waiting_time_int:
2555
2556 **
2557 ** Returns: True if WLCL remove started properly
2558 **
2559 *******************************************************************************/
nfcManager_doDetectEpRemoval(JNIEnv * e,jobject o,jint waiting_time_int)2560 static jboolean nfcManager_doDetectEpRemoval(JNIEnv* e, jobject o,
2561 jint waiting_time_int) {
2562 if (sIsShuttingDown) return false;
2563 tNFA_STATUS stat = NFA_STATUS_FAILED;
2564
2565 LOG(DEBUG) << StringPrintf("%s: enter waiting_time = %04X", __func__,
2566 waiting_time_int);
2567
2568 nativeNfcTag_acquireRfInterfaceMutexLock();
2569 stat = NFA_StartRemovalDetection((uint8_t)(waiting_time_int & 0xFF));
2570 if (stat == NFA_STATUS_OK) {
2571 LOG(DEBUG) << StringPrintf(
2572 "%s: start detect EP Listener removal, wait for success confirmation",
2573 __func__);
2574 SyncEventGuard g(gNfaRemoveEpEvent);
2575 gNfaRemoveEpEvent.wait();
2576 stat = sIsEpDetectStarted ? JNI_TRUE : JNI_FALSE;
2577 } else {
2578 LOG(ERROR) << StringPrintf("%s: fail detect EP removal; error=0x%X",
2579 __func__, stat);
2580 stat = false;
2581 }
2582 nativeNfcTag_releaseRfInterfaceMutexLock();
2583 return stat;
2584 }
2585
2586 /*******************************************************************************
2587 **
2588 ** Function: nfcManager_isRemovalDetectionSupported
2589 **
2590 ** Description: Check if the Removal Detection in Poll mode is supported.
2591 ** e: JVM environment.
2592 ** o: Java object.
2593 **
2594 ** Returns: True if supports 'Removal Detection Mode'
2595 **
2596 *******************************************************************************/
nfcManager_isRemovalDetectionSupported(JNIEnv * e,jobject o)2597 static jboolean nfcManager_isRemovalDetectionSupported(JNIEnv* e, jobject o) {
2598 if (sIsShuttingDown) return false;
2599 return NFA_IsRfRemovalDetectionSupported();
2600 }
2601
nfcManager_updateIsoDepProtocolRoute(JNIEnv * e,jobject o,jint route)2602 static void nfcManager_updateIsoDepProtocolRoute(JNIEnv* e, jobject o,
2603 jint route) {
2604 if (sIsShuttingDown) return;
2605 LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2606 RoutingManager::getInstance().updateIsoDepProtocolRoute(route);
2607 }
2608
nfcManager_updateTechnologyABFRoute(JNIEnv * e,jobject o,jint route,jint felicaRoute)2609 static void nfcManager_updateTechnologyABFRoute(JNIEnv* e, jobject o,
2610 jint route, jint felicaRoute) {
2611 if (sIsShuttingDown) return;
2612 LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2613 RoutingManager::getInstance().updateTechnologyABFRoute(route, felicaRoute);
2614 }
2615
nfcManager_updateSystemCodeRoute(JNIEnv * e,jobject o,jint route)2616 static void nfcManager_updateSystemCodeRoute(JNIEnv* e, jobject o,
2617 jint route) {
2618 if (sIsShuttingDown) return;
2619 LOG(DEBUG) << StringPrintf("%s: route=0x%X", __func__, route);
2620 RoutingManager::getInstance().updateSystemCodeRoute(route);
2621 }
2622
2623 /*******************************************************************************
2624 **
2625 ** Function: nfcManager_setDiscoveryTech
2626 **
2627 ** Description: Temporarily changes the RF parameter
2628 ** pollTech: RF tech parameters for poll mode
2629 ** listenTech: RF tech parameters for listen mode
2630 **
2631 ** Returns: None.
2632 **
2633 *******************************************************************************/
nfcManager_setDiscoveryTech(JNIEnv * e,jobject o,jint pollTech,jint listenTech)2634 static void nfcManager_setDiscoveryTech(JNIEnv* e, jobject o, jint pollTech,
2635 jint listenTech) {
2636 if (sIsShuttingDown) return;
2637 tNFA_STATUS nfaStat;
2638 bool isRevertPoll = false;
2639 bool isRevertListen = false;
2640 bool changeDefaultTech = false;
2641 LOG(DEBUG) << StringPrintf("%s pollTech = 0x%x, listenTech = 0x%x", __func__,
2642 pollTech, listenTech);
2643
2644 if (pollTech < 0) isRevertPoll = true;
2645 if (listenTech < 0) isRevertListen = true;
2646 if (pollTech & FLAG_SET_DEFAULT_TECH || listenTech & FLAG_SET_DEFAULT_TECH)
2647 changeDefaultTech = true;
2648
2649 // Need listen tech routing update in routing table
2650 // for addition of blocking bit
2651 RoutingManager::getInstance().setEeTechRouteUpdateRequired();
2652
2653 nativeNfcTag_acquireRfInterfaceMutexLock();
2654 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2655
2656 nfaStat = NFA_ChangeDiscoveryTech(pollTech, listenTech, isRevertPoll,
2657 isRevertListen, changeDefaultTech);
2658
2659 if (nfaStat == NFA_STATUS_OK) {
2660 // wait for NFA_LISTEN_DISABLED_EVT
2661 sNfaEnableDisablePollingEvent.wait();
2662 } else {
2663 LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
2664 nfaStat);
2665 }
2666 nativeNfcTag_releaseRfInterfaceMutexLock();
2667 }
2668
2669 /*******************************************************************************
2670 **
2671 ** Function: nfcManager_resetDiscoveryTech
2672 **
2673 ** Description: Restores the RF tech to the state before
2674 ** nfcManager_setDiscoveryTech was called
2675 **
2676 ** Returns: None.
2677 **
2678 *******************************************************************************/
nfcManager_resetDiscoveryTech(JNIEnv * e,jobject o)2679 static void nfcManager_resetDiscoveryTech(JNIEnv* e, jobject o) {
2680 if (sIsShuttingDown) return;
2681 tNFA_STATUS nfaStat;
2682 LOG(DEBUG) << StringPrintf("%s : enter", __func__);
2683
2684 // Need listen tech routing update in routing table
2685 // for addition of blocking bit
2686 RoutingManager::getInstance().setEeTechRouteUpdateRequired();
2687
2688 nativeNfcTag_acquireRfInterfaceMutexLock();
2689 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2690
2691 nfaStat = NFA_ChangeDiscoveryTech(0xFF, 0xFF, true, true, false);
2692
2693 if (nfaStat == NFA_STATUS_OK) {
2694 // wait for NFA_LISTEN_DISABLED_EVT
2695 sNfaEnableDisablePollingEvent.wait();
2696 } else {
2697 LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
2698 nfaStat);
2699 }
2700 nativeNfcTag_releaseRfInterfaceMutexLock();
2701 }
2702
ncfManager_nativeEnableVendorNciNotifications(JNIEnv * env,jobject o,jboolean enable)2703 static void ncfManager_nativeEnableVendorNciNotifications(JNIEnv* env,
2704 jobject o,
2705 jboolean enable) {
2706 if (sIsShuttingDown) return;
2707 sEnableVendorNciNotifications = (enable == JNI_TRUE);
2708 }
2709
nfcManager_dofetchActiveNfceeList(JNIEnv * e,jobject o)2710 static jobject nfcManager_dofetchActiveNfceeList(JNIEnv* e, jobject o) {
2711 (void)o;
2712 if (sIsShuttingDown) return nullptr;
2713 return NfceeManager::getInstance().getActiveNfceeList(e);
2714 }
2715
nfcManager_nativeSendRawVendorCmd(JNIEnv * env,jobject o,jint mt,jint gid,jint oid,jbyteArray payload)2716 static jobject nfcManager_nativeSendRawVendorCmd(JNIEnv* env, jobject o,
2717 jint mt, jint gid, jint oid,
2718 jbyteArray payload) {
2719 if (sIsShuttingDown) return nullptr;
2720 LOG(DEBUG) << StringPrintf("%s : enter", __func__);
2721 ScopedByteArrayRO payloaBytes(env, payload);
2722 ScopedLocalRef<jclass> cls(env,
2723 env->FindClass(gNfcVendorNciResponseClassName));
2724 jmethodID responseConstructor =
2725 env->GetMethodID(cls.get(), "<init>", "(BII[B)V");
2726
2727 jbyte mStatus = NFA_STATUS_FAILED;
2728 jint resGid = 0;
2729 jint resOid = 0;
2730 jbyteArray resPayload = nullptr;
2731
2732 sRawVendorCmdResponse.clear();
2733
2734 std::vector<uint8_t> command;
2735 command.push_back((uint8_t)((mt << NCI_MT_SHIFT) | gid));
2736 command.push_back((uint8_t)oid);
2737 command.push_back((uint8_t)payloaBytes.size());
2738 if (payloaBytes.size() > 0) {
2739 command.insert(command.end(), &payloaBytes[0],
2740 &payloaBytes[payloaBytes.size()]);
2741 }
2742
2743 SyncEventGuard guard(gSendRawVsCmdEvent);
2744 mStatus = NFA_SendRawVsCommand(command.size(), command.data(),
2745 sendRawVsCmdCallback);
2746 if (mStatus == NFA_STATUS_OK) {
2747 if (gSendRawVsCmdEvent.wait(2000) == false) {
2748 mStatus = NFA_STATUS_FAILED;
2749 LOG(ERROR) << StringPrintf("%s: timeout ", __func__);
2750 }
2751
2752 if (mStatus == NFA_STATUS_OK && sRawVendorCmdResponse.size() > 2) {
2753 resGid = sRawVendorCmdResponse[0] & NCI_GID_MASK;
2754 resOid = sRawVendorCmdResponse[1];
2755 const jsize len = static_cast<jsize>(sRawVendorCmdResponse[2]);
2756 if (sRawVendorCmdResponse.size() >= (sRawVendorCmdResponse[2] + 3)) {
2757 resPayload = env->NewByteArray(len);
2758 std::vector<uint8_t> payloadVec(sRawVendorCmdResponse.begin() + 3,
2759 sRawVendorCmdResponse.end());
2760 env->SetByteArrayRegion(
2761 resPayload, 0, len,
2762 reinterpret_cast<const jbyte*>(payloadVec.data()));
2763 } else {
2764 mStatus = NFA_STATUS_FAILED;
2765 LOG(ERROR) << StringPrintf("%s: invalid payload data", __func__);
2766 }
2767 } else {
2768 mStatus = NFA_STATUS_FAILED;
2769 }
2770 }
2771
2772 LOG(DEBUG) << StringPrintf("%s : exit", __func__);
2773 return env->NewObject(cls.get(), responseConstructor, mStatus, resGid, resOid,
2774 resPayload);
2775 }
2776
sendRawVsCmdCallback(uint8_t event,uint16_t param_len,uint8_t * p_param)2777 static void sendRawVsCmdCallback(uint8_t event, uint16_t param_len,
2778 uint8_t* p_param) {
2779 sRawVendorCmdResponse = std::vector<uint8_t>(p_param, p_param + param_len);
2780
2781 SyncEventGuard guard(gSendRawVsCmdEvent);
2782 gSendRawVsCmdEvent.notifyOne();
2783 } /* namespace android */
2784
2785 /*****************************************************************************
2786 **
2787 ** JNI functions for android-4.0.1_r1
2788 **
2789 *****************************************************************************/
2790 static JNINativeMethod gMethods[] = {
doDownload()2791 {"doDownload", "()Z", (void*)nfcManager_doDownload},
2792
initializeNativeStructure()2793 {"initializeNativeStructure", "()Z", (void*)nfcManager_initNativeStruc},
2794
doInitialize()2795 {"doInitialize", "()Z", (void*)nfcManager_doInitialize},
2796
doSetPartialInitMode(I)2797 {"doSetPartialInitMode", "(I)V", (void*)nfcManager_doSetPartialInitMode},
2798
doDeinitialize()2799 {"doDeinitialize", "()Z", (void*)nfcManager_doDeinitialize},
2800
sendRawFrame([B)2801 {"sendRawFrame", "([B)Z", (void*)nfcManager_sendRawFrame},
2802
routeAid([BIII)2803 {"routeAid", "([BIII)Z", (void*)nfcManager_routeAid},
2804
unrouteAid([B)2805 {"unrouteAid", "([B)Z", (void*)nfcManager_unrouteAid},
2806
commitRouting()2807 {"commitRouting", "()I", (void*)nfcManager_commitRouting},
2808
doRegisterT3tIdentifier([B)2809 {"doRegisterT3tIdentifier", "([B)I",
2810 (void*)nfcManager_doRegisterT3tIdentifier},
2811
doDeregisterT3tIdentifier(I)2812 {"doDeregisterT3tIdentifier", "(I)V",
2813 (void*)nfcManager_doDeregisterT3tIdentifier},
2814
getLfT3tMax()2815 {"getLfT3tMax", "()I", (void*)nfcManager_getLfT3tMax},
2816
doEnableDiscovery(IZZZ[BZ)2817 {"doEnableDiscovery", "(IZZZ[BZ)V", (void*)nfcManager_enableDiscovery},
2818
doStartStopPolling(Z)2819 {"doStartStopPolling", "(Z)V", (void*)nfcManager_doStartStopPolling},
2820
disableDiscovery()2821 {"disableDiscovery", "()V", (void*)nfcManager_disableDiscovery},
2822
doSetTimeout(II)2823 {"doSetTimeout", "(II)Z", (void*)nfcManager_doSetTimeout},
2824
doGetTimeout(I)2825 {"doGetTimeout", "(I)I", (void*)nfcManager_doGetTimeout},
2826
doResetTimeouts()2827 {"doResetTimeouts", "()V", (void*)nfcManager_doResetTimeouts},
2828
doAbort(Ljava/lang/String;)2829 {"doAbort", "(Ljava/lang/String;)V", (void*)nfcManager_doAbort},
2830
doSetScreenState(IZ)2831 {"doSetScreenState", "(IZ)V", (void*)nfcManager_doSetScreenState},
2832
doDump(Ljava/io/FileDescriptor;)2833 {"doDump", "(Ljava/io/FileDescriptor;)V", (void*)nfcManager_doDump},
2834
getNciVersion()2835 {"getNciVersion", "()I", (void*)nfcManager_doGetNciVersion},
doEnableDtaMode()2836 {"doEnableDtaMode", "()V", (void*)nfcManager_doEnableDtaMode},
doDisableDtaMode()2837 {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode},
doFactoryReset()2838 {"doFactoryReset", "()V", (void*)nfcManager_doFactoryReset},
doShutdown()2839 {"doShutdown", "()V", (void*)nfcManager_doShutdown},
2840
getIsoDepMaxTransceiveLength()2841 {"getIsoDepMaxTransceiveLength", "()I",
2842 (void*)nfcManager_getIsoDepMaxTransceiveLength},
2843
getAidTableSize()2844 {"getAidTableSize", "()I", (void*)nfcManager_getAidTableSize},
2845
doSetNfcSecure(Z)2846 {"doSetNfcSecure", "(Z)Z", (void*)nfcManager_doSetNfcSecure},
2847
doSetNfceePowerAndLinkCtrl(Z)2848 {"doSetNfceePowerAndLinkCtrl", "(Z)V",
2849 (void*)nfcManager_doSetNfceePowerAndLinkCtrl},
2850
doSetPowerSavingMode(Z)2851 {"doSetPowerSavingMode", "(Z)Z", (void*)nfcManager_doSetPowerSavingMode},
2852
getRoutingTable()2853 {"getRoutingTable", "()[B", (void*)nfcManager_doGetRoutingTable},
2854
getMaxRoutingTableSize()2855 {"getMaxRoutingTableSize", "()I",
2856 (void*)nfcManager_doGetMaxRoutingTableSize},
2857
setObserveMode(Z)2858 {"setObserveMode", "(Z)Z", (void*)nfcManager_setObserveMode},
2859
isObserveModeEnabled()2860 {"isObserveModeEnabled", "()Z", (void*)nfcManager_isObserveModeEnabled},
2861
isMultiTag()2862 {"isMultiTag", "()Z", (void*)nfcManager_isMultiTag},
2863
clearRoutingEntry(I)2864 {"clearRoutingEntry", "(I)V", (void*)nfcManager_clearRoutingEntry},
2865
setIsoDepProtocolRoute(I)2866 {"setIsoDepProtocolRoute", "(I)V",
2867 (void*)nfcManager_updateIsoDepProtocolRoute},
2868
setTechnologyABFRoute(II)2869 {"setTechnologyABFRoute", "(II)V",
2870 (void*)nfcManager_updateTechnologyABFRoute},
2871
setSystemCodeRoute(I)2872 {"setSystemCodeRoute", "(I)V", (void*)nfcManager_updateSystemCodeRoute},
2873
setDiscoveryTech(II)2874 {"setDiscoveryTech", "(II)V", (void*)nfcManager_setDiscoveryTech},
2875
resetDiscoveryTech()2876 {"resetDiscoveryTech", "()V", (void*)nfcManager_resetDiscoveryTech},
nativeSendRawVendorCmd(III[B)2877 {"nativeSendRawVendorCmd", "(III[B)Lcom/android/nfc/NfcVendorNciResponse;",
2878 (void*)nfcManager_nativeSendRawVendorCmd},
2879
dofetchActiveNfceeList()2880 {"dofetchActiveNfceeList", "()Ljava/util/Map;",
2881 (void*)nfcManager_dofetchActiveNfceeList},
2882
getProprietaryCaps()2883 {"getProprietaryCaps", "()[B", (void*)nfcManager_getProprietaryCaps},
enableVendorNciNotifications(Z)2884 {"enableVendorNciNotifications", "(Z)V",
2885 (void*)ncfManager_nativeEnableVendorNciNotifications},
injectNtf([B)2886 {"injectNtf", "([B)V", (void*)nfcManager_injectNtf},
doDetectEpRemoval(I)2887 {"doDetectEpRemoval", "(I)Z", (void*)nfcManager_doDetectEpRemoval},
isRemovalDetectionInPollModeSupported()2888 {"isRemovalDetectionInPollModeSupported", "()Z",
2889 (void*)nfcManager_isRemovalDetectionSupported},
setFirmwareExitFrameTable([Lcom/android/nfc/ExitFrame;[B)2890 {"setFirmwareExitFrameTable", "([Lcom/android/nfc/ExitFrame;[B)Z",
2891 (void*)nfcManager_setFirmwareExitFrameTable},
doRestartRfDiscovery()2892 {"doRestartRfDiscovery", "()V", (void*)nfcManager_restartRfDiscovery},
2893 };
2894
2895 /*******************************************************************************
2896 **
2897 ** Function: register_com_android_nfc_NativeNfcManager
2898 **
2899 ** Description: Regisgter JNI functions with Java Virtual Machine.
2900 ** e: Environment of JVM.
2901 **
2902 ** Returns: Status of registration.
2903 **
2904 *******************************************************************************/
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2905 int register_com_android_nfc_NativeNfcManager(JNIEnv* e) {
2906 return jniRegisterNativeMethods(e, gNativeNfcManagerClassName, gMethods,
2907 NELEM(gMethods));
2908 }
2909
2910 /*******************************************************************************
2911 **
2912 ** Function: startRfDiscovery
2913 **
2914 ** Description: Ask stack to start polling and listening for devices.
2915 ** isStart: Whether to start.
2916 **
2917 ** Returns: None
2918 **
2919 *******************************************************************************/
startRfDiscovery(bool isStart)2920 void startRfDiscovery(bool isStart) {
2921 tNFA_STATUS status = NFA_STATUS_FAILED;
2922
2923 LOG(DEBUG) << StringPrintf("%s: is start=%d", __func__, isStart);
2924 nativeNfcTag_acquireRfInterfaceMutexLock();
2925 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
2926 status = isStart ? NFA_StartRfDiscovery() : NFA_StopRfDiscovery();
2927 if (status == NFA_STATUS_OK) {
2928 sNfaEnableDisablePollingEvent.wait(); // wait for NFA_RF_DISCOVERY_xxxx_EVT
2929 sRfEnabled = isStart;
2930 } else {
2931 LOG(ERROR) << StringPrintf(
2932 "%s: Failed to start/stop RF discovery; error=0x%X", __func__, status);
2933 }
2934 nativeNfcTag_releaseRfInterfaceMutexLock();
2935 }
2936
2937 /*******************************************************************************
2938 **
2939 ** Function: isDiscoveryStarted
2940 **
2941 ** Description: Indicates whether the discovery is started.
2942 **
2943 ** Returns: True if discovery is started
2944 **
2945 *******************************************************************************/
isDiscoveryStarted()2946 bool isDiscoveryStarted() { return sRfEnabled; }
2947
2948 /*******************************************************************************
2949 **
2950 ** Function: doStartupConfig
2951 **
2952 ** Description: Configure the NFC controller.
2953 **
2954 ** Returns: None
2955 **
2956 *******************************************************************************/
doStartupConfig()2957 void doStartupConfig() {
2958 // configure RF polling frequency for each technology
2959 static tNFA_DM_DISC_FREQ_CFG nfa_dm_disc_freq_cfg;
2960 // values in the polling_frequency[] map to members of nfa_dm_disc_freq_cfg
2961 std::vector<uint8_t> polling_frequency;
2962 if (NfcConfig::hasKey(NAME_POLL_FREQUENCY))
2963 polling_frequency = NfcConfig::getBytes(NAME_POLL_FREQUENCY);
2964 if (polling_frequency.size() == 8) {
2965 LOG(DEBUG) << StringPrintf("%s: polling frequency", __func__);
2966 memset(&nfa_dm_disc_freq_cfg, 0, sizeof(nfa_dm_disc_freq_cfg));
2967 nfa_dm_disc_freq_cfg.pa = polling_frequency[0];
2968 nfa_dm_disc_freq_cfg.pb = polling_frequency[1];
2969 nfa_dm_disc_freq_cfg.pf = polling_frequency[2];
2970 nfa_dm_disc_freq_cfg.pi93 = polling_frequency[3];
2971 nfa_dm_disc_freq_cfg.pbp = polling_frequency[4];
2972 nfa_dm_disc_freq_cfg.pk = polling_frequency[5];
2973 nfa_dm_disc_freq_cfg.paa = polling_frequency[6];
2974 nfa_dm_disc_freq_cfg.pfa = polling_frequency[7];
2975 p_nfa_dm_rf_disc_freq_cfg = &nfa_dm_disc_freq_cfg;
2976 }
2977
2978 // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
2979 nfcManager_configNfccConfigControl(true);
2980
2981 }
2982
2983 /*******************************************************************************
2984 **
2985 ** Function: nfcManager_isNfcActive
2986 **
2987 ** Description: Used externaly to determine if NFC is active or not.
2988 **
2989 ** Returns: 'true' if the NFC stack is running, else 'false'.
2990 **
2991 *******************************************************************************/
nfcManager_isNfcActive()2992 bool nfcManager_isNfcActive() { return sIsNfaEnabled; }
2993
2994 /*******************************************************************************
2995 **
2996 ** Function: startStopPolling
2997 **
2998 ** Description: Start or stop polling.
2999 ** isStartPolling: true to start polling; false to stop
3000 *polling.
3001 **
3002 ** Returns: None.
3003 **
3004 *******************************************************************************/
startStopPolling(bool isStartPolling)3005 void startStopPolling(bool isStartPolling) {
3006 tNFA_STATUS status = NFA_STATUS_FAILED;
3007 uint8_t discovry_param = 0;
3008 LOG(DEBUG) << StringPrintf("%s: enter; isStart=%u", __func__, isStartPolling);
3009
3010 if (NFC_GetNCIVersion() >= NCI_VERSION_2_0) {
3011 SyncEventGuard guard(gNfaSetConfigEvent);
3012 if (isStartPolling) {
3013 discovry_param =
3014 NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
3015 } else {
3016 discovry_param =
3017 NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_DISABLE_MASK;
3018 }
3019 status = NFA_SetConfig(NCI_PARAM_ID_CON_DISCOVERY_PARAM,
3020 NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param);
3021 if (status == NFA_STATUS_OK) {
3022 gNfaSetConfigEvent.wait();
3023 } else {
3024 LOG(ERROR) << StringPrintf("%s: Failed to update CON_DISCOVER_PARAM",
3025 __FUNCTION__);
3026 }
3027 } else {
3028 startRfDiscovery(false);
3029 if (isStartPolling)
3030 startPolling_rfDiscoveryDisabled(0);
3031 else
3032 stopPolling_rfDiscoveryDisabled();
3033 startRfDiscovery(true);
3034 }
3035 LOG(DEBUG) << StringPrintf("%s: exit", __func__);
3036 }
3037
startPolling_rfDiscoveryDisabled(tNFA_TECHNOLOGY_MASK tech_mask)3038 static tNFA_STATUS startPolling_rfDiscoveryDisabled(
3039 tNFA_TECHNOLOGY_MASK tech_mask) {
3040 tNFA_STATUS stat = NFA_STATUS_FAILED;
3041
3042 if (tech_mask == 0)
3043 tech_mask =
3044 NfcConfig::getUnsigned(NAME_POLLING_TECH_MASK, DEFAULT_TECH_MASK);
3045
3046 nativeNfcTag_acquireRfInterfaceMutexLock();
3047 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
3048 LOG(DEBUG) << StringPrintf("%s: enable polling", __func__);
3049 stat = NFA_EnablePolling(tech_mask);
3050 if (stat == NFA_STATUS_OK) {
3051 LOG(DEBUG) << StringPrintf("%s: wait for enable event", __func__);
3052 sPollingEnabled = true;
3053 sNfaEnableDisablePollingEvent.wait(); // wait for NFA_POLL_ENABLED_EVT
3054 } else {
3055 LOG(ERROR) << StringPrintf("%s: fail enable polling; error=0x%X", __func__,
3056 stat);
3057 }
3058 nativeNfcTag_releaseRfInterfaceMutexLock();
3059
3060 return stat;
3061 }
3062
stopPolling_rfDiscoveryDisabled()3063 static tNFA_STATUS stopPolling_rfDiscoveryDisabled() {
3064 tNFA_STATUS stat = NFA_STATUS_FAILED;
3065
3066 nativeNfcTag_acquireRfInterfaceMutexLock();
3067 SyncEventGuard guard(sNfaEnableDisablePollingEvent);
3068 LOG(DEBUG) << StringPrintf("%s: disable polling", __func__);
3069 stat = NFA_DisablePolling();
3070 if (stat == NFA_STATUS_OK) {
3071 sPollingEnabled = false;
3072 sNfaEnableDisablePollingEvent.wait(); // wait for NFA_POLL_DISABLED_EVT
3073 } else {
3074 LOG(ERROR) << StringPrintf("%s: fail disable polling; error=0x%X", __func__,
3075 stat);
3076 }
3077 nativeNfcTag_releaseRfInterfaceMutexLock();
3078
3079 return stat;
3080 }
3081
nfcManager_doSetPowerSavingMode(JNIEnv * e,jobject o,bool flag)3082 static jboolean nfcManager_doSetPowerSavingMode(JNIEnv* e, jobject o,
3083 bool flag) {
3084 if (sIsShuttingDown) return false;
3085 LOG(DEBUG) << StringPrintf("%s: enter; ", __func__);
3086 uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP,
3087 NCI_MSG_PROP_ANDROID, NCI_ANDROID_POWER_SAVING_PARAM_SIZE,
3088 NCI_ANDROID_POWER_SAVING,
3089 NCI_ANDROID_POWER_SAVING_PARAM_DISABLE};
3090 cmd[4] = flag ? NCI_ANDROID_POWER_SAVING_PARAM_ENABLE
3091 : NCI_ANDROID_POWER_SAVING_PARAM_DISABLE;
3092
3093 SyncEventGuard guard(gNfaVsCommand);
3094 tNFA_STATUS status =
3095 NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaSendRawVsCmdCallback);
3096 if (status == NFA_STATUS_OK) {
3097 gNfaVsCommand.wait();
3098 } else {
3099 LOG(ERROR) << StringPrintf("%s: Failed to set power-saving mode", __func__);
3100 gVSCmdStatus = NFA_STATUS_FAILED;
3101 }
3102 return gVSCmdStatus == NFA_STATUS_OK;
3103 }
3104
nfcManager_getProprietaryCaps(JNIEnv * e,jobject o)3105 static jbyteArray nfcManager_getProprietaryCaps(JNIEnv* e, jobject o) {
3106 if (sIsShuttingDown) return nullptr;
3107 LOG(DEBUG) << StringPrintf("%s: enter; ", __func__);
3108 uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP,
3109 NCI_MSG_PROP_ANDROID, NCI_ANDROID_GET_CAPS_PARAM_SIZE,
3110 NCI_ANDROID_GET_CAPS};
3111 SyncEventGuard guard(gNfaVsCommand);
3112
3113 tNFA_STATUS status = NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaVSCallback);
3114 if (status == NFA_STATUS_OK) {
3115 if (!gNfaVsCommand.wait(1000)) {
3116 LOG(ERROR) << StringPrintf(
3117 "%s: Timed out waiting for a response to get caps ",
3118 __FUNCTION__);
3119 gVSCmdStatus = NFA_STATUS_FAILED;
3120 }
3121 } else {
3122 LOG(ERROR) << StringPrintf("%s: Failed to get caps", __func__);
3123 gVSCmdStatus = NFA_STATUS_FAILED;
3124 }
3125 CHECK(e);
3126 jbyteArray rtJavaArray = e->NewByteArray(gCaps.size());
3127 CHECK(rtJavaArray);
3128 e->SetByteArrayRegion(rtJavaArray, 0, gCaps.size(), (jbyte*)gCaps.data());
3129 return rtJavaArray;
3130 }
3131
nfcManager_setFirmwareExitFrameTable(JNIEnv * env,jobject o,jobjectArray exit_frames,jbyteArray timeout)3132 static jboolean nfcManager_setFirmwareExitFrameTable(JNIEnv* env, jobject o,
3133 jobjectArray exit_frames,
3134 jbyteArray timeout) {
3135 if (sIsShuttingDown) return false;
3136 LOG(DEBUG) << __func__ << ": Setting firmware exit frame table";
3137 std::vector<uint8_t> command;
3138 command.push_back(NCI_ANDROID_SET_PASSIVE_OBSERVER_EXIT_FRAME);
3139
3140 // TODO(b/380455428)
3141 // Support more than 5 exit frames if firmware allows it. If we do so, might need to send second
3142 // NCI command if one is too large.
3143 uint8_t more = 0x00;
3144 command.push_back(more);
3145
3146 uint8_t timeout_len = env->GetArrayLength(timeout);
3147 auto* timeout_arr = (uint8_t*)env->GetByteArrayElements(timeout, nullptr);
3148
3149 for (int i = 0; i < timeout_len; ++i) {
3150 command.push_back(timeout_arr[i]);
3151 }
3152 env->ReleaseByteArrayElements(timeout, (jbyte*)timeout_arr, JNI_ABORT);
3153
3154 uint8_t num_exit_frames = env->GetArrayLength(exit_frames);
3155 if (num_exit_frames > 5) {
3156 LOG(INFO)
3157 << "Truncating exit frame table to 5 frames so it fits in a single NCI command. "
3158 << "Original size was " << num_exit_frames;
3159 num_exit_frames = 5;
3160 }
3161 command.push_back(num_exit_frames);
3162
3163 if (num_exit_frames > 0) {
3164 jobject exit_frame = env->GetObjectArrayElement(exit_frames, 0);
3165 jclass clazz = env->GetObjectClass(exit_frame);
3166 jmethodID is_prefix_allowed =
3167 env->GetMethodID(clazz, "isPrefixMatchingAllowed", "()Z");
3168 jmethodID get_data = env->GetMethodID(clazz, "getData", "()[B");
3169 jmethodID get_data_mask = env->GetMethodID(clazz, "getDataMask", "()[B");
3170 jmethodID get_tech = env->GetMethodID(clazz, "getNfcTech", "()I");
3171 jmethodID get_power_state = env->GetMethodID(clazz, "getPowerState", "()I");
3172
3173 for (int i = 0; i < num_exit_frames; ++i) {
3174 jobject frame = env->GetObjectArrayElement(exit_frames, i);
3175
3176 uint8_t qualifier_type = 0x00;
3177 if (env->CallBooleanMethod(frame, is_prefix_allowed)) {
3178 qualifier_type |= 0b00010000;
3179 }
3180 qualifier_type |= env->CallIntMethod(frame, get_tech);
3181 command.push_back(qualifier_type);
3182
3183 uint8_t power_state = env->CallIntMethod(frame, get_power_state);
3184
3185 jbyteArray data = (jbyteArray)env->CallObjectMethod(frame, get_data);
3186 uint8_t data_len = env->GetArrayLength(data);
3187 auto* data_arr = (uint8_t*)env->GetByteArrayElements(data, nullptr);
3188
3189 jbyteArray data_mask =
3190 (jbyteArray)env->CallObjectMethod(frame, get_data_mask);
3191 uint8_t data_mask_len = env->GetArrayLength(data_mask);
3192 auto* data_mask_arr =
3193 (uint8_t*)env->GetByteArrayElements(data_mask, nullptr);
3194
3195 uint8_t value_len = 1 + data_len + data_mask_len;
3196
3197 command.push_back(value_len);
3198 command.push_back(power_state);
3199
3200 for (int j = 0; j < data_len; ++j) {
3201 command.push_back(data_arr[j]);
3202 }
3203 for (int j = 0; j < data_mask_len; ++j) {
3204 command.push_back(data_mask_arr[j]);
3205 }
3206 env->ReleaseByteArrayElements(data, (jbyte*)data_arr, JNI_ABORT);
3207 env->ReleaseByteArrayElements(data_mask, (jbyte*)data_mask_arr,
3208 JNI_ABORT);
3209 }
3210 }
3211
3212 bool reenableDiscovery = false;
3213 if (sRfEnabled) {
3214 startRfDiscovery(false);
3215 reenableDiscovery = true;
3216 }
3217
3218 // TODO make helper to send single command and wait on response
3219 {
3220 SyncEventGuard guard(gNfaVsCommand);
3221 tNFA_STATUS status = NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, command.size(),
3222 command.data(), nfaVSCallback);
3223
3224 if (status == NFA_STATUS_OK) {
3225 if (!gNfaVsCommand.wait(1000)) {
3226 LOG(ERROR) << StringPrintf(
3227 "%s: Timed out waiting for a response to set exit frame table ",
3228 __FUNCTION__);
3229 gVSCmdStatus = NFA_STATUS_FAILED;
3230 }
3231 } else {
3232 LOG(DEBUG) << StringPrintf("%s: Failed to set exit frame table",
3233 __FUNCTION__);
3234 gVSCmdStatus = NFA_STATUS_FAILED;
3235 }
3236 }
3237
3238 if (reenableDiscovery) {
3239 startRfDiscovery(true);
3240 }
3241
3242 return gVSCmdStatus == NFA_STATUS_OK;
3243 }
3244
3245 /*******************************************************************************
3246 **
3247 ** Function: nfcManager_restartRfDiscovery
3248 ** Description: Restarts RF discovery
3249 **
3250 ** e: JVM environment.
3251 ** o: Java object.
3252 **
3253 *******************************************************************************/
nfcManager_restartRfDiscovery(JNIEnv *,jobject)3254 static void nfcManager_restartRfDiscovery(JNIEnv*, jobject) {
3255 if (sIsShuttingDown) return;
3256 if (sRfEnabled) {
3257 android::startRfDiscovery(false);
3258 }
3259 android::startRfDiscovery(true);
3260 }
3261
3262 } /* namespace android */
3263