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