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