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