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