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