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 <semaphore.h>
18 #include <errno.h>
19 #include "OverrideLog.h"
20 #include "NfcJniUtil.h"
21 #include "NfcAdaptation.h"
22 #include "SyncEvent.h"
23 #include "PeerToPeer.h"
24 #include "SecureElement.h"
25 #include "NfcTag.h"
26 #include "config.h"
27 #include "PowerSwitch.h"
28 #include "JavaClassConstants.h"
29 #include "Pn544Interop.h"
30 #include <ScopedLocalRef.h>
31 #include <ScopedUtfChars.h>
32
33 extern "C"
34 {
35 #include "nfa_api.h"
36 #include "nfa_p2p_api.h"
37 #include "rw_api.h"
38 #include "nfa_ee_api.h"
39 #include "nfc_brcm_defs.h"
40 #include "ce_api.h"
41 }
42
43 extern UINT8 *p_nfa_dm_start_up_cfg;
44 extern const UINT8 nfca_version_string [];
45 namespace android
46 {
47 extern bool gIsTagDeactivating;
48 extern bool gIsSelectingRfInterface;
49 extern void nativeNfcTag_doTransceiveStatus (uint8_t * buf, uint32_t buflen);
50 extern void nativeNfcTag_doConnectStatus (jboolean is_connect_ok);
51 extern void nativeNfcTag_doDeactivateStatus (int status);
52 extern void nativeNfcTag_doWriteStatus (jboolean is_write_ok);
53 extern void nativeNfcTag_doCheckNdefResult (tNFA_STATUS status, uint32_t max_size, uint32_t current_size, uint8_t flags);
54 extern void nativeNfcTag_doMakeReadonlyResult (tNFA_STATUS status);
55 extern void nativeNfcTag_doPresenceCheckResult (tNFA_STATUS status);
56 extern void nativeNfcTag_formatStatus (bool is_ok);
57 extern void nativeNfcTag_resetPresenceCheck ();
58 extern void nativeNfcTag_doReadCompleted (tNFA_STATUS status);
59 extern void nativeNfcTag_abortWaits ();
60 extern void nativeLlcpConnectionlessSocket_abortWait ();
61 extern void nativeNfcTag_registerNdefTypeHandler ();
62 extern void nativeLlcpConnectionlessSocket_receiveData (uint8_t* data, uint32_t len, uint32_t remote_sap);
63 }
64
65
66 /*****************************************************************************
67 **
68 ** public variables and functions
69 **
70 *****************************************************************************/
71
72 namespace android
73 {
74 int gGeneralTransceiveTimeout = 1000;
75 jmethodID gCachedNfcManagerNotifyNdefMessageListeners;
76 jmethodID gCachedNfcManagerNotifyTransactionListeners;
77 jmethodID gCachedNfcManagerNotifyLlcpLinkActivation;
78 jmethodID gCachedNfcManagerNotifyLlcpLinkDeactivated;
79 jmethodID gCachedNfcManagerNotifyLlcpFirstPacketReceived;
80 jmethodID gCachedNfcManagerNotifySeFieldActivated;
81 jmethodID gCachedNfcManagerNotifySeFieldDeactivated;
82 jmethodID gCachedNfcManagerNotifySeListenActivated;
83 jmethodID gCachedNfcManagerNotifySeListenDeactivated;
84 const char* gNativeP2pDeviceClassName = "com/android/nfc/dhimpl/NativeP2pDevice";
85 const char* gNativeLlcpServiceSocketClassName = "com/android/nfc/dhimpl/NativeLlcpServiceSocket";
86 const char* gNativeLlcpConnectionlessSocketClassName = "com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket";
87 const char* gNativeLlcpSocketClassName = "com/android/nfc/dhimpl/NativeLlcpSocket";
88 const char* gNativeNfcTagClassName = "com/android/nfc/dhimpl/NativeNfcTag";
89 const char* gNativeNfcManagerClassName = "com/android/nfc/dhimpl/NativeNfcManager";
90 const char* gNativeNfcSecureElementClassName = "com/android/nfc/dhimpl/NativeNfcSecureElement";
91 void doStartupConfig ();
92 void startStopPolling (bool isStartPolling);
93 void startRfDiscovery (bool isStart);
94 void setUiccIdleTimeout (bool enable);
95 }
96
97
98 /*****************************************************************************
99 **
100 ** private variables and functions
101 **
102 *****************************************************************************/
103 namespace android
104 {
105 static jint sLastError = ERROR_BUFFER_TOO_SMALL;
106 static jmethodID sCachedNfcManagerNotifySeApduReceived;
107 static jmethodID sCachedNfcManagerNotifySeMifareAccess;
108 static jmethodID sCachedNfcManagerNotifySeEmvCardRemoval;
109 static jmethodID sCachedNfcManagerNotifyTargetDeselected;
110 static SyncEvent sNfaEnableEvent; //event for NFA_Enable()
111 static SyncEvent sNfaDisableEvent; //event for NFA_Disable()
112 static SyncEvent sNfaEnableDisablePollingEvent; //event for NFA_EnablePolling(), NFA_DisablePolling()
113 static SyncEvent sNfaSetConfigEvent; // event for Set_Config....
114 static SyncEvent sNfaGetConfigEvent; // event for Get_Config....
115 static bool sIsNfaEnabled = false;
116 static bool sDiscoveryEnabled = false; //is polling for tag?
117 static bool sIsDisabling = false;
118 static bool sRfEnabled = false; // whether RF discovery is enabled
119 static bool sSeRfActive = false; // whether RF with SE is likely active
120 static bool sP2pActive = false; // whether p2p was last active
121 static bool sAbortConnlessWait = false;
122 static bool sIsSecElemSelected = false; //has NFC service selected a sec elem
123 #define CONFIG_UPDATE_TECH_MASK (1 << 1)
124 #define DEFAULT_TECH_MASK (NFA_TECHNOLOGY_MASK_A \
125 | NFA_TECHNOLOGY_MASK_B \
126 | NFA_TECHNOLOGY_MASK_F \
127 | NFA_TECHNOLOGY_MASK_ISO15693 \
128 | NFA_TECHNOLOGY_MASK_B_PRIME \
129 | NFA_TECHNOLOGY_MASK_A_ACTIVE \
130 | NFA_TECHNOLOGY_MASK_F_ACTIVE \
131 | NFA_TECHNOLOGY_MASK_KOVIO)
132
133
134 static void nfaConnectionCallback (UINT8 event, tNFA_CONN_EVT_DATA *eventData);
135 static void nfaDeviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA *eventData);
136 static bool isPeerToPeer (tNFA_ACTIVATED& activated);
137 static bool isListenMode(tNFA_ACTIVATED& activated);
138
139 static UINT16 sCurrentConfigLen;
140 static UINT8 sConfig[256];
141 /////////////////////////////////////////////////////////////
142 /////////////////////////////////////////////////////////////
143
144
145 /*******************************************************************************
146 **
147 ** Function: getNative
148 **
149 ** Description: Get native data
150 **
151 ** Returns: Native data structure.
152 **
153 *******************************************************************************/
getNative(JNIEnv * e,jobject o)154 nfc_jni_native_data *getNative (JNIEnv* e, jobject o)
155 {
156 static struct nfc_jni_native_data *sCachedNat = NULL;
157 if (e)
158 {
159 sCachedNat = nfc_jni_get_nat(e, o);
160 }
161 return sCachedNat;
162 }
163
164
165 /*******************************************************************************
166 **
167 ** Function: handleRfDiscoveryEvent
168 **
169 ** Description: Handle RF-discovery events from the stack.
170 ** discoveredDevice: Discovered device.
171 **
172 ** Returns: None
173 **
174 *******************************************************************************/
handleRfDiscoveryEvent(tNFC_RESULT_DEVT * discoveredDevice)175 static void handleRfDiscoveryEvent (tNFC_RESULT_DEVT* discoveredDevice)
176 {
177 if (discoveredDevice->more)
178 {
179 //there is more discovery notification coming
180 return;
181 }
182
183 bool isP2p = NfcTag::getInstance ().isP2pDiscovered ();
184 if (isP2p)
185 {
186 //select the peer that supports P2P
187 NfcTag::getInstance ().selectP2p();
188 }
189 else
190 {
191 //select the first of multiple tags that is discovered
192 NfcTag::getInstance ().selectFirstTag();
193 }
194 }
195
196
197 /*******************************************************************************
198 **
199 ** Function: nfaConnectionCallback
200 **
201 ** Description: Receive connection-related events from stack.
202 ** connEvent: Event code.
203 ** eventData: Event data.
204 **
205 ** Returns: None
206 **
207 *******************************************************************************/
nfaConnectionCallback(UINT8 connEvent,tNFA_CONN_EVT_DATA * eventData)208 static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventData)
209 {
210 tNFA_STATUS status = NFA_STATUS_FAILED;
211 ALOGD("%s: event= %u", __FUNCTION__, connEvent);
212
213 // TODO this if can probably be completely removed. It's unclear why this
214 // was present in the initial code drop - either to work around NFCC,
215 // stack or certain NFC tags bugs. Until we verify removing it doesn't
216 // break things, leave it be.
217 if (gIsTagDeactivating && connEvent != NFA_DEACTIVATED_EVT &&
218 connEvent != NFA_PRESENCE_CHECK_EVT && connEvent != NFA_DATA_EVT &&
219 connEvent != NFA_RW_INTF_ERROR_EVT)
220 {
221 // special case to switching frame interface for ISO_DEP tags
222 gIsTagDeactivating = false;
223 ALOGD("%s: deactivating, should get NFA_DEACTIVATED_EVT", __FUNCTION__);
224 nativeNfcTag_doDeactivateStatus(1);
225 }
226
227 switch (connEvent)
228 {
229 case NFA_POLL_ENABLED_EVT: // whether polling successfully started
230 {
231 ALOGD("%s: NFA_POLL_ENABLED_EVT: status = %u", __FUNCTION__, eventData->status);
232
233 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
234 sNfaEnableDisablePollingEvent.notifyOne ();
235 }
236 break;
237
238 case NFA_POLL_DISABLED_EVT: // Listening/Polling stopped
239 {
240 ALOGD("%s: NFA_POLL_DISABLED_EVT: status = %u", __FUNCTION__, eventData->status);
241
242 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
243 sNfaEnableDisablePollingEvent.notifyOne ();
244 }
245 break;
246
247 case NFA_RF_DISCOVERY_STARTED_EVT: // RF Discovery started
248 {
249 ALOGD("%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u", __FUNCTION__, eventData->status);
250
251 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
252 sNfaEnableDisablePollingEvent.notifyOne ();
253 }
254 break;
255
256 case NFA_RF_DISCOVERY_STOPPED_EVT: // RF Discovery stopped event
257 {
258 ALOGD("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u", __FUNCTION__, eventData->status);
259
260 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
261 sNfaEnableDisablePollingEvent.notifyOne ();
262 }
263 break;
264
265 case NFA_DISC_RESULT_EVT: // NFC link/protocol discovery notificaiton
266 status = eventData->disc_result.status;
267 ALOGD("%s: NFA_DISC_RESULT_EVT: status = %d", __FUNCTION__, status);
268 if (status != NFA_STATUS_OK)
269 {
270 ALOGE("%s: NFA_DISC_RESULT_EVT error: status = %d", __FUNCTION__, status);
271 }
272 else
273 {
274 NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
275 handleRfDiscoveryEvent(&eventData->disc_result.discovery_ntf);
276 }
277 break;
278
279 case NFA_SELECT_RESULT_EVT: // NFC link/protocol discovery select response
280 ALOGD("%s: NFA_SELECT_RESULT_EVT: status = %d, gIsSelectingRfInterface = %d, sIsDisabling=%d", __FUNCTION__, eventData->status, gIsSelectingRfInterface, sIsDisabling);
281
282 if (sIsDisabling)
283 break;
284
285 if (eventData->status != NFA_STATUS_OK)
286 {
287 if (gIsSelectingRfInterface)
288 {
289 nativeNfcTag_doConnectStatus(false);
290 }
291
292 ALOGE("%s: NFA_SELECT_RESULT_EVT error: status = %d", __FUNCTION__, eventData->status);
293 NFA_Deactivate (FALSE);
294 }
295 break;
296
297 case NFA_DEACTIVATE_FAIL_EVT:
298 ALOGD("%s: NFA_DEACTIVATE_FAIL_EVT: status = %d", __FUNCTION__, eventData->status);
299 break;
300
301 case NFA_ACTIVATED_EVT: // NFC link/protocol activated
302 ALOGD("%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d", __FUNCTION__, gIsSelectingRfInterface, sIsDisabling);
303 if (sIsDisabling || !sIsNfaEnabled)
304 break;
305
306 NfcTag::getInstance().setActivationState ();
307 if (gIsSelectingRfInterface)
308 {
309 nativeNfcTag_doConnectStatus(true);
310 break;
311 }
312
313 nativeNfcTag_resetPresenceCheck();
314 if (isPeerToPeer(eventData->activated))
315 {
316 sP2pActive = true;
317 ALOGD("%s: NFA_ACTIVATED_EVT; is p2p", __FUNCTION__);
318 // Disable RF field events in case of p2p
319 UINT8 nfa_disable_rf_events[] = { 0x00 };
320 ALOGD ("%s: Disabling RF field events", __FUNCTION__);
321 status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_disable_rf_events),
322 &nfa_disable_rf_events[0]);
323 if (status == NFA_STATUS_OK) {
324 ALOGD ("%s: Disabled RF field events", __FUNCTION__);
325 } else {
326 ALOGE ("%s: Failed to disable RF field events", __FUNCTION__);
327 }
328 // For the SE, consider the field to be on while p2p is active.
329 SecureElement::getInstance().notifyRfFieldEvent (true);
330 }
331 else if (pn544InteropIsBusy() == false)
332 {
333 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
334
335 // We know it is not activating for P2P. If it activated in
336 // listen mode then it is likely for an SE transaction.
337 // Send the RF Event.
338 if (isListenMode(eventData->activated))
339 {
340 sSeRfActive = true;
341 SecureElement::getInstance().notifyListenModeState (true);
342 }
343 }
344
345 break;
346
347 case NFA_DEACTIVATED_EVT: // NFC link/protocol deactivated
348 ALOGD("%s: NFA_DEACTIVATED_EVT Type: %u, gIsTagDeactivating: %d", __FUNCTION__, eventData->deactivated.type,gIsTagDeactivating);
349 NfcTag::getInstance().setDeactivationState (eventData->deactivated);
350 if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP)
351 {
352 nativeNfcTag_resetPresenceCheck();
353 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
354 nativeNfcTag_abortWaits();
355 NfcTag::getInstance().abort ();
356 }
357 else if (gIsTagDeactivating)
358 {
359 nativeNfcTag_doDeactivateStatus(0);
360 }
361
362 // If RF is activated for what we think is a Secure Element transaction
363 // and it is deactivated to either IDLE or DISCOVERY mode, notify w/event.
364 if ((eventData->deactivated.type == NFA_DEACTIVATE_TYPE_IDLE)
365 || (eventData->deactivated.type == NFA_DEACTIVATE_TYPE_DISCOVERY))
366 {
367 if (sSeRfActive) {
368 sSeRfActive = false;
369 if (!sIsDisabling && sIsNfaEnabled)
370 SecureElement::getInstance().notifyListenModeState (false);
371 } else if (sP2pActive) {
372 sP2pActive = false;
373 // Make sure RF field events are re-enabled
374 ALOGD("%s: NFA_DEACTIVATED_EVT; is p2p", __FUNCTION__);
375 // Disable RF field events in case of p2p
376 UINT8 nfa_enable_rf_events[] = { 0x01 };
377
378 if (!sIsDisabling && sIsNfaEnabled)
379 {
380 ALOGD ("%s: Enabling RF field events", __FUNCTION__);
381 status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_enable_rf_events),
382 &nfa_enable_rf_events[0]);
383 if (status == NFA_STATUS_OK) {
384 ALOGD ("%s: Enabled RF field events", __FUNCTION__);
385 } else {
386 ALOGE ("%s: Failed to enable RF field events", __FUNCTION__);
387 }
388 // Consider the field to be off at this point
389 SecureElement::getInstance().notifyRfFieldEvent (false);
390 }
391 }
392 }
393
394 break;
395
396 case NFA_TLV_DETECT_EVT: // TLV Detection complete
397 status = eventData->tlv_detect.status;
398 ALOGD("%s: NFA_TLV_DETECT_EVT: status = %d, protocol = %d, num_tlvs = %d, num_bytes = %d",
399 __FUNCTION__, status, eventData->tlv_detect.protocol,
400 eventData->tlv_detect.num_tlvs, eventData->tlv_detect.num_bytes);
401 if (status != NFA_STATUS_OK)
402 {
403 ALOGE("%s: NFA_TLV_DETECT_EVT error: status = %d", __FUNCTION__, status);
404 }
405 break;
406
407 case NFA_NDEF_DETECT_EVT: // NDEF Detection complete;
408 //if status is failure, it means the tag does not contain any or valid NDEF data;
409 //pass the failure status to the NFC Service;
410 status = eventData->ndef_detect.status;
411 ALOGD("%s: NFA_NDEF_DETECT_EVT: status = 0x%X, protocol = %u, "
412 "max_size = %lu, cur_size = %lu, flags = 0x%X", __FUNCTION__,
413 status,
414 eventData->ndef_detect.protocol, eventData->ndef_detect.max_size,
415 eventData->ndef_detect.cur_size, eventData->ndef_detect.flags);
416 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
417 nativeNfcTag_doCheckNdefResult(status,
418 eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size,
419 eventData->ndef_detect.flags);
420 break;
421
422 case NFA_DATA_EVT: // Data message received (for non-NDEF reads)
423 ALOGD("%s: NFA_DATA_EVT: len = %d", __FUNCTION__, eventData->data.len);
424 nativeNfcTag_doTransceiveStatus(eventData->data.p_data,eventData->data.len);
425 break;
426
427 case NFA_SELECT_CPLT_EVT: // Select completed
428 status = eventData->status;
429 ALOGD("%s: NFA_SELECT_CPLT_EVT: status = %d", __FUNCTION__, status);
430 if (status != NFA_STATUS_OK)
431 {
432 ALOGE("%s: NFA_SELECT_CPLT_EVT error: status = %d", __FUNCTION__, status);
433 }
434 break;
435
436 case NFA_READ_CPLT_EVT: // NDEF-read or tag-specific-read completed
437 ALOGD("%s: NFA_READ_CPLT_EVT: status = 0x%X", __FUNCTION__, eventData->status);
438 nativeNfcTag_doReadCompleted (eventData->status);
439 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
440 break;
441
442 case NFA_WRITE_CPLT_EVT: // Write completed
443 ALOGD("%s: NFA_WRITE_CPLT_EVT: status = %d", __FUNCTION__, eventData->status);
444 nativeNfcTag_doWriteStatus (eventData->status == NFA_STATUS_OK);
445 break;
446
447 case NFA_SET_TAG_RO_EVT: // Tag set as Read only
448 ALOGD("%s: NFA_SET_TAG_RO_EVT: status = %d", __FUNCTION__, eventData->status);
449 nativeNfcTag_doMakeReadonlyResult(eventData->status);
450 break;
451
452 case NFA_CE_NDEF_WRITE_START_EVT: // NDEF write started
453 ALOGD("%s: NFA_CE_NDEF_WRITE_START_EVT: status: %d", __FUNCTION__, eventData->status);
454
455 if (eventData->status != NFA_STATUS_OK)
456 ALOGE("%s: NFA_CE_NDEF_WRITE_START_EVT error: status = %d", __FUNCTION__, eventData->status);
457 break;
458
459 case NFA_CE_NDEF_WRITE_CPLT_EVT: // NDEF write completed
460 ALOGD("%s: FA_CE_NDEF_WRITE_CPLT_EVT: len = %lu", __FUNCTION__, eventData->ndef_write_cplt.len);
461 break;
462
463 case NFA_LLCP_ACTIVATED_EVT: // LLCP link is activated
464 ALOGD("%s: NFA_LLCP_ACTIVATED_EVT: is_initiator: %d remote_wks: %d, remote_lsc: %d, remote_link_miu: %d, local_link_miu: %d",
465 __FUNCTION__,
466 eventData->llcp_activated.is_initiator,
467 eventData->llcp_activated.remote_wks,
468 eventData->llcp_activated.remote_lsc,
469 eventData->llcp_activated.remote_link_miu,
470 eventData->llcp_activated.local_link_miu);
471
472 PeerToPeer::getInstance().llcpActivatedHandler (getNative(0, 0), eventData->llcp_activated);
473 break;
474
475 case NFA_LLCP_DEACTIVATED_EVT: // LLCP link is deactivated
476 ALOGD("%s: NFA_LLCP_DEACTIVATED_EVT", __FUNCTION__);
477 PeerToPeer::getInstance().llcpDeactivatedHandler (getNative(0, 0), eventData->llcp_deactivated);
478 break;
479 case NFA_LLCP_FIRST_PACKET_RECEIVED_EVT: // Received first packet over llcp
480 ALOGD("%s: NFA_LLCP_FIRST_PACKET_RECEIVED_EVT", __FUNCTION__);
481 PeerToPeer::getInstance().llcpFirstPacketHandler (getNative(0, 0));
482 break;
483 case NFA_PRESENCE_CHECK_EVT:
484 ALOGD("%s: NFA_PRESENCE_CHECK_EVT", __FUNCTION__);
485 nativeNfcTag_doPresenceCheckResult (eventData->status);
486 break;
487 case NFA_FORMAT_CPLT_EVT:
488 ALOGD("%s: NFA_FORMAT_CPLT_EVT: status=0x%X", __FUNCTION__, eventData->status);
489 nativeNfcTag_formatStatus (eventData->status == NFA_STATUS_OK);
490 break;
491
492 case NFA_I93_CMD_CPLT_EVT:
493 ALOGD("%s: NFA_I93_CMD_CPLT_EVT: status=0x%X", __FUNCTION__, eventData->status);
494 break;
495
496 case NFA_CE_UICC_LISTEN_CONFIGURED_EVT :
497 ALOGD("%s: NFA_CE_UICC_LISTEN_CONFIGURED_EVT : status=0x%X", __FUNCTION__, eventData->status);
498 SecureElement::getInstance().connectionEventHandler (connEvent, eventData);
499 break;
500
501 case NFA_SET_P2P_LISTEN_TECH_EVT:
502 ALOGD("%s: NFA_SET_P2P_LISTEN_TECH_EVT", __FUNCTION__);
503 PeerToPeer::getInstance().connectionEventHandler (connEvent, eventData);
504 break;
505
506 default:
507 ALOGE("%s: unknown event ????", __FUNCTION__);
508 break;
509 }
510 }
511
512
513 /*******************************************************************************
514 **
515 ** Function: nfcManager_initNativeStruc
516 **
517 ** Description: Initialize variables.
518 ** e: JVM environment.
519 ** o: Java object.
520 **
521 ** Returns: True if ok.
522 **
523 *******************************************************************************/
nfcManager_initNativeStruc(JNIEnv * e,jobject o)524 static jboolean nfcManager_initNativeStruc (JNIEnv* e, jobject o)
525 {
526 ALOGD ("%s: enter", __FUNCTION__);
527
528 nfc_jni_native_data* nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
529 if (nat == NULL)
530 {
531 ALOGE ("%s: fail allocate native data", __FUNCTION__);
532 return JNI_FALSE;
533 }
534
535 memset (nat, 0, sizeof(*nat));
536 e->GetJavaVM(&(nat->vm));
537 nat->env_version = e->GetVersion();
538 nat->manager = e->NewGlobalRef(o);
539
540 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
541 jfieldID f = e->GetFieldID(cls.get(), "mNative", "I");
542 e->SetIntField(o, f, (jint)nat);
543
544 /* Initialize native cached references */
545 gCachedNfcManagerNotifyNdefMessageListeners = e->GetMethodID(cls.get(),
546 "notifyNdefMessageListeners", "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
547 gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID(cls.get(),
548 "notifyTransactionListeners", "([B)V");
549 gCachedNfcManagerNotifyLlcpLinkActivation = e->GetMethodID(cls.get(),
550 "notifyLlcpLinkActivation", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
551 gCachedNfcManagerNotifyLlcpLinkDeactivated = e->GetMethodID(cls.get(),
552 "notifyLlcpLinkDeactivated", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
553 gCachedNfcManagerNotifyLlcpFirstPacketReceived = e->GetMethodID(cls.get(),
554 "notifyLlcpLinkFirstPacketReceived", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
555 sCachedNfcManagerNotifyTargetDeselected = e->GetMethodID(cls.get(),
556 "notifyTargetDeselected","()V");
557 gCachedNfcManagerNotifySeFieldActivated = e->GetMethodID(cls.get(),
558 "notifySeFieldActivated", "()V");
559 gCachedNfcManagerNotifySeFieldDeactivated = e->GetMethodID(cls.get(),
560 "notifySeFieldDeactivated", "()V");
561 gCachedNfcManagerNotifySeListenActivated = e->GetMethodID(cls.get(),
562 "notifySeListenActivated", "()V");
563 gCachedNfcManagerNotifySeListenDeactivated = e->GetMethodID(cls.get(),
564 "notifySeListenDeactivated", "()V");
565
566 sCachedNfcManagerNotifySeApduReceived = e->GetMethodID(cls.get(),
567 "notifySeApduReceived", "([B)V");
568
569 sCachedNfcManagerNotifySeMifareAccess = e->GetMethodID(cls.get(),
570 "notifySeMifareAccess", "([B)V");
571
572 sCachedNfcManagerNotifySeEmvCardRemoval = e->GetMethodID(cls.get(),
573 "notifySeEmvCardRemoval", "()V");
574
575 if (nfc_jni_cache_object(e, gNativeNfcTagClassName, &(nat->cached_NfcTag)) == -1)
576 {
577 ALOGE ("%s: fail cache NativeNfcTag", __FUNCTION__);
578 return JNI_FALSE;
579 }
580
581 if (nfc_jni_cache_object(e, gNativeP2pDeviceClassName, &(nat->cached_P2pDevice)) == -1)
582 {
583 ALOGE ("%s: fail cache NativeP2pDevice", __FUNCTION__);
584 return JNI_FALSE;
585 }
586
587 ALOGD ("%s: exit", __FUNCTION__);
588 return JNI_TRUE;
589 }
590
591
592 /*******************************************************************************
593 **
594 ** Function: nfaDeviceManagementCallback
595 **
596 ** Description: Receive device management events from stack.
597 ** dmEvent: Device-management event ID.
598 ** eventData: Data associated with event ID.
599 **
600 ** Returns: None
601 **
602 *******************************************************************************/
nfaDeviceManagementCallback(UINT8 dmEvent,tNFA_DM_CBACK_DATA * eventData)603 void nfaDeviceManagementCallback (UINT8 dmEvent, tNFA_DM_CBACK_DATA* eventData)
604 {
605 ALOGD ("%s: enter; event=0x%X", __FUNCTION__, dmEvent);
606
607 switch (dmEvent)
608 {
609 case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
610 {
611 SyncEventGuard guard (sNfaEnableEvent);
612 ALOGD ("%s: NFA_DM_ENABLE_EVT; status=0x%X",
613 __FUNCTION__, eventData->status);
614 sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
615 sIsDisabling = false;
616 sNfaEnableEvent.notifyOne ();
617 }
618 break;
619
620 case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
621 {
622 SyncEventGuard guard (sNfaDisableEvent);
623 ALOGD ("%s: NFA_DM_DISABLE_EVT", __FUNCTION__);
624 sIsNfaEnabled = false;
625 sIsDisabling = false;
626 sNfaDisableEvent.notifyOne ();
627 }
628 break;
629
630 case NFA_DM_SET_CONFIG_EVT: //result of NFA_SetConfig
631 ALOGD ("%s: NFA_DM_SET_CONFIG_EVT", __FUNCTION__);
632 {
633 SyncEventGuard guard (sNfaSetConfigEvent);
634 sNfaSetConfigEvent.notifyOne();
635 }
636 break;
637
638 case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */
639 ALOGD ("%s: NFA_DM_GET_CONFIG_EVT", __FUNCTION__);
640 {
641 SyncEventGuard guard (sNfaGetConfigEvent);
642 if (eventData->status == NFA_STATUS_OK &&
643 eventData->get_config.tlv_size <= sizeof(sConfig))
644 {
645 sCurrentConfigLen = eventData->get_config.tlv_size;
646 memcpy(sConfig, eventData->get_config.param_tlvs, eventData->get_config.tlv_size);
647 }
648 else
649 {
650 ALOGE("%s: NFA_DM_GET_CONFIG failed", __FUNCTION__);
651 sCurrentConfigLen = 0;
652 }
653 sNfaGetConfigEvent.notifyOne();
654 }
655 break;
656
657 case NFA_DM_RF_FIELD_EVT:
658 ALOGD ("%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __FUNCTION__,
659 eventData->rf_field.status, eventData->rf_field.rf_field_status);
660 if (sIsDisabling || !sIsNfaEnabled)
661 break;
662
663 if (!sP2pActive && eventData->rf_field.status == NFA_STATUS_OK)
664 SecureElement::getInstance().notifyRfFieldEvent (
665 eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON);
666 break;
667
668 case NFA_DM_NFCC_TRANSPORT_ERR_EVT:
669 case NFA_DM_NFCC_TIMEOUT_EVT:
670 {
671 if (dmEvent == NFA_DM_NFCC_TIMEOUT_EVT)
672 ALOGD ("%s: NFA_DM_NFCC_TIMEOUT_EVT; abort all outstanding operations", __FUNCTION__);
673 else
674 ALOGD ("%s: NFA_DM_NFCC_TRANSPORT_ERR_EVT; abort all outstanding operations", __FUNCTION__);
675
676 nativeNfcTag_abortWaits();
677 NfcTag::getInstance().abort ();
678 sAbortConnlessWait = true;
679 nativeLlcpConnectionlessSocket_abortWait();
680 {
681 ALOGD ("%s: aborting sNfaEnableDisablePollingEvent", __FUNCTION__);
682 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
683 sNfaEnableDisablePollingEvent.notifyOne();
684 }
685 {
686 ALOGD ("%s: aborting sNfaEnableEvent", __FUNCTION__);
687 SyncEventGuard guard (sNfaEnableEvent);
688 sNfaEnableEvent.notifyOne();
689 }
690 {
691 ALOGD ("%s: aborting sNfaDisableEvent", __FUNCTION__);
692 SyncEventGuard guard (sNfaDisableEvent);
693 sNfaDisableEvent.notifyOne();
694 }
695 sDiscoveryEnabled = false;
696 PowerSwitch::getInstance ().abort ();
697
698 if (!sIsDisabling && sIsNfaEnabled)
699 {
700 NFA_Disable(FALSE);
701 sIsDisabling = true;
702 }
703 else
704 {
705 sIsNfaEnabled = false;
706 sIsDisabling = false;
707 }
708 PowerSwitch::getInstance ().initialize (PowerSwitch::UNKNOWN_LEVEL);
709 ALOGD ("%s: aborted all waiting events", __FUNCTION__);
710 }
711 break;
712
713 case NFA_DM_PWR_MODE_CHANGE_EVT:
714 PowerSwitch::getInstance ().deviceManagementCallback (dmEvent, eventData);
715 break;
716
717 default:
718 ALOGD ("%s: unhandled event", __FUNCTION__);
719 break;
720 }
721 }
722
723
724 /*******************************************************************************
725 **
726 ** Function: nfcManager_doInitialize
727 **
728 ** Description: Turn on NFC.
729 ** e: JVM environment.
730 ** o: Java object.
731 **
732 ** Returns: True if ok.
733 **
734 *******************************************************************************/
nfcManager_doInitialize(JNIEnv * e,jobject o)735 static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o)
736 {
737 ALOGD ("%s: enter; NCI_VERSION=0x%02X", __FUNCTION__, NCI_VERSION);
738 tNFA_STATUS stat = NFA_STATUS_OK;
739
740 if (sIsNfaEnabled)
741 {
742 ALOGD ("%s: already enabled", __FUNCTION__);
743 goto TheEnd;
744 }
745
746 PowerSwitch::getInstance ().initialize (PowerSwitch::FULL_POWER);
747
748 {
749 unsigned long num = 0;
750
751 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
752 theInstance.Initialize(); //start GKI, NCI task, NFC task
753
754 {
755 SyncEventGuard guard (sNfaEnableEvent);
756 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs ();
757
758 NFA_Init (halFuncEntries);
759
760 stat = NFA_Enable (nfaDeviceManagementCallback, nfaConnectionCallback);
761 if (stat == NFA_STATUS_OK)
762 {
763 num = initializeGlobalAppLogLevel ();
764 CE_SetTraceLevel (num);
765 LLCP_SetTraceLevel (num);
766 NFC_SetTraceLevel (num);
767 RW_SetTraceLevel (num);
768 NFA_SetTraceLevel (num);
769 NFA_P2pSetTraceLevel (num);
770 sNfaEnableEvent.wait(); //wait for NFA command to finish
771 }
772 }
773
774 if (stat == NFA_STATUS_OK)
775 {
776 //sIsNfaEnabled indicates whether stack started successfully
777 if (sIsNfaEnabled)
778 {
779 SecureElement::getInstance().initialize (getNative(e, o));
780 nativeNfcTag_registerNdefTypeHandler ();
781 NfcTag::getInstance().initialize (getNative(e, o));
782 PeerToPeer::getInstance().initialize ();
783 PeerToPeer::getInstance().handleNfcOnOff (true);
784
785 /////////////////////////////////////////////////////////////////////////////////
786 // Add extra configuration here (work-arounds, etc.)
787
788 struct nfc_jni_native_data *nat = getNative(e, o);
789
790 if ( nat )
791 {
792 if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num)))
793 nat->tech_mask = num;
794 else
795 nat->tech_mask = DEFAULT_TECH_MASK;
796
797 ALOGD ("%s: tag polling tech mask=0x%X", __FUNCTION__, nat->tech_mask);
798 }
799
800 // if this value exists, set polling interval.
801 if (GetNumValue(NAME_NFA_DM_DISC_DURATION_POLL, &num, sizeof(num)))
802 NFA_SetRfDiscoveryDuration(num);
803
804 // Do custom NFCA startup configuration.
805 doStartupConfig();
806 goto TheEnd;
807 }
808 }
809
810 ALOGE ("%s: fail nfa enable; error=0x%X", __FUNCTION__, stat);
811
812 if (sIsNfaEnabled)
813 stat = NFA_Disable (FALSE /* ungraceful */);
814
815 theInstance.Finalize();
816 }
817
818 TheEnd:
819 if (sIsNfaEnabled)
820 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
821 ALOGD ("%s: exit", __FUNCTION__);
822 return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE;
823 }
824
825
826 /*******************************************************************************
827 **
828 ** Function: nfcManager_enableDiscovery
829 **
830 ** Description: Start polling and listening for devices.
831 ** e: JVM environment.
832 ** o: Java object.
833 ** mode: Not used.
834 **
835 ** Returns: None
836 **
837 *******************************************************************************/
nfcManager_enableDiscovery(JNIEnv * e,jobject o)838 static void nfcManager_enableDiscovery (JNIEnv* e, jobject o)
839 {
840 tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
841 struct nfc_jni_native_data *nat = getNative(e, o);
842
843 if (nat)
844 tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask;
845
846 ALOGD ("%s: enter; tech_mask = %02x", __FUNCTION__, tech_mask);
847
848 if (sDiscoveryEnabled)
849 {
850 ALOGE ("%s: already polling", __FUNCTION__);
851 return;
852 }
853
854 tNFA_STATUS stat = NFA_STATUS_OK;
855
856 ALOGD ("%s: sIsSecElemSelected=%u", __FUNCTION__, sIsSecElemSelected);
857
858 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
859
860 if (sRfEnabled) {
861 // Stop RF discovery to reconfigure
862 startRfDiscovery(false);
863 }
864
865 {
866 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
867 stat = NFA_EnablePolling (tech_mask);
868 if (stat == NFA_STATUS_OK)
869 {
870 ALOGD ("%s: wait for enable event", __FUNCTION__);
871 sDiscoveryEnabled = true;
872 sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
873 ALOGD ("%s: got enabled event", __FUNCTION__);
874 }
875 else
876 {
877 ALOGE ("%s: fail enable discovery; error=0x%X", __FUNCTION__, stat);
878 }
879 }
880
881 // Start P2P listening if tag polling was enabled or the mask was 0.
882 if (sDiscoveryEnabled || (tech_mask == 0))
883 {
884 ALOGD ("%s: Enable p2pListening", __FUNCTION__);
885 PeerToPeer::getInstance().enableP2pListening (true);
886
887 //if NFC service has deselected the sec elem, then apply default routes
888 if (!sIsSecElemSelected)
889 stat = SecureElement::getInstance().routeToDefault ();
890 }
891
892 // Actually start discovery.
893 startRfDiscovery (true);
894
895 PowerSwitch::getInstance ().setModeOn (PowerSwitch::DISCOVERY);
896
897 ALOGD ("%s: exit", __FUNCTION__);
898 }
899
900
901 /*******************************************************************************
902 **
903 ** Function: nfcManager_disableDiscovery
904 **
905 ** Description: Stop polling and listening for devices.
906 ** e: JVM environment.
907 ** o: Java object.
908 **
909 ** Returns: None
910 **
911 *******************************************************************************/
nfcManager_disableDiscovery(JNIEnv *,jobject)912 void nfcManager_disableDiscovery (JNIEnv*, jobject)
913 {
914 tNFA_STATUS status = NFA_STATUS_OK;
915 ALOGD ("%s: enter;", __FUNCTION__);
916
917 pn544InteropAbortNow ();
918 if (sDiscoveryEnabled == false)
919 {
920 ALOGD ("%s: already disabled", __FUNCTION__);
921 goto TheEnd;
922 }
923
924 // Stop RF Discovery.
925 startRfDiscovery (false);
926
927 if (sDiscoveryEnabled)
928 {
929 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
930 status = NFA_DisablePolling ();
931 if (status == NFA_STATUS_OK)
932 {
933 sDiscoveryEnabled = false;
934 sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
935 }
936 else
937 ALOGE ("%s: Failed to disable polling; error=0x%X", __FUNCTION__, status);
938 }
939
940 PeerToPeer::getInstance().enableP2pListening (false);
941
942 //if nothing is active after this, then tell the controller to power down
943 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::DISCOVERY))
944 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
945
946 // We may have had RF field notifications that did not cause
947 // any activate/deactive events. For example, caused by wireless
948 // charging orbs. Those may cause us to go to sleep while the last
949 // field event was indicating a field. To prevent sticking in that
950 // state, always reset the rf field status when we disable discovery.
951 SecureElement::getInstance().resetRfFieldStatus();
952 TheEnd:
953 ALOGD ("%s: exit", __FUNCTION__);
954 }
955
setUiccIdleTimeout(bool enable)956 void setUiccIdleTimeout (bool enable)
957 {
958 // This method is *NOT* thread-safe. Right now
959 // it is only called from the same thread so it's
960 // not an issue.
961 tNFA_STATUS stat = NFA_STATUS_OK;
962 UINT8 swp_cfg_byte0 = 0x00;
963 {
964 SyncEventGuard guard (sNfaGetConfigEvent);
965 stat = NFA_GetConfig(1, new tNFA_PMID[1] {0xC2});
966 if (stat != NFA_STATUS_OK)
967 {
968 ALOGE("%s: NFA_GetConfig failed", __FUNCTION__);
969 return;
970 }
971 sNfaGetConfigEvent.wait ();
972 if (sCurrentConfigLen < 4 || sConfig[1] != 0xC2) {
973 ALOGE("%s: Config TLV length %d returned is too short", __FUNCTION__,
974 sCurrentConfigLen);
975 return;
976 }
977 swp_cfg_byte0 = sConfig[3];
978 }
979 SyncEventGuard guard(sNfaSetConfigEvent);
980 if (enable)
981 swp_cfg_byte0 |= 0x01;
982 else
983 swp_cfg_byte0 &= ~0x01;
984
985 stat = NFA_SetConfig(0xC2, 1, &swp_cfg_byte0);
986 if (stat == NFA_STATUS_OK)
987 sNfaSetConfigEvent.wait ();
988 else
989 ALOGE("%s: Could not configure UICC idle timeout feature", __FUNCTION__);
990 return;
991 }
992 /*******************************************************************************
993 **
994 ** Function nfc_jni_cache_object_local
995 **
996 ** Description Allocates a java object and calls it's constructor
997 **
998 ** Returns -1 on failure, 0 on success
999 **
1000 *******************************************************************************/
nfc_jni_cache_object_local(JNIEnv * e,const char * className,jobject * cachedObj)1001 static int nfc_jni_cache_object_local (JNIEnv *e, const char *className, jobject *cachedObj)
1002 {
1003 ScopedLocalRef<jclass> cls(e, e->FindClass(className));
1004 if(cls.get() == NULL) {
1005 ALOGE ("%s: find class error", __FUNCTION__);
1006 return -1;
1007 }
1008
1009 jmethodID ctor = e->GetMethodID(cls.get(), "<init>", "()V");
1010 jobject obj = e->NewObject(cls.get(), ctor);
1011 if (obj == NULL) {
1012 ALOGE ("%s: create object error", __FUNCTION__);
1013 return -1;
1014 }
1015
1016 *cachedObj = obj;
1017 if (*cachedObj == NULL) {
1018 ALOGE ("%s: global ref error", __FUNCTION__);
1019 return -1;
1020 }
1021 return 0;
1022 }
1023
1024
1025 /*******************************************************************************
1026 **
1027 ** Function: nfcManager_doCreateLlcpServiceSocket
1028 **
1029 ** Description: Create a new LLCP server socket.
1030 ** e: JVM environment.
1031 ** o: Java object.
1032 ** nSap: Service access point.
1033 ** sn: Service name
1034 ** miu: Maximum information unit.
1035 ** rw: Receive window size.
1036 ** linearBufferLength: Max buffer size.
1037 **
1038 ** Returns: NativeLlcpServiceSocket Java object.
1039 **
1040 *******************************************************************************/
nfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)1041 static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
1042 {
1043 PeerToPeer::tJNI_HANDLE jniHandle = PeerToPeer::getInstance().getNewJniHandle ();
1044
1045 ScopedUtfChars serviceName(e, sn);
1046
1047 ALOGD ("%s: enter: sap=%i; name=%s; miu=%i; rw=%i; buffLen=%i", __FUNCTION__, nSap, serviceName.c_str(), miu, rw, linearBufferLength);
1048
1049 /* Create new NativeLlcpServiceSocket object */
1050 jobject serviceSocket = NULL;
1051 if (nfc_jni_cache_object(e, gNativeLlcpServiceSocketClassName, &(serviceSocket)) == -1)
1052 {
1053 ALOGE ("%s: Llcp socket object creation error", __FUNCTION__);
1054 return NULL;
1055 }
1056
1057 /* Get NativeLlcpServiceSocket class object */
1058 ScopedLocalRef<jclass> clsNativeLlcpServiceSocket(e, e->GetObjectClass(serviceSocket));
1059 if (e->ExceptionCheck())
1060 {
1061 e->ExceptionClear();
1062 ALOGE("%s: Llcp Socket get object class error", __FUNCTION__);
1063 return NULL;
1064 }
1065
1066 if (!PeerToPeer::getInstance().registerServer (jniHandle, serviceName.c_str()))
1067 {
1068 ALOGE("%s: RegisterServer error", __FUNCTION__);
1069 return NULL;
1070 }
1071
1072 jfieldID f;
1073
1074 /* Set socket handle to be the same as the NfaHandle*/
1075 f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mHandle", "I");
1076 e->SetIntField(serviceSocket, f, (jint) jniHandle);
1077 ALOGD ("%s: socket Handle = 0x%X", __FUNCTION__, jniHandle);
1078
1079 /* Set socket linear buffer length */
1080 f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalLinearBufferLength", "I");
1081 e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
1082 ALOGD ("%s: buffer length = %d", __FUNCTION__, linearBufferLength);
1083
1084 /* Set socket MIU */
1085 f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalMiu", "I");
1086 e->SetIntField(serviceSocket, f,(jint)miu);
1087 ALOGD ("%s: MIU = %d", __FUNCTION__, miu);
1088
1089 /* Set socket RW */
1090 f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalRw", "I");
1091 e->SetIntField(serviceSocket, f,(jint)rw);
1092 ALOGD ("%s: RW = %d", __FUNCTION__, rw);
1093
1094 sLastError = 0;
1095 ALOGD ("%s: exit", __FUNCTION__);
1096 return serviceSocket;
1097 }
1098
1099
1100 /*******************************************************************************
1101 **
1102 ** Function: nfcManager_doGetLastError
1103 **
1104 ** Description: Get the last error code.
1105 ** e: JVM environment.
1106 ** o: Java object.
1107 **
1108 ** Returns: Last error code.
1109 **
1110 *******************************************************************************/
nfcManager_doGetLastError(JNIEnv *,jobject)1111 static jint nfcManager_doGetLastError(JNIEnv*, jobject)
1112 {
1113 ALOGD ("%s: last error=%i", __FUNCTION__, sLastError);
1114 return sLastError;
1115 }
1116
1117
1118 /*******************************************************************************
1119 **
1120 ** Function: nfcManager_doDeinitialize
1121 **
1122 ** Description: Turn off NFC.
1123 ** e: JVM environment.
1124 ** o: Java object.
1125 **
1126 ** Returns: True if ok.
1127 **
1128 *******************************************************************************/
nfcManager_doDeinitialize(JNIEnv *,jobject)1129 static jboolean nfcManager_doDeinitialize (JNIEnv*, jobject)
1130 {
1131 ALOGD ("%s: enter", __FUNCTION__);
1132
1133 sIsDisabling = true;
1134 pn544InteropAbortNow ();
1135 SecureElement::getInstance().finalize ();
1136
1137 if (sIsNfaEnabled)
1138 {
1139 SyncEventGuard guard (sNfaDisableEvent);
1140 tNFA_STATUS stat = NFA_Disable (TRUE /* graceful */);
1141 if (stat == NFA_STATUS_OK)
1142 {
1143 ALOGD ("%s: wait for completion", __FUNCTION__);
1144 sNfaDisableEvent.wait (); //wait for NFA command to finish
1145 PeerToPeer::getInstance ().handleNfcOnOff (false);
1146 }
1147 else
1148 {
1149 ALOGE ("%s: fail disable; error=0x%X", __FUNCTION__, stat);
1150 }
1151 }
1152 nativeNfcTag_abortWaits();
1153 NfcTag::getInstance().abort ();
1154 sAbortConnlessWait = true;
1155 nativeLlcpConnectionlessSocket_abortWait();
1156 sIsNfaEnabled = false;
1157 sDiscoveryEnabled = false;
1158 sIsDisabling = false;
1159 sIsSecElemSelected = false;
1160
1161 {
1162 //unblock NFA_EnablePolling() and NFA_DisablePolling()
1163 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
1164 sNfaEnableDisablePollingEvent.notifyOne ();
1165 }
1166
1167 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
1168 theInstance.Finalize();
1169
1170 ALOGD ("%s: exit", __FUNCTION__);
1171 return JNI_TRUE;
1172 }
1173
1174
1175 /*******************************************************************************
1176 **
1177 ** Function: nfcManager_doCreateLlcpSocket
1178 **
1179 ** Description: Create a LLCP connection-oriented socket.
1180 ** e: JVM environment.
1181 ** o: Java object.
1182 ** nSap: Service access point.
1183 ** miu: Maximum information unit.
1184 ** rw: Receive window size.
1185 ** linearBufferLength: Max buffer size.
1186 **
1187 ** Returns: NativeLlcpSocket Java object.
1188 **
1189 *******************************************************************************/
nfcManager_doCreateLlcpSocket(JNIEnv * e,jobject,jint nSap,jint miu,jint rw,jint linearBufferLength)1190 static jobject nfcManager_doCreateLlcpSocket (JNIEnv* e, jobject, jint nSap, jint miu, jint rw, jint linearBufferLength)
1191 {
1192 ALOGD ("%s: enter; sap=%d; miu=%d; rw=%d; buffer len=%d", __FUNCTION__, nSap, miu, rw, linearBufferLength);
1193
1194 PeerToPeer::tJNI_HANDLE jniHandle = PeerToPeer::getInstance().getNewJniHandle ();
1195 bool stat = PeerToPeer::getInstance().createClient (jniHandle, miu, rw);
1196
1197 /* Create new NativeLlcpSocket object */
1198 jobject clientSocket = NULL;
1199 if (nfc_jni_cache_object_local(e, gNativeLlcpSocketClassName, &(clientSocket)) == -1)
1200 {
1201 ALOGE ("%s: fail Llcp socket creation", __FUNCTION__);
1202 return clientSocket;
1203 }
1204
1205 /* Get NativeConnectionless class object */
1206 ScopedLocalRef<jclass> clsNativeLlcpSocket(e, e->GetObjectClass(clientSocket));
1207 if (e->ExceptionCheck())
1208 {
1209 e->ExceptionClear();
1210 ALOGE ("%s: fail get class object", __FUNCTION__);
1211 return clientSocket;
1212 }
1213
1214 jfieldID f;
1215
1216 /* Set socket SAP */
1217 f = e->GetFieldID (clsNativeLlcpSocket.get(), "mSap", "I");
1218 e->SetIntField (clientSocket, f, (jint) nSap);
1219
1220 /* Set socket handle */
1221 f = e->GetFieldID (clsNativeLlcpSocket.get(), "mHandle", "I");
1222 e->SetIntField (clientSocket, f, (jint) jniHandle);
1223
1224 /* Set socket MIU */
1225 f = e->GetFieldID (clsNativeLlcpSocket.get(), "mLocalMiu", "I");
1226 e->SetIntField (clientSocket, f, (jint) miu);
1227
1228 /* Set socket RW */
1229 f = e->GetFieldID (clsNativeLlcpSocket.get(), "mLocalRw", "I");
1230 e->SetIntField (clientSocket, f, (jint) rw);
1231
1232 ALOGD ("%s: exit", __FUNCTION__);
1233 return clientSocket;
1234 }
1235
1236
1237 /*******************************************************************************
1238 **
1239 ** Function: nfcManager_doCreateLlcpConnectionlessSocket
1240 **
1241 ** Description: Create a connection-less socket.
1242 ** e: JVM environment.
1243 ** o: Java object.
1244 ** nSap: Service access point.
1245 ** sn: Service name.
1246 **
1247 ** Returns: NativeLlcpConnectionlessSocket Java object.
1248 **
1249 *******************************************************************************/
nfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *,jobject,jint nSap,jstring)1250 static jobject nfcManager_doCreateLlcpConnectionlessSocket (JNIEnv *, jobject, jint nSap, jstring /*sn*/)
1251 {
1252 ALOGD ("%s: nSap=0x%X", __FUNCTION__, nSap);
1253 return NULL;
1254 }
1255
1256
1257 /*******************************************************************************
1258 **
1259 ** Function: nfcManager_doGetSecureElementList
1260 **
1261 ** Description: Get a list of secure element handles.
1262 ** e: JVM environment.
1263 ** o: Java object.
1264 **
1265 ** Returns: List of secure element handles.
1266 **
1267 *******************************************************************************/
nfcManager_doGetSecureElementList(JNIEnv * e,jobject)1268 static jintArray nfcManager_doGetSecureElementList(JNIEnv* e, jobject)
1269 {
1270 ALOGD ("%s", __FUNCTION__);
1271 return SecureElement::getInstance().getListOfEeHandles (e);
1272 }
1273
1274
1275 /*******************************************************************************
1276 **
1277 ** Function: nfcManager_doSelectSecureElement
1278 **
1279 ** Description: NFC controller starts routing data in listen mode.
1280 ** e: JVM environment.
1281 ** o: Java object.
1282 **
1283 ** Returns: None
1284 **
1285 *******************************************************************************/
nfcManager_doSelectSecureElement(JNIEnv *,jobject)1286 static void nfcManager_doSelectSecureElement(JNIEnv*, jobject)
1287 {
1288 ALOGD ("%s: enter", __FUNCTION__);
1289 bool stat = true;
1290
1291 if (sIsSecElemSelected)
1292 {
1293 ALOGD ("%s: already selected", __FUNCTION__);
1294 goto TheEnd;
1295 }
1296
1297 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
1298
1299 if (sRfEnabled) {
1300 // Stop RF Discovery if we were polling
1301 startRfDiscovery (false);
1302 }
1303
1304 stat = SecureElement::getInstance().activate (0xABCDEF);
1305 if (stat)
1306 SecureElement::getInstance().routeToSecureElement ();
1307 sIsSecElemSelected = true;
1308
1309 startRfDiscovery (true);
1310 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_ROUTING);
1311 TheEnd:
1312 ALOGD ("%s: exit", __FUNCTION__);
1313 }
1314
1315
1316 /*******************************************************************************
1317 **
1318 ** Function: nfcManager_doDeselectSecureElement
1319 **
1320 ** Description: NFC controller stops routing data in listen mode.
1321 ** e: JVM environment.
1322 ** o: Java object.
1323 **
1324 ** Returns: None
1325 **
1326 *******************************************************************************/
nfcManager_doDeselectSecureElement(JNIEnv *,jobject)1327 static void nfcManager_doDeselectSecureElement(JNIEnv*, jobject)
1328 {
1329 ALOGD ("%s: enter", __FUNCTION__);
1330 bool stat = false;
1331 bool bRestartDiscovery = false;
1332
1333 if (! sIsSecElemSelected)
1334 {
1335 ALOGE ("%s: already deselected", __FUNCTION__);
1336 goto TheEnd;
1337 }
1338
1339 if (PowerSwitch::getInstance ().getLevel() == PowerSwitch::LOW_POWER)
1340 {
1341 ALOGD ("%s: do not deselect while power is OFF", __FUNCTION__);
1342 sIsSecElemSelected = false;
1343 goto TheEnd;
1344 }
1345
1346 if (sRfEnabled) {
1347 // Stop RF Discovery if we were polling
1348 startRfDiscovery (false);
1349 bRestartDiscovery = true;
1350 }
1351
1352 stat = SecureElement::getInstance().routeToDefault ();
1353 sIsSecElemSelected = false;
1354
1355 //if controller is not routing to sec elems AND there is no pipe connected,
1356 //then turn off the sec elems
1357 if (SecureElement::getInstance().isBusy() == false)
1358 SecureElement::getInstance().deactivate (0xABCDEF);
1359
1360 TheEnd:
1361 if (bRestartDiscovery)
1362 startRfDiscovery (true);
1363
1364 //if nothing is active after this, then tell the controller to power down
1365 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_ROUTING))
1366 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
1367
1368 ALOGD ("%s: exit", __FUNCTION__);
1369 }
1370
1371
1372 /*******************************************************************************
1373 **
1374 ** Function: isPeerToPeer
1375 **
1376 ** Description: Whether the activation data indicates the peer supports NFC-DEP.
1377 ** activated: Activation data.
1378 **
1379 ** Returns: True if the peer supports NFC-DEP.
1380 **
1381 *******************************************************************************/
isPeerToPeer(tNFA_ACTIVATED & activated)1382 static bool isPeerToPeer (tNFA_ACTIVATED& activated)
1383 {
1384 return activated.activate_ntf.protocol == NFA_PROTOCOL_NFC_DEP;
1385 }
1386
1387 /*******************************************************************************
1388 **
1389 ** Function: isListenMode
1390 **
1391 ** Description: Indicates whether the activation data indicates it is
1392 ** listen mode.
1393 **
1394 ** Returns: True if this listen mode.
1395 **
1396 *******************************************************************************/
isListenMode(tNFA_ACTIVATED & activated)1397 static bool isListenMode(tNFA_ACTIVATED& activated)
1398 {
1399 return ((NFC_DISCOVERY_TYPE_LISTEN_A == activated.activate_ntf.rf_tech_param.mode)
1400 || (NFC_DISCOVERY_TYPE_LISTEN_B == activated.activate_ntf.rf_tech_param.mode)
1401 || (NFC_DISCOVERY_TYPE_LISTEN_F == activated.activate_ntf.rf_tech_param.mode)
1402 || (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == activated.activate_ntf.rf_tech_param.mode)
1403 || (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == activated.activate_ntf.rf_tech_param.mode)
1404 || (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == activated.activate_ntf.rf_tech_param.mode)
1405 || (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == activated.activate_ntf.rf_tech_param.mode));
1406 }
1407
1408 /*******************************************************************************
1409 **
1410 ** Function: nfcManager_doCheckLlcp
1411 **
1412 ** Description: Not used.
1413 **
1414 ** Returns: True
1415 **
1416 *******************************************************************************/
nfcManager_doCheckLlcp(JNIEnv *,jobject)1417 static jboolean nfcManager_doCheckLlcp(JNIEnv*, jobject)
1418 {
1419 ALOGD("%s", __FUNCTION__);
1420 return JNI_TRUE;
1421 }
1422
1423
1424 /*******************************************************************************
1425 **
1426 ** Function: nfcManager_doActivateLlcp
1427 **
1428 ** Description: Not used.
1429 **
1430 ** Returns: True
1431 **
1432 *******************************************************************************/
nfcManager_doActivateLlcp(JNIEnv *,jobject)1433 static jboolean nfcManager_doActivateLlcp(JNIEnv*, jobject)
1434 {
1435 ALOGD("%s", __FUNCTION__);
1436 return JNI_TRUE;
1437 }
1438
1439
1440 /*******************************************************************************
1441 **
1442 ** Function: nfcManager_doAbort
1443 **
1444 ** Description: Not used.
1445 **
1446 ** Returns: None
1447 **
1448 *******************************************************************************/
nfcManager_doAbort(JNIEnv *,jobject)1449 static void nfcManager_doAbort(JNIEnv*, jobject)
1450 {
1451 ALOGE("%s: abort()", __FUNCTION__);
1452 abort();
1453 }
1454
1455
1456 /*******************************************************************************
1457 **
1458 ** Function: nfcManager_doDownload
1459 **
1460 ** Description: Not used.
1461 **
1462 ** Returns: True
1463 **
1464 *******************************************************************************/
nfcManager_doDownload(JNIEnv *,jobject)1465 static jboolean nfcManager_doDownload(JNIEnv*, jobject)
1466 {
1467 ALOGD("%s", __FUNCTION__);
1468 return JNI_TRUE;
1469 }
1470
1471
1472 /*******************************************************************************
1473 **
1474 ** Function: nfcManager_doResetTimeouts
1475 **
1476 ** Description: Not used.
1477 **
1478 ** Returns: None
1479 **
1480 *******************************************************************************/
nfcManager_doResetTimeouts(JNIEnv *,jobject)1481 static void nfcManager_doResetTimeouts(JNIEnv*, jobject)
1482 {
1483 ALOGD ("%s: %d millisec", __FUNCTION__, DEFAULT_GENERAL_TRANS_TIMEOUT);
1484 gGeneralTransceiveTimeout = DEFAULT_GENERAL_TRANS_TIMEOUT;
1485 }
1486
1487
1488 /*******************************************************************************
1489 **
1490 ** Function: nfcManager_doSetTimeout
1491 **
1492 ** Description: Set timeout value.
1493 ** e: JVM environment.
1494 ** o: Java object.
1495 ** timeout: Timeout value.
1496 **
1497 ** Returns: True if ok.
1498 **
1499 *******************************************************************************/
nfcManager_doSetTimeout(JNIEnv *,jobject,jint,jint timeout)1500 static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint /*tech*/, jint timeout)
1501 {
1502 if (timeout <= 0)
1503 {
1504 ALOGE("%s: Timeout must be positive.",__FUNCTION__);
1505 return false;
1506 }
1507
1508 ALOGD ("%s: timeout=%d", __FUNCTION__, timeout);
1509 gGeneralTransceiveTimeout = timeout;
1510 return true;
1511 }
1512
1513
1514 /*******************************************************************************
1515 **
1516 ** Function: nfcManager_doGetTimeout
1517 **
1518 ** Description: Get timeout value.
1519 ** e: JVM environment.
1520 ** o: Java object.
1521 ** tech: Not used.
1522 **
1523 ** Returns: Timeout value.
1524 **
1525 *******************************************************************************/
nfcManager_doGetTimeout(JNIEnv *,jobject,jint)1526 static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint /*tech*/)
1527 {
1528 ALOGD ("%s: timeout=%d", __FUNCTION__, gGeneralTransceiveTimeout);
1529 return gGeneralTransceiveTimeout;
1530 }
1531
1532
1533 /*******************************************************************************
1534 **
1535 ** Function: nfcManager_doDump
1536 **
1537 ** Description: Not used.
1538 ** e: JVM environment.
1539 ** o: Java object.
1540 **
1541 ** Returns: Text dump.
1542 **
1543 *******************************************************************************/
nfcManager_doDump(JNIEnv * e,jobject)1544 static jstring nfcManager_doDump(JNIEnv* e, jobject)
1545 {
1546 char buffer[100];
1547 snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", /*libnfc_llc_error_count*/ 0);
1548 return e->NewStringUTF(buffer);
1549 }
1550
1551
1552 /*******************************************************************************
1553 **
1554 ** Function: nfcManager_doSetP2pInitiatorModes
1555 **
1556 ** Description: Set P2P initiator's activation modes.
1557 ** e: JVM environment.
1558 ** o: Java object.
1559 ** modes: Active and/or passive modes. The values are specified
1560 ** in external/libnfc-nxp/inc/phNfcTypes.h. See
1561 ** enum phNfc_eP2PMode_t.
1562 **
1563 ** Returns: None.
1564 **
1565 *******************************************************************************/
nfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)1566 static void nfcManager_doSetP2pInitiatorModes (JNIEnv *e, jobject o, jint modes)
1567 {
1568 ALOGD ("%s: modes=0x%X", __FUNCTION__, modes);
1569 struct nfc_jni_native_data *nat = getNative(e, o);
1570
1571 tNFA_TECHNOLOGY_MASK mask = 0;
1572 if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A;
1573 if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F;
1574 if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F;
1575 if (modes & 0x08) mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE;
1576 if (modes & 0x10) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE;
1577 if (modes & 0x20) mask |= NFA_TECHNOLOGY_MASK_F_ACTIVE;
1578 nat->tech_mask = mask;
1579
1580 //this function is not called by the NFC service nor exposed by public API.
1581 }
1582
1583
1584 /*******************************************************************************
1585 **
1586 ** Function: nfcManager_doSetP2pTargetModes
1587 **
1588 ** Description: Set P2P target's activation modes.
1589 ** e: JVM environment.
1590 ** o: Java object.
1591 ** modes: Active and/or passive modes.
1592 **
1593 ** Returns: None.
1594 **
1595 *******************************************************************************/
nfcManager_doSetP2pTargetModes(JNIEnv *,jobject,jint modes)1596 static void nfcManager_doSetP2pTargetModes (JNIEnv*, jobject, jint modes)
1597 {
1598 ALOGD ("%s: modes=0x%X", __FUNCTION__, modes);
1599 // Map in the right modes
1600 tNFA_TECHNOLOGY_MASK mask = 0;
1601 if (modes & 0x01) mask |= NFA_TECHNOLOGY_MASK_A;
1602 if (modes & 0x02) mask |= NFA_TECHNOLOGY_MASK_F;
1603 if (modes & 0x04) mask |= NFA_TECHNOLOGY_MASK_F;
1604 if (modes & 0x08) mask |= NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE;
1605
1606 PeerToPeer::getInstance().setP2pListenMask(mask);
1607 //this function is not called by the NFC service nor exposed by public API.
1608 }
1609
1610 /*****************************************************************************
1611 **
1612 ** JNI functions for android-4.0.1_r1
1613 **
1614 *****************************************************************************/
1615 static JNINativeMethod gMethods[] =
1616 {
1617 {"doDownload", "()Z",
1618 (void *)nfcManager_doDownload},
1619
1620 {"initializeNativeStructure", "()Z",
1621 (void*) nfcManager_initNativeStruc},
1622
1623 {"doInitialize", "()Z",
1624 (void*) nfcManager_doInitialize},
1625
1626 {"doDeinitialize", "()Z",
1627 (void*) nfcManager_doDeinitialize},
1628
1629 {"enableDiscovery", "()V",
1630 (void*) nfcManager_enableDiscovery},
1631
1632 {"doGetSecureElementList", "()[I",
1633 (void *)nfcManager_doGetSecureElementList},
1634
1635 {"doSelectSecureElement", "()V",
1636 (void *)nfcManager_doSelectSecureElement},
1637
1638 {"doDeselectSecureElement", "()V",
1639 (void *)nfcManager_doDeselectSecureElement},
1640
1641 {"doCheckLlcp", "()Z",
1642 (void *)nfcManager_doCheckLlcp},
1643
1644 {"doActivateLlcp", "()Z",
1645 (void *)nfcManager_doActivateLlcp},
1646
1647 {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
1648 (void *)nfcManager_doCreateLlcpConnectionlessSocket},
1649
1650 {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
1651 (void*) nfcManager_doCreateLlcpServiceSocket},
1652
1653 {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
1654 (void*) nfcManager_doCreateLlcpSocket},
1655
1656 {"doGetLastError", "()I",
1657 (void*) nfcManager_doGetLastError},
1658
1659 {"disableDiscovery", "()V",
1660 (void*) nfcManager_disableDiscovery},
1661
1662 {"doSetTimeout", "(II)Z",
1663 (void *)nfcManager_doSetTimeout},
1664
1665 {"doGetTimeout", "(I)I",
1666 (void *)nfcManager_doGetTimeout},
1667
1668 {"doResetTimeouts", "()V",
1669 (void *)nfcManager_doResetTimeouts},
1670
1671 {"doAbort", "()V",
1672 (void *)nfcManager_doAbort},
1673
1674 {"doSetP2pInitiatorModes", "(I)V",
1675 (void *)nfcManager_doSetP2pInitiatorModes},
1676
1677 {"doSetP2pTargetModes", "(I)V",
1678 (void *)nfcManager_doSetP2pTargetModes},
1679
1680 {"doDump", "()Ljava/lang/String;",
1681 (void *)nfcManager_doDump},
1682 };
1683
1684
1685 /*******************************************************************************
1686 **
1687 ** Function: register_com_android_nfc_NativeNfcManager
1688 **
1689 ** Description: Regisgter JNI functions with Java Virtual Machine.
1690 ** e: Environment of JVM.
1691 **
1692 ** Returns: Status of registration.
1693 **
1694 *******************************************************************************/
register_com_android_nfc_NativeNfcManager(JNIEnv * e)1695 int register_com_android_nfc_NativeNfcManager (JNIEnv *e)
1696 {
1697 ALOGD ("%s: enter", __FUNCTION__);
1698 PowerSwitch::getInstance ().initialize (PowerSwitch::UNKNOWN_LEVEL);
1699 ALOGD ("%s: exit", __FUNCTION__);
1700 return jniRegisterNativeMethods (e, gNativeNfcManagerClassName, gMethods, NELEM (gMethods));
1701 }
1702
1703
1704 /*******************************************************************************
1705 **
1706 ** Function: startRfDiscovery
1707 **
1708 ** Description: Ask stack to start polling and listening for devices.
1709 ** isStart: Whether to start.
1710 **
1711 ** Returns: None
1712 **
1713 *******************************************************************************/
startRfDiscovery(bool isStart)1714 void startRfDiscovery(bool isStart)
1715 {
1716 tNFA_STATUS status = NFA_STATUS_FAILED;
1717
1718 ALOGD ("%s: is start=%d", __FUNCTION__, isStart);
1719 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
1720 status = isStart ? NFA_StartRfDiscovery () : NFA_StopRfDiscovery ();
1721 if (status == NFA_STATUS_OK)
1722 {
1723 sNfaEnableDisablePollingEvent.wait (); //wait for NFA_RF_DISCOVERY_xxxx_EVT
1724 sRfEnabled = isStart;
1725 }
1726 else
1727 {
1728 ALOGE ("%s: Failed to start/stop RF discovery; error=0x%X", __FUNCTION__, status);
1729 }
1730 }
1731
1732
1733 /*******************************************************************************
1734 **
1735 ** Function: doStartupConfig
1736 **
1737 ** Description: Configure the NFC controller.
1738 **
1739 ** Returns: None
1740 **
1741 *******************************************************************************/
doStartupConfig()1742 void doStartupConfig()
1743 {
1744 unsigned long num = 0;
1745 struct nfc_jni_native_data *nat = getNative(0, 0);
1746 tNFA_STATUS stat = NFA_STATUS_FAILED;
1747
1748 // If polling for Active mode, set the ordering so that we choose Active over Passive mode first.
1749 if (nat && (nat->tech_mask & (NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE)))
1750 {
1751 UINT8 act_mode_order_param[] = { 0x01 };
1752 SyncEventGuard guard (sNfaSetConfigEvent);
1753 stat = NFA_SetConfig(NCI_PARAM_ID_ACT_ORDER, sizeof(act_mode_order_param), &act_mode_order_param[0]);
1754 if (stat == NFA_STATUS_OK)
1755 sNfaSetConfigEvent.wait ();
1756 }
1757 }
1758
1759
1760 /*******************************************************************************
1761 **
1762 ** Function: nfcManager_isNfcActive
1763 **
1764 ** Description: Used externaly to determine if NFC is active or not.
1765 **
1766 ** Returns: 'true' if the NFC stack is running, else 'false'.
1767 **
1768 *******************************************************************************/
nfcManager_isNfcActive()1769 bool nfcManager_isNfcActive()
1770 {
1771 return sIsNfaEnabled;
1772 }
1773
1774
1775 /*******************************************************************************
1776 **
1777 ** Function: startStopPolling
1778 **
1779 ** Description: Start or stop polling.
1780 ** isStartPolling: true to start polling; false to stop polling.
1781 **
1782 ** Returns: None.
1783 **
1784 *******************************************************************************/
startStopPolling(bool isStartPolling)1785 void startStopPolling (bool isStartPolling)
1786 {
1787 ALOGD ("%s: enter; isStart=%u", __FUNCTION__, isStartPolling);
1788 tNFA_STATUS stat = NFA_STATUS_FAILED;
1789
1790 startRfDiscovery (false);
1791 if (isStartPolling)
1792 {
1793 tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
1794 unsigned long num = 0;
1795 if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num)))
1796 tech_mask = num;
1797
1798 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
1799 ALOGD ("%s: enable polling", __FUNCTION__);
1800 stat = NFA_EnablePolling (tech_mask);
1801 if (stat == NFA_STATUS_OK)
1802 {
1803 ALOGD ("%s: wait for enable event", __FUNCTION__);
1804 sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
1805 }
1806 else
1807 ALOGE ("%s: fail enable polling; error=0x%X", __FUNCTION__, stat);
1808 }
1809 else
1810 {
1811 SyncEventGuard guard (sNfaEnableDisablePollingEvent);
1812 ALOGD ("%s: disable polling", __FUNCTION__);
1813 stat = NFA_DisablePolling ();
1814 if (stat == NFA_STATUS_OK)
1815 {
1816 sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
1817 }
1818 else
1819 ALOGE ("%s: fail disable polling; error=0x%X", __FUNCTION__, stat);
1820 }
1821 startRfDiscovery (true);
1822 ALOGD ("%s: exit", __FUNCTION__);
1823 }
1824
1825
1826 } /* namespace android */
1827