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