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