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