/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *  Tag-reading, tag-writing operations.
 */
#include "NfcTag.h"

#include <android-base/stringprintf.h>
#include <base/logging.h>
#include <log/log.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedPrimitiveArray.h>

#include "JavaClassConstants.h"
#include "nfc_brcm_defs.h"
#include "nfc_config.h"
#include "phNxpExtns.h"
#include "rw_int.h"

using android::base::StringPrintf;

extern bool nfc_debug_enabled;

/*******************************************************************************
**
** Function:        NfcTag
**
** Description:     Initialize member variables.
**
** Returns:         None
**
*******************************************************************************/
NfcTag::NfcTag()
    : mNumTechList(0),
      mTechnologyTimeoutsTable(MAX_NUM_TECHNOLOGY),
      mNativeData(NULL),
      mIsActivated(false),
      mActivationState(Idle),
      mProtocol(NFC_PROTOCOL_UNKNOWN),
      mtT1tMaxMessageSize(0),
      mReadCompletedStatus(NFA_STATUS_OK),
      mLastKovioUidLen(0),
      mNdefDetectionTimedOut(false),
      mIsDynamicTagId(false),
      mPresenceCheckAlgorithm(NFA_RW_PRES_CHK_DEFAULT),
      mIsFelicaLite(false) {
  memset(mTechList, 0, sizeof(mTechList));
  memset(mTechHandles, 0, sizeof(mTechHandles));
  memset(mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
  memset(mTechParams, 0, sizeof(mTechParams));
  memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN);
}

/*******************************************************************************
**
** Function:        getInstance
**
** Description:     Get a reference to the singleton NfcTag object.
**
** Returns:         Reference to NfcTag object.
**
*******************************************************************************/
NfcTag& NfcTag::getInstance() {
  static NfcTag tag;
  return tag;
}

/*******************************************************************************
**
** Function:        initialize
**
** Description:     Reset member variables.
**                  native: Native data.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::initialize(nfc_jni_native_data* native) {
  mNativeData = native;
  mIsActivated = false;
  mActivationState = Idle;
  mProtocol = NFC_PROTOCOL_UNKNOWN;
  mNumTechList = 0;
  mtT1tMaxMessageSize = 0;
  mReadCompletedStatus = NFA_STATUS_OK;
  resetTechnologies();
  if (NfcConfig::hasKey(NAME_PRESENCE_CHECK_ALGORITHM))
    mPresenceCheckAlgorithm =
        NfcConfig::getUnsigned(NAME_PRESENCE_CHECK_ALGORITHM);
}

/*******************************************************************************
**
** Function:        abort
**
** Description:     Unblock all operations.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::abort() {
  SyncEventGuard g(mReadCompleteEvent);
  mReadCompleteEvent.notifyOne();
}

/*******************************************************************************
**
** Function:        getActivationState
**
** Description:     What is the current state: Idle, Sleep, or Activated.
**
** Returns:         Idle, Sleep, or Activated.
**
*******************************************************************************/
NfcTag::ActivationState NfcTag::getActivationState() {
  return mActivationState;
}

/*******************************************************************************
**
** Function:        setDeactivationState
**
** Description:     Set the current state: Idle or Sleep.
**                  deactivated: state of deactivation.
**
** Returns:         None.
**
*******************************************************************************/
void NfcTag::setDeactivationState(tNFA_DEACTIVATED& deactivated) {
  static const char fn[] = "NfcTag::setDeactivationState";
  mActivationState = Idle;
  mNdefDetectionTimedOut = false;
  if (deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP) mActivationState = Sleep;
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s: state=%u", fn, mActivationState);
}

/*******************************************************************************
**
** Function:        setActivationState
**
** Description:     Set the current state to Active.
**
** Returns:         None.
**
*******************************************************************************/
void NfcTag::setActivationState() {
  static const char fn[] = "NfcTag::setActivationState";
  mNdefDetectionTimedOut = false;
  mActivationState = Active;
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s: state=%u", fn, mActivationState);
}

/*******************************************************************************
**
** Function:        isActivated
**
** Description:     Is tag activated?
**
** Returns:         True if tag is activated.
**
*******************************************************************************/
bool NfcTag::isActivated() { return mIsActivated; }

/*******************************************************************************
**
** Function:        getProtocol
**
** Description:     Get the protocol of the current tag.
**
** Returns:         Protocol number.
**
*******************************************************************************/
tNFC_PROTOCOL NfcTag::getProtocol() { return mProtocol; }

/*******************************************************************************
**
** Function         TimeDiff
**
** Description      Computes time difference in milliseconds.
**
** Returns          Time difference in milliseconds
**
*******************************************************************************/
uint32_t TimeDiff(timespec start, timespec end) {
  timespec temp;
  if ((end.tv_nsec - start.tv_nsec) < 0) {
    temp.tv_sec = end.tv_sec - start.tv_sec - 1;
    temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
  } else {
    temp.tv_sec = end.tv_sec - start.tv_sec;
    temp.tv_nsec = end.tv_nsec - start.tv_nsec;
  }

  return (temp.tv_sec * 1000) + (temp.tv_nsec / 1000000);
}

/*******************************************************************************
**
** Function:        IsSameKovio
**
** Description:     Checks if tag activate is the same (UID) Kovio tag
*previously
**                  activated.  This is needed due to a problem with some Kovio
**                  tags re-activating multiple times.
**                  activationData: data from activation.
**
** Returns:         true if the activation is from the same tag previously
**                  activated, false otherwise
**
*******************************************************************************/
bool NfcTag::IsSameKovio(tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::IsSameKovio";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
  tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;

  if (rfDetail.protocol != NFC_PROTOCOL_KOVIO) return false;

  memcpy(&(mTechParams[0]), &(rfDetail.rf_tech_param),
         sizeof(rfDetail.rf_tech_param));
  if (mTechParams[0].mode != NFC_DISCOVERY_TYPE_POLL_KOVIO) return false;

  struct timespec now;
  clock_gettime(CLOCK_REALTIME, &now);

  bool rVal = false;
  if (mTechParams[0].param.pk.uid_len == mLastKovioUidLen) {
    if (memcmp(mLastKovioUid, &mTechParams[0].param.pk.uid,
               mTechParams[0].param.pk.uid_len) == 0) {
      // same tag
      if (TimeDiff(mLastKovioTime, now) < 500) {
        // same tag within 500 ms, ignore activation
        rVal = true;
      }
    }
  }

  // save Kovio tag info
  if (!rVal) {
    if ((mLastKovioUidLen = mTechParams[0].param.pk.uid_len) >
        NFC_KOVIO_MAX_LEN)
      mLastKovioUidLen = NFC_KOVIO_MAX_LEN;
    memcpy(mLastKovioUid, mTechParams[0].param.pk.uid, mLastKovioUidLen);
  }
  mLastKovioTime = now;
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s: exit, is same Kovio=%d", fn, rVal);
  return rVal;
}

/*******************************************************************************
**
** Function:        discoverTechnologies
**
** Description:     Discover the technologies that NFC service needs by
*interpreting
**                  the data structures from the stack.
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::discoverTechnologies(tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::discoverTechnologies (activation)";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
  tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;

  mNumTechList = 0;
  mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
  mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;

  // save the stack's data structure for interpretation later
  memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
         sizeof(rfDetail.rf_tech_param));

  if (NFC_PROTOCOL_T1T == rfDetail.protocol) {
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
  } else if (NFC_PROTOCOL_T2T == rfDetail.protocol) {
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
    // could be MifFare UL or Classic or Kovio
    {
      // need to look at first byte of uid to find Manufacture Byte
      tNFC_RF_TECH_PARAMS tech_params;
      memcpy(&tech_params, &(rfDetail.rf_tech_param),
             sizeof(rfDetail.rf_tech_param));

      if ((tech_params.param.pa.nfcid1[0] == 0x04 &&
           rfDetail.rf_tech_param.param.pa.sel_rsp == 0) ||
          rfDetail.rf_tech_param.param.pa.sel_rsp == 0x18 ||
          rfDetail.rf_tech_param.param.pa.sel_rsp == 0x08) {
        if (rfDetail.rf_tech_param.param.pa.sel_rsp == 0) {
          mNumTechList++;
          mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
          mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
          // save the stack's data structure for interpretation later
          memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
                 sizeof(rfDetail.rf_tech_param));
          mTechList[mNumTechList] =
              TARGET_TYPE_MIFARE_UL;  // is TagTechnology.MIFARE_ULTRALIGHT by
                                      // Java API
        }
      }
    }
  } else if (NFC_PROTOCOL_T3T == rfDetail.protocol) {
    uint8_t xx = 0;

    mTechList[mNumTechList] = TARGET_TYPE_FELICA;

    // see if it is Felica Lite.
    while (xx < activationData.params.t3t.num_system_codes) {
      if (activationData.params.t3t.p_system_codes[xx++] ==
          T3T_SYSTEM_CODE_FELICA_LITE) {
        mIsFelicaLite = true;
        break;
      }
    }
  } else if (NFC_PROTOCOL_ISO_DEP == rfDetail.protocol) {
    // type-4 tag uses technology ISO-DEP and technology A or B
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_4;  // is TagTechnology.ISO_DEP by Java API
    if ((rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
        (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
        (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
        (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
      mNumTechList++;
      mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
      mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
      mTechList[mNumTechList] =
          TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
      // save the stack's data structure for interpretation later
      memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
             sizeof(rfDetail.rf_tech_param));
    } else if ((rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
               (rfDetail.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
               (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
               (rfDetail.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)) {
      mNumTechList++;
      mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
      mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
      mTechList[mNumTechList] =
          TARGET_TYPE_ISO14443_3B;  // is TagTechnology.NFC_B by Java API
      // save the stack's data structure for interpretation later
      memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
             sizeof(rfDetail.rf_tech_param));
    }
  } else if (NFC_PROTOCOL_T5T == rfDetail.protocol) {
    // is TagTechnology.NFC_V by Java API
    mTechList[mNumTechList] = TARGET_TYPE_V;
  } else if (NFC_PROTOCOL_KOVIO == rfDetail.protocol) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Kovio", fn);
    mTechList[mNumTechList] = TARGET_TYPE_KOVIO_BARCODE;
  } else if (NFC_PROTOCOL_MIFARE == rfDetail.protocol) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Mifare Classic", fn);
    EXTNS_MfcInit(activationData);
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
    mNumTechList++;
    mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
    mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
    // save the stack's data structure for interpretation later
    memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
           sizeof(rfDetail.rf_tech_param));
    mTechList[mNumTechList] =
        TARGET_TYPE_MIFARE_CLASSIC;  // is TagTechnology.MIFARE_CLASSIC by Java
                                     // API
  } else {
    LOG(ERROR) << StringPrintf("%s: unknown protocol ????", fn);
    mTechList[mNumTechList] = TARGET_TYPE_UNKNOWN;
  }

  mNumTechList++;
  for (int i = 0; i < mNumTechList; i++) {
    DLOG_IF(INFO, nfc_debug_enabled)
        << StringPrintf("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn, i,
                        mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]);
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
}

/*******************************************************************************
**
** Function:        discoverTechnologies
**
** Description:     Discover the technologies that NFC service needs by
*interpreting
**                  the data structures from the stack.
**                  discoveryData: data from discovery events(s).
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::discoverTechnologies(tNFA_DISC_RESULT& discoveryData) {
  static const char fn[] = "NfcTag::discoverTechnologies (discovery)";
  tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf;

  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
      "%s: enter: rf disc. id=%u; protocol=%u, mNumTechList=%u", fn,
      discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList);
  if (mNumTechList >= MAX_NUM_TECHNOLOGY) {
    LOG(ERROR) << StringPrintf("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
    goto TheEnd;
  }
  mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
  mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;

  // save the stack's data structure for interpretation later
  memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
         sizeof(discovery_ntf.rf_tech_param));

  if (NFC_PROTOCOL_T1T == discovery_ntf.protocol) {
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
  } else if (NFC_PROTOCOL_T2T == discovery_ntf.protocol) {
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
    // type-2 tags are identical to Mifare Ultralight, so Ultralight is also
    // discovered
    if ((discovery_ntf.rf_tech_param.param.pa.sel_rsp == 0) &&
        (mNumTechList < (MAX_NUM_TECHNOLOGY - 1))) {
      // Mifare Ultralight
      mNumTechList++;
      mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
      mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
      mTechList[mNumTechList] =
          TARGET_TYPE_MIFARE_UL;  // is TagTechnology.MIFARE_ULTRALIGHT by Java
                                  // API
    }

    // save the stack's data structure for interpretation later
    memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
           sizeof(discovery_ntf.rf_tech_param));
  } else if (NFC_PROTOCOL_T3T == discovery_ntf.protocol) {
    mTechList[mNumTechList] = TARGET_TYPE_FELICA;
  } else if (NFC_PROTOCOL_ISO_DEP == discovery_ntf.protocol) {
    // type-4 tag uses technology ISO-DEP and technology A or B
    mTechList[mNumTechList] =
        TARGET_TYPE_ISO14443_4;  // is TagTechnology.ISO_DEP by Java API
    if ((discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
        (discovery_ntf.rf_tech_param.mode ==
         NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
        (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
        (discovery_ntf.rf_tech_param.mode ==
         NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
      if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
        mNumTechList++;
        mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
        mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
        mTechList[mNumTechList] =
            TARGET_TYPE_ISO14443_3A;  // is TagTechnology.NFC_A by Java API
        // save the stack's data structure for interpretation later
        memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
               sizeof(discovery_ntf.rf_tech_param));
      }
    } else if ((discovery_ntf.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_POLL_B) ||
               (discovery_ntf.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
               (discovery_ntf.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_LISTEN_B) ||
               (discovery_ntf.rf_tech_param.mode ==
                NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)) {
      if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
        mNumTechList++;
        mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
        mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
        mTechList[mNumTechList] =
            TARGET_TYPE_ISO14443_3B;  // is TagTechnology.NFC_B by Java API
        // save the stack's data structure for interpretation later
        memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
               sizeof(discovery_ntf.rf_tech_param));
      }
    }
  } else if (NFC_PROTOCOL_T5T == discovery_ntf.protocol) {
    // is TagTechnology.NFC_V by Java API
    mTechList[mNumTechList] = TARGET_TYPE_V;
  } else if (NFC_PROTOCOL_MIFARE == discovery_ntf.protocol) {
    mTechList[mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC;
    if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
      mNumTechList++;
      mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
      mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
      mTechList[mNumTechList] = TARGET_TYPE_ISO14443_3A;
      // save the stack's data structure for interpretation later
      memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
             sizeof(discovery_ntf.rf_tech_param));
    }
  } else {
    LOG(ERROR) << StringPrintf("%s: unknown protocol ????", fn);
    mTechList[mNumTechList] = TARGET_TYPE_UNKNOWN;
  }

  mNumTechList++;
  if (discovery_ntf.more != NCI_DISCOVER_NTF_MORE) {
    for (int i = 0; i < mNumTechList; i++) {
      DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
          "%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn, i, mTechList[i],
          mTechHandles[i], mTechLibNfcTypes[i]);
    }
  }

TheEnd:
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
}

/*******************************************************************************
**
** Function:        createNativeNfcTag
**
** Description:     Create a brand new Java NativeNfcTag object;
**                  fill the objects's member variables with data;
**                  notify NFC service;
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::createNativeNfcTag(tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::createNativeNfcTag";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);

  JNIEnv* e = NULL;
  ScopedAttach attach(mNativeData->vm, &e);
  if (e == NULL) {
    LOG(ERROR) << StringPrintf("%s: jni env is null", fn);
    return;
  }

  ScopedLocalRef<jclass> tag_cls(e,
                                 e->GetObjectClass(mNativeData->cached_NfcTag));
  if (e->ExceptionCheck()) {
    e->ExceptionClear();
    LOG(ERROR) << StringPrintf("%s: failed to get class", fn);
    return;
  }

  // create a new Java NativeNfcTag object
  jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
  ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor));

  // fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes
  fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get());

  // fill NativeNfcTag's members: mHandle, mConnectedTechnology
  fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData);

  // fill NativeNfcTag's members: mTechPollBytes
  fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData);

  // fill NativeNfcTag's members: mTechActBytes
  fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData);

  // fill NativeNfcTag's members: mUid
  fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData);

  if (mNativeData->tag != NULL) {
    e->DeleteGlobalRef(mNativeData->tag);
  }
  mNativeData->tag = e->NewGlobalRef(tag.get());

  // notify NFC service about this new tag
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s: try notify nfc service", fn);
  e->CallVoidMethod(mNativeData->manager,
                    android::gCachedNfcManagerNotifyNdefMessageListeners,
                    tag.get());
  if (e->ExceptionCheck()) {
    e->ExceptionClear();
    LOG(ERROR) << StringPrintf("%s: fail notify nfc service", fn);
  }

  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
}

/*******************************************************************************
**
** Function:        fillNativeNfcTagMembers1
**
** Description:     Fill NativeNfcTag's members: mProtocols, mTechList,
*mTechHandles, mTechLibNfcTypes.
**                  e: JVM environment.
**                  tag_cls: Java NativeNfcTag class.
**                  tag: Java NativeNfcTag object.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::fillNativeNfcTagMembers1(JNIEnv* e, jclass tag_cls, jobject tag) {
  static const char fn[] = "NfcTag::fillNativeNfcTagMembers1";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);

  // create objects that represent NativeNfcTag's member variables
  ScopedLocalRef<jintArray> techList(e, e->NewIntArray(mNumTechList));
  ScopedLocalRef<jintArray> handleList(e, e->NewIntArray(mNumTechList));
  ScopedLocalRef<jintArray> typeList(e, e->NewIntArray(mNumTechList));

  {
    ScopedIntArrayRW technologies(e, techList.get());
    ScopedIntArrayRW handles(e, handleList.get());
    ScopedIntArrayRW types(e, typeList.get());
    for (int i = 0; i < mNumTechList; i++) {
      mNativeData->tProtocols[i] = mTechLibNfcTypes[i];
      mNativeData->handles[i] = mTechHandles[i];
      technologies[i] = mTechList[i];
      handles[i] = mTechHandles[i];
      types[i] = mTechLibNfcTypes[i];
    }
  }

  jfieldID f = NULL;

  f = e->GetFieldID(tag_cls, "mTechList", "[I");
  e->SetObjectField(tag, f, techList.get());

  f = e->GetFieldID(tag_cls, "mTechHandles", "[I");
  e->SetObjectField(tag, f, handleList.get());

  f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I");
  e->SetObjectField(tag, f, typeList.get());
}

/*******************************************************************************
**
** Function:        fillNativeNfcTagMembers2
**
** Description:     Fill NativeNfcTag's members: mConnectedTechIndex or
*mConnectedTechnology.
**                  The original Google's implementation is in
*set_target_pollBytes(
**                  in com_android_nfc_NativeNfcTag.cpp;
**                  e: JVM environment.
**                  tag_cls: Java NativeNfcTag class.
**                  tag: Java NativeNfcTag object.
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::fillNativeNfcTagMembers2(JNIEnv* e, jclass tag_cls, jobject tag,
                                      tNFA_ACTIVATED& /*activationData*/) {
  static const char fn[] = "NfcTag::fillNativeNfcTagMembers2";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
  jfieldID f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I");
  e->SetIntField(tag, f, (jint)0);
}

/*******************************************************************************
**
** Function:        fillNativeNfcTagMembers3
**
** Description:     Fill NativeNfcTag's members: mTechPollBytes.
**                  The original Google's implementation is in
*set_target_pollBytes(
**                  in com_android_nfc_NativeNfcTag.cpp;
**                  e: JVM environment.
**                  tag_cls: Java NativeNfcTag class.
**                  tag: Java NativeNfcTag object.
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::fillNativeNfcTagMembers3(JNIEnv* e, jclass tag_cls, jobject tag,
                                      tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::fillNativeNfcTagMembers3";
  ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0));
  ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get()));
  ScopedLocalRef<jobjectArray> techPollBytes(
      e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
  int len = 0;

  for (int i = 0; i < mNumTechList; i++) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
        "%s: index=%d; rf tech params mode=%u", fn, i, mTechParams[i].mode);
    if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams[i].mode ||
        NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams[i].mode ||
        NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams[i].mode ||
        NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams[i].mode) {
      DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech A", fn);
      pollBytes.reset(e->NewByteArray(2));
      e->SetByteArrayRegion(pollBytes.get(), 0, 2,
                            (jbyte*)mTechParams[i].param.pa.sens_res);
    } else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams[i].mode) {
      if (mTechList[i] ==
          TARGET_TYPE_ISO14443_3B)  // is TagTechnology.NFC_B by Java API
      {
        /*****************
        see NFC Forum Digital Protocol specification; section 5.6.2;
        in SENSB_RES response, byte 6 through 9 is Application Data, byte 10-12
        or 13 is Protocol Info; used by public API: NfcB.getApplicationData(),
        NfcB.getProtocolInfo();
        *****************/
        DLOG_IF(INFO, nfc_debug_enabled)
            << StringPrintf("%s: tech B; TARGET_TYPE_ISO14443_3B", fn);
        len = mTechParams[i].param.pb.sensb_res_len;
        if (len >= NFC_NFCID0_MAX_LEN) {
          // subtract 4 bytes for NFCID0 at byte 2 through 5
          len = len - NFC_NFCID0_MAX_LEN;
        } else {
          android_errorWriteLog(0x534e4554, "124940143");
          LOG(ERROR) << StringPrintf("%s: sensb_res_len error", fn);
          len = 0;
        }
        pollBytes.reset(e->NewByteArray(len));
        e->SetByteArrayRegion(pollBytes.get(), 0, len,
                              (jbyte*)(mTechParams[i].param.pb.sensb_res + 4));
      } else {
        pollBytes.reset(e->NewByteArray(0));
      }
    } else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams[i].mode) {
      /****************
      see NFC Forum Type 3 Tag Operation Specification; sections 2.3.2, 2.3.1.2;
      see NFC Forum Digital Protocol Specification; sections 6.6.2;
      PMm: manufacture parameter; 8 bytes;
      System Code: 2 bytes;
      ****************/
      DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech F", fn);
      uint8_t result[10];  // return result to NFC service
      memset(result, 0, sizeof(result));
      len = 10;

      /****
      for (int ii = 0; ii < mTechParams [i].param.pf.sensf_res_len; ii++)
      {
          DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech F,
      sendf_res[%d]=%d (0x%x)", fn, ii, mTechParams
      [i].param.pf.sensf_res[ii],mTechParams [i].param.pf.sensf_res[ii]);
      }
      ***/
      memcpy(result, mTechParams[i].param.pf.sensf_res + 8, 8);  // copy PMm
      if (activationData.params.t3t.num_system_codes >
          0)  // copy the first System Code
      {
        uint16_t systemCode = *(activationData.params.t3t.p_system_codes);
        result[8] = (uint8_t)(systemCode >> 8);
        result[9] = (uint8_t)systemCode;
        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
            "%s: tech F; sys code=0x%X 0x%X", fn, result[8], result[9]);
      }
      pollBytes.reset(e->NewByteArray(len));
      e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*)result);
    } else if (NFC_DISCOVERY_TYPE_POLL_V == mTechParams[i].mode ||
               NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams[i].mode) {
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: tech iso 15693", fn);
      // iso 15693 response flags: 1 octet
      // iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
      // used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
      uint8_t data[2] = {activationData.params.i93.afi,
                         activationData.params.i93.dsfid};
      pollBytes.reset(e->NewByteArray(2));
      e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*)data);
    } else {
      LOG(ERROR) << StringPrintf("%s: tech unknown ????", fn);
      pollBytes.reset(e->NewByteArray(0));
    }  // switch: every type of technology
    e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get());
  }  // for: every technology in the array
  jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B");
  e->SetObjectField(tag, f, techPollBytes.get());
}

/*******************************************************************************
**
** Function:        fillNativeNfcTagMembers4
**
** Description:     Fill NativeNfcTag's members: mTechActBytes.
**                  The original Google's implementation is in
*set_target_activationBytes()
**                  in com_android_nfc_NativeNfcTag.cpp;
**                  e: JVM environment.
**                  tag_cls: Java NativeNfcTag class.
**                  tag: Java NativeNfcTag object.
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::fillNativeNfcTagMembers4(JNIEnv* e, jclass tag_cls, jobject tag,
                                      tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::fillNativeNfcTagMembers4";
  ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0));
  ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get()));
  ScopedLocalRef<jobjectArray> techActBytes(
      e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));

  for (int i = 0; i < mNumTechList; i++) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: index=%d", fn, i);
    if (NFC_PROTOCOL_T1T == mTechLibNfcTypes[i] ||
        NFC_PROTOCOL_T2T == mTechLibNfcTypes[i]) {
      if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T1T)
        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: T1T; tech A", fn);
      else if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T2T)
        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: T2T; tech A", fn);
      actBytes.reset(e->NewByteArray(1));
      e->SetByteArrayRegion(actBytes.get(), 0, 1,
                            (jbyte*)&mTechParams[i].param.pa.sel_rsp);
    } else if (NFC_PROTOCOL_T3T == mTechLibNfcTypes[i]) {
      // felica
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: T3T; felica; tech F", fn);
      // really, there is no data
      actBytes.reset(e->NewByteArray(0));
    } else if (NFC_PROTOCOL_MIFARE == mTechLibNfcTypes[i]) {
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: Mifare Classic; tech A", fn);
      actBytes.reset(e->NewByteArray(1));
      e->SetByteArrayRegion(actBytes.get(), 0, 1,
                            (jbyte*)&mTechParams[i].param.pa.sel_rsp);
    } else if (NFC_PROTOCOL_ISO_DEP == mTechLibNfcTypes[i]) {
      // t4t
      if (mTechList[i] ==
          TARGET_TYPE_ISO14443_4)  // is TagTechnology.ISO_DEP by Java API
      {
        if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
          // see NFC Forum Digital Protocol specification, section 11.6.2, "RATS
          // Response"; search for "historical bytes";  copy historical bytes
          // into Java object;  the public API, IsoDep.getHistoricalBytes(),
          // returns this data;
          if (activationData.activate_ntf.intf_param.type ==
              NFC_INTERFACE_ISO_DEP) {
            tNFC_INTF_PA_ISO_DEP& pa_iso =
                activationData.activate_ntf.intf_param.intf_param.pa_iso;
            DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
                "%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u",
                fn, pa_iso.his_byte_len);
            actBytes.reset(e->NewByteArray(pa_iso.his_byte_len));
            if (pa_iso.his_byte_len > 0)
              e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len,
                                    (jbyte*)(pa_iso.his_byte));
          } else {
            LOG(ERROR) << StringPrintf(
                "%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn,
                activationData.activate_ntf.intf_param.type);
            actBytes.reset(e->NewByteArray(0));
          }
        } else if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) ||
                   (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
                   (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
                   (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)) {
          // see NFC Forum Digital Protocol specification, section 12.6.2,
          // "ATTRIB Response";  copy higher-layer response bytes into Java
          // object;  the public API, IsoDep.getHiLayerResponse(), returns this
          // data;
          if (activationData.activate_ntf.intf_param.type ==
              NFC_INTERFACE_ISO_DEP) {
            tNFC_INTF_PB_ISO_DEP& pb_iso =
                activationData.activate_ntf.intf_param.intf_param.pb_iso;
            DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
                "%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn,
                pb_iso.hi_info_len);
            actBytes.reset(e->NewByteArray(pb_iso.hi_info_len));
            if (pb_iso.hi_info_len > 0)
              e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len,
                                    (jbyte*)(pb_iso.hi_info));
          } else {
            LOG(ERROR) << StringPrintf(
                "%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn,
                activationData.activate_ntf.intf_param.type);
            actBytes.reset(e->NewByteArray(0));
          }
        }
      } else if (mTechList[i] ==
                 TARGET_TYPE_ISO14443_3A)  // is TagTechnology.NFC_A by Java API
      {
        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: T4T; tech A", fn);
        actBytes.reset(e->NewByteArray(1));
        e->SetByteArrayRegion(actBytes.get(), 0, 1,
                              (jbyte*)&mTechParams[i].param.pa.sel_rsp);
      } else {
        actBytes.reset(e->NewByteArray(0));
      }
    }  // case NFC_PROTOCOL_ISO_DEP: //t4t
    else if (NFC_PROTOCOL_T5T == mTechLibNfcTypes[i]) {
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: tech iso 15693", fn);
      // iso 15693 response flags: 1 octet
      // iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
      // used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
      uint8_t data[2] = {activationData.params.i93.afi,
                         activationData.params.i93.dsfid};
      actBytes.reset(e->NewByteArray(2));
      e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte*)data);
    } else {
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: tech unknown ????", fn);
      actBytes.reset(e->NewByteArray(0));
    }
    e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
  }  // for: every technology in the array
  jfieldID f = e->GetFieldID(tag_cls, "mTechActBytes", "[[B");
  e->SetObjectField(tag, f, techActBytes.get());
}

/*******************************************************************************
**
** Function:        fillNativeNfcTagMembers5
**
** Description:     Fill NativeNfcTag's members: mUid.
**                  The original Google's implementation is in
*nfc_jni_Discovery_notification_callback()
**                  in com_android_nfc_NativeNfcManager.cpp;
**                  e: JVM environment.
**                  tag_cls: Java NativeNfcTag class.
**                  tag: Java NativeNfcTag object.
**                  activationData: data from activation.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::fillNativeNfcTagMembers5(JNIEnv* e, jclass tag_cls, jobject tag,
                                      tNFA_ACTIVATED& activationData) {
  static const char fn[] = "NfcTag::fillNativeNfcTagMembers5";
  int len = 0;
  ScopedLocalRef<jbyteArray> uid(e, NULL);

  if (NFC_DISCOVERY_TYPE_POLL_KOVIO == mTechParams[0].mode) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: Kovio", fn);
    len = mTechParams[0].param.pk.uid_len;
    uid.reset(e->NewByteArray(len));
    e->SetByteArrayRegion(uid.get(), 0, len,
                          (jbyte*)&mTechParams[0].param.pk.uid);
  } else if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams[0].mode) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech A", fn);
    len = mTechParams[0].param.pa.nfcid1_len;
    uid.reset(e->NewByteArray(len));
    e->SetByteArrayRegion(uid.get(), 0, len,
                          (jbyte*)&mTechParams[0].param.pa.nfcid1);
    // a tag's NFCID1 can change dynamically at each activation;
    // only the first byte (0x08) is constant; a dynamic NFCID1's length
    // must be 4 bytes (see NFC Digitial Protocol,
    // section 4.7.2 SDD_RES Response, Requirements 20).
    mIsDynamicTagId = (mTechParams[0].param.pa.nfcid1_len == 4) &&
                      (mTechParams[0].param.pa.nfcid1[0] == 0x08);
  } else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams[0].mode) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech B", fn);
    uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN));
    e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN,
                          (jbyte*)&mTechParams[0].param.pb.nfcid0);
  } else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams[0].mode) {
    uid.reset(e->NewByteArray(NFC_NFCID2_LEN));
    e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN,
                          (jbyte*)&mTechParams[0].param.pf.nfcid2);
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech F", fn);
  } else if (NFC_DISCOVERY_TYPE_POLL_V == mTechParams[0].mode ||
             NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams[0].mode) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: tech iso 15693", fn);
    jbyte data[I93_UID_BYTE_LEN];               // 8 bytes
    for (int i = 0; i < I93_UID_BYTE_LEN; ++i)  // reverse the ID
      data[i] = activationData.params.i93.uid[I93_UID_BYTE_LEN - i - 1];
    uid.reset(e->NewByteArray(I93_UID_BYTE_LEN));
    e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data);
  } else {
    LOG(ERROR) << StringPrintf("%s: tech unknown ????", fn);
    uid.reset(e->NewByteArray(0));
  }
  jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B");
  e->SetObjectField(tag, f, uid.get());
}

/*******************************************************************************
**
** Function:        isP2pDiscovered
**
** Description:     Does the peer support P2P?
**
** Returns:         True if the peer supports P2P.
**
*******************************************************************************/
bool NfcTag::isP2pDiscovered() {
  static const char fn[] = "NfcTag::isP2pDiscovered";
  bool retval = false;

  for (int i = 0; i < mNumTechList; i++) {
    if (mTechLibNfcTypes[i] == NFA_PROTOCOL_NFC_DEP) {
      // if remote device supports P2P
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("%s: discovered P2P", fn);
      retval = true;
      break;
    }
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
  return retval;
}

/*******************************************************************************
**
** Function:        selectP2p
**
** Description:     Select the preferred P2P technology if there is a choice.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::selectP2p() {
  static const char fn[] = "NfcTag::selectP2p";
  uint8_t rfDiscoveryId = 0;

  for (int i = 0; i < mNumTechList; i++) {
    // if remote device does not support P2P, just skip it
    if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP) continue;

    // if remote device supports tech F;
    // tech F is preferred because it is faster than tech A
    if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F) ||
        (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
      rfDiscoveryId = mTechHandles[i];
      break;  // no need to search further
    } else if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
               (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE)) {
      // only choose tech A if tech F is unavailable
      if (rfDiscoveryId == 0) rfDiscoveryId = mTechHandles[i];
    }
  }

  if (rfDiscoveryId > 0) {
    DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
        "%s: select P2P; target rf discov id=0x%X", fn, rfDiscoveryId);
    tNFA_STATUS stat =
        NFA_Select(rfDiscoveryId, NFA_PROTOCOL_NFC_DEP, NFA_INTERFACE_NFC_DEP);
    if (stat != NFA_STATUS_OK)
      LOG(ERROR) << StringPrintf("%s: fail select P2P; error=0x%X", fn, stat);
  } else
    LOG(ERROR) << StringPrintf("%s: cannot find P2P", fn);
  resetTechnologies();
}

/*******************************************************************************
**
** Function:        resetTechnologies
**
** Description:     Clear all data related to the technology, protocol of the
*tag.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::resetTechnologies() {
  static const char fn[] = "NfcTag::resetTechnologies";
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
  mNumTechList = 0;
  memset(mTechList, 0, sizeof(mTechList));
  memset(mTechHandles, 0, sizeof(mTechHandles));
  memset(mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
  memset(mTechParams, 0, sizeof(mTechParams));
  mIsDynamicTagId = false;
  mIsFelicaLite = false;
  resetAllTransceiveTimeouts();
}

/*******************************************************************************
**
** Function:        selectFirstTag
**
** Description:     When multiple tags are discovered, just select the first one
*to activate.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::selectFirstTag() {
  static const char fn[] = "NfcTag::selectFirstTag";
  int foundIdx = -1;
  tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;

  for (int i = 0; i < mNumTechList; i++) {
    DLOG_IF(INFO, nfc_debug_enabled)
        << StringPrintf("%s: nfa target idx=%d h=0x%X; protocol=0x%X", fn, i,
                        mTechHandles[i], mTechLibNfcTypes[i]);
    if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP) {
      foundIdx = i;
      break;
    }
  }

  if (foundIdx != -1) {
    if (mTechLibNfcTypes[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
      rf_intf = NFA_INTERFACE_ISO_DEP;
    } else if (mTechLibNfcTypes[foundIdx] == NFC_PROTOCOL_MIFARE) {
      rf_intf = NFA_INTERFACE_MIFARE;
    } else
      rf_intf = NFA_INTERFACE_FRAME;

    tNFA_STATUS stat =
        NFA_Select(mTechHandles[foundIdx], mTechLibNfcTypes[foundIdx], rf_intf);
    if (stat != NFA_STATUS_OK)
      LOG(ERROR) << StringPrintf("%s: fail select; error=0x%X", fn, stat);
  } else
    LOG(ERROR) << StringPrintf("%s: only found NFC-DEP technology.", fn);
}

/*******************************************************************************
**
** Function:        getT1tMaxMessageSize
**
** Description:     Get the maximum size (octet) that a T1T can store.
**
** Returns:         Maximum size in octets.
**
*******************************************************************************/
int NfcTag::getT1tMaxMessageSize() {
  static const char fn[] = "NfcTag::getT1tMaxMessageSize";

  if (mProtocol != NFC_PROTOCOL_T1T) {
    LOG(ERROR) << StringPrintf("%s: wrong protocol %u", fn, mProtocol);
    return 0;
  }
  return mtT1tMaxMessageSize;
}

/*******************************************************************************
**
** Function:        calculateT1tMaxMessageSize
**
** Description:     Calculate type-1 tag's max message size based on header ROM
*bytes.
**                  activate: reference to activation data.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::calculateT1tMaxMessageSize(tNFA_ACTIVATED& activate) {
  static const char fn[] = "NfcTag::calculateT1tMaxMessageSize";

  // make sure the tag is type-1
  if (activate.activate_ntf.protocol != NFC_PROTOCOL_T1T) {
    mtT1tMaxMessageSize = 0;
    return;
  }

  // examine the first byte of header ROM bytes
  switch (activate.params.t1t.hr[0]) {
    case RW_T1T_IS_TOPAZ96:
      mtT1tMaxMessageSize = 90;
      break;
    case RW_T1T_IS_TOPAZ512:
      mtT1tMaxMessageSize = 462;
      break;
    default:
      LOG(ERROR) << StringPrintf("%s: unknown T1T HR0=%u", fn,
                                 activate.params.t1t.hr[0]);
      mtT1tMaxMessageSize = 0;
      break;
  }
}

/*******************************************************************************
**
** Function:        isMifareUltralight
**
** Description:     Whether the currently activated tag is Mifare Ultralight.
**
** Returns:         True if tag is Mifare Ultralight.
**
*******************************************************************************/
bool NfcTag::isMifareUltralight() {
  static const char fn[] = "NfcTag::isMifareUltralight";
  bool retval = false;

  for (int i = 0; i < mNumTechList; i++) {
    if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
      // see NFC Digital Protocol, section 4.6.3 (SENS_RES); section 4.8.2
      // (SEL_RES).  see "MF0ICU1 Functional specification MIFARE Ultralight",
      // Rev. 3.4 - 4 February 2008,  section 6.7.
      if ((mTechParams[i].param.pa.sens_res[0] == 0x44) &&
          (mTechParams[i].param.pa.sens_res[1] == 0) &&
          ((mTechParams[i].param.pa.sel_rsp == 0) ||
           (mTechParams[i].param.pa.sel_rsp == 0x04)) &&
          (mTechParams[i].param.pa.nfcid1[0] == 0x04)) {
        retval = true;
      }
      break;
    }
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
  return retval;
}

/*******************************************************************************
**
** Function:        isMifareDESFire
**
** Description:     Whether the currently activated tag is Mifare DESFire.
**
** Returns:         True if tag is Mifare DESFire.
**
*******************************************************************************/
bool NfcTag::isMifareDESFire() {
  static const char fn[] = "NfcTag::isMifareDESFire";
  bool retval = false;

  for (int i = 0; i < mNumTechList; i++) {
    if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
        (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
        (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
      /* DESfire has one sak byte and 2 ATQA bytes */
      if ((mTechParams[i].param.pa.sens_res[0] == 0x44) &&
          (mTechParams[i].param.pa.sens_res[1] == 0x03) &&
          (mTechParams[i].param.pa.sel_rsp == 0x20)) {
        retval = true;
      }
      break;
    }
  }

  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
  return retval;
}

/*******************************************************************************
**
** Function:        isFelicaLite
**
** Description:     Whether the currently activated tag is Felica Lite.
**
** Returns:         True if tag is Felica Lite.
**
*******************************************************************************/

bool NfcTag::isFelicaLite() { return mIsFelicaLite; }

/*******************************************************************************
**
** Function:        isT2tNackResponse
**
** Description:     Whether the response is a T2T NACK response.
**                  See NFC Digital Protocol Technical Specification
*(2010-11-17).
**                  Chapter 9 (Type 2 Tag Platform), section 9.6 (READ).
**                  response: buffer contains T2T response.
**                  responseLen: length of the response.
**
** Returns:         True if the response is NACK
**
*******************************************************************************/
bool NfcTag::isT2tNackResponse(const uint8_t* response, uint32_t responseLen) {
  static const char fn[] = "NfcTag::isT2tNackResponse";
  bool isNack = false;

  if (responseLen == 1) {
    if (response[0] == 0xA)
      isNack = false;  // an ACK response, so definitely not a NACK
    else
      isNack = true;  // assume every value is a NACK
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return %u", fn, isNack);
  return isNack;
}

/*******************************************************************************
**
** Function:        isNdefDetectionTimedOut
**
** Description:     Whether NDEF-detection algorithm timed out.
**
** Returns:         True if NDEF-detection algorithm timed out.
**
*******************************************************************************/
bool NfcTag::isNdefDetectionTimedOut() { return mNdefDetectionTimedOut; }

/*******************************************************************************
**
** Function:        connectionEventHandler
**
** Description:     Handle connection-related events.
**                  event: event code.
**                  data: pointer to event data.
**
** Returns:         None
**
*******************************************************************************/
void NfcTag::connectionEventHandler(uint8_t event, tNFA_CONN_EVT_DATA* data) {
  static const char fn[] = "NfcTag::connectionEventHandler";

  switch (event) {
    case NFA_DISC_RESULT_EVT: {
      tNFA_DISC_RESULT& disc_result = data->disc_result;
      if (disc_result.status == NFA_STATUS_OK) {
        discoverTechnologies(disc_result);
      }
    } break;

    case NFA_ACTIVATED_EVT:
      // Only do tag detection if we are polling and it is not 'EE Direct RF'
      // activation (which may happen when we are activated as a tag).
      if (data->activated.activate_ntf.rf_tech_param.mode <
              NCI_DISCOVERY_TYPE_LISTEN_A &&
          data->activated.activate_ntf.intf_param.type !=
              NFC_INTERFACE_EE_DIRECT_RF) {
        tNFA_ACTIVATED& activated = data->activated;
        if (IsSameKovio(activated)) break;
        mIsActivated = true;
        mProtocol = activated.activate_ntf.protocol;
        calculateT1tMaxMessageSize(activated);
        discoverTechnologies(activated);
        createNativeNfcTag(activated);
      }
      break;

    case NFA_DEACTIVATED_EVT:
      mIsActivated = false;
      mProtocol = NFC_PROTOCOL_UNKNOWN;
      resetTechnologies();
      break;

    case NFA_READ_CPLT_EVT: {
      SyncEventGuard g(mReadCompleteEvent);
      mReadCompletedStatus = data->status;
      mNdefDetectionTimedOut = data->status != NFA_STATUS_OK;
      if (mNdefDetectionTimedOut)
        LOG(ERROR) << StringPrintf("%s: NDEF detection timed out", fn);
      mReadCompleteEvent.notifyOne();
    } break;

    case NFA_NDEF_DETECT_EVT: {
      tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect;
      mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT;
      if (mNdefDetectionTimedOut)
        LOG(ERROR) << StringPrintf("%s: NDEF detection timed out", fn);
    }
  }
}

/*******************************************************************************
**
** Function         setActive
**
** Description      Sets the active state for the object
**
** Returns          None.
**
*******************************************************************************/
void NfcTag::setActive(bool active) { mIsActivated = active; }

/*******************************************************************************
**
** Function:        isDynamicTagId
**
** Description:     Whether a tag has a dynamic tag ID.
**
** Returns:         True if ID is dynamic.
**
*******************************************************************************/
bool NfcTag::isDynamicTagId() {
  return mIsDynamicTagId &&
         (mTechList[0] == TARGET_TYPE_ISO14443_4) &&  // type-4 tag
         (mTechList[1] == TARGET_TYPE_ISO14443_3A);   // tech A
}

/*******************************************************************************
**
** Function:        resetAllTransceiveTimeouts
**
** Description:     Reset all timeouts for all technologies to default values.
**
** Returns:         none
**
*******************************************************************************/
void NfcTag::resetAllTransceiveTimeouts() {
  mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_3A] = 618;   // NfcA
  mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_3B] = 1000;  // NfcB
  mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_4] = 618;    // ISO-DEP
  mTechnologyTimeoutsTable[TARGET_TYPE_FELICA] = 255;        // Felica
  mTechnologyTimeoutsTable[TARGET_TYPE_V] = 1000;            // NfcV
  mTechnologyTimeoutsTable[TARGET_TYPE_NDEF] = 1000;
  mTechnologyTimeoutsTable[TARGET_TYPE_NDEF_FORMATABLE] = 1000;
  mTechnologyTimeoutsTable[TARGET_TYPE_MIFARE_CLASSIC] = 618;  // MifareClassic
  mTechnologyTimeoutsTable[TARGET_TYPE_MIFARE_UL] = 618;  // MifareUltralight
  mTechnologyTimeoutsTable[TARGET_TYPE_KOVIO_BARCODE] = 1000;  // NfcBarcode
}

/*******************************************************************************
**
** Function:        getTransceiveTimeout
**
** Description:     Get the timeout value for one technology.
**                  techId: one of the values in TARGET_TYPE_* defined in
*NfcJniUtil.h
**
** Returns:         Timeout value in millisecond.
**
*******************************************************************************/
int NfcTag::getTransceiveTimeout(int techId) {
  static const char fn[] = "NfcTag::getTransceiveTimeout";
  int retval = 1000;
  if ((techId > 0) && (techId < (int)mTechnologyTimeoutsTable.size()))
    retval = mTechnologyTimeoutsTable[techId];
  else
    LOG(ERROR) << StringPrintf("%s: invalid tech=%d", fn, techId);
  return retval;
}

/*******************************************************************************
**
** Function:        setTransceiveTimeout
**
** Description:     Set the timeout value for one technology.
**                  techId: one of the values in TARGET_TYPE_* defined in
*NfcJniUtil.h
**                  timeout: timeout value in millisecond.
**
** Returns:         Timeout value.
**
*******************************************************************************/
void NfcTag::setTransceiveTimeout(int techId, int timeout) {
  static const char fn[] = "NfcTag::setTransceiveTimeout";
  if ((techId >= 0) && (techId < (int)mTechnologyTimeoutsTable.size()))
    mTechnologyTimeoutsTable[techId] = timeout;
  else
    LOG(ERROR) << StringPrintf("%s: invalid tech=%d", fn, techId);
}

/*******************************************************************************
**
** Function:        getPresenceCheckAlgorithm
**
** Description:     Get presence-check algorithm from .conf file.
**
** Returns:         Presence-check algorithm.
**
*******************************************************************************/
tNFA_RW_PRES_CHK_OPTION NfcTag::getPresenceCheckAlgorithm() {
  return mPresenceCheckAlgorithm;
}

/*******************************************************************************
**
** Function:        isInfineonMyDMove
**
** Description:     Whether the currently activated tag is Infineon My-D Move.
**
** Returns:         True if tag is Infineon My-D Move.
**
*******************************************************************************/
bool NfcTag::isInfineonMyDMove() {
  static const char fn[] = "NfcTag::isInfineonMyDMove";
  bool retval = false;

  for (int i = 0; i < mNumTechList; i++) {
    if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
      // see Infineon my-d move, my-d move NFC, SLE 66R01P, SLE 66R01PN,
      // Short Product Information, 2011-11-24, section 3.5
      if (mTechParams[i].param.pa.nfcid1[0] == 0x05) {
        uint8_t highNibble = mTechParams[i].param.pa.nfcid1[1] & 0xF0;
        if (highNibble == 0x30) retval = true;
      }
      break;
    }
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
  return retval;
}

/*******************************************************************************
**
** Function:        isKovioType2Tag
**
** Description:     Whether the currently activated tag is Kovio Type-2 tag.
**
** Returns:         True if tag is Kovio Type-2 tag.
**
*******************************************************************************/
bool NfcTag::isKovioType2Tag() {
  static const char fn[] = "NfcTag::isKovioType2Tag";
  bool retval = false;

  for (int i = 0; i < mNumTechList; i++) {
    if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
      // Kovio 2Kb RFID Tag, Functional Specification,
      // March 2, 2012, v2.0, section 8.3.
      if (mTechParams[i].param.pa.nfcid1[0] == 0x37) retval = true;
      break;
    }
  }
  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
  return retval;
}
