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