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