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