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