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