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