/*
 * Copyright (C) 2015 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.
 */

#include <android-base/stringprintf.h>
#include <base/logging.h>
#include <log/log.h>
#include <nfc_api.h>
#include <nfc_int.h>
#include <phNfcCompId.h>
#include <phNxpExtns_MifareStd.h>
#include <rw_api.h>

using android::base::StringPrintf;

extern bool nfc_debug_enabled;

phNxpExtns_Context_t gphNxpExtns_Context;
phNciNfc_TransceiveInfo_t tNciTranscvInfo;
phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt = NULL;
phFriNfc_NdefMap_t* NdefMap = NULL;
phLibNfc_NdefInfo_t NdefInfo;
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
pthread_mutex_t SharedDataMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
uint8_t current_key[6] = {0};
phNci_mfc_auth_cmd_t gAuthCmdBuf;
static NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo,
                                    uint8_t* buff, uint16_t* buffSz);
static NFCSTATUS phLibNfc_SendRawCmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf);
static NFCSTATUS phLibNfc_SendWrt16Cmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf);
static NFCSTATUS phLibNfc_SendAuthCmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    phNciNfc_TransceiveInfo_t* tNciTranscvInfo) __attribute__((unused));
static NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType,
                                  phNfc_sTransceiveInfo_t* pTransceiveInfo,
                                  pphNciNfc_TransceiveInfo_t pMappedTranscvIf);
static NFCSTATUS phLibNfc_MifareMap(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf);
static NFCSTATUS phLibNfc_ChkAuthCmdMFC(
    phNfc_sTransceiveInfo_t* pTransceiveInfo, uint8_t* bKey);
static NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t* buffer, uint8_t* bKey);
static void phLibNfc_CalSectorAddress(uint8_t* Sector_Address);
static NFCSTATUS phNciNfc_MfCreateAuthCmdHdr(
    phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t bBlockAddr, uint8_t* buff,
    uint16_t* buffSz);
static NFCSTATUS phNciNfc_MfCreateXchgDataHdr(
    phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t* buff, uint16_t* buffSz);
static NFCSTATUS phLibNfc_SendWrt16CmdPayload(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf);
static NFCSTATUS phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo,
                                     NFCSTATUS wStatus);
static NFCSTATUS nativeNfcExtns_doTransceive(uint8_t* buff, uint16_t buffSz);
static NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(
    phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt, uint8_t* SendRecvBuffer,
    uint16_t* SendRecvBuffLen);
static NFCSTATUS phFriNfc_ValidateParams(uint8_t* PacketData,
                                         uint32_t* PacketDataLength,
                                         uint8_t Offset,
                                         phFriNfc_NdefMap_t* pNdefMap,
                                         uint8_t bNdefReq);
static void Mfc_FormatNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status);
static void Mfc_WriteNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status);
static void Mfc_ReadNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status);
static void Mfc_CheckNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status);

/*******************************************************************************
**
** Function         phNxpExtns_MfcModuleDeInit
**
** Description      It Deinitializes the Mifare module.
**
**                  Frees all the memory occupied by Mifare module
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully deinitialize
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS phNxpExtns_MfcModuleDeInit(void) {
  NFCSTATUS status = NFCSTATUS_FAILED;

  if (NdefMap != NULL) {
    if (NdefMap->psRemoteDevInfo != NULL) {
      free(NdefMap->psRemoteDevInfo);
      NdefMap->psRemoteDevInfo = NULL;
    }
    if (NdefMap->SendRecvBuf != NULL) {
      free(NdefMap->SendRecvBuf);
      NdefMap->SendRecvBuf = NULL;
    }
    if (NdefMap->SendRecvLength != NULL) {
      free(NdefMap->SendRecvLength);
      NdefMap->SendRecvLength = NULL;
    }
    if (NdefMap->DataCount != NULL) {
      free(NdefMap->DataCount);
      NdefMap->DataCount = NULL;
    }
    if (NdefMap->pTransceiveInfo != NULL) {
      if (NdefMap->pTransceiveInfo->sSendData.buffer != NULL) {
        free(NdefMap->pTransceiveInfo->sSendData.buffer);
        NdefMap->pTransceiveInfo->sSendData.buffer = NULL;
      }
      if (NdefMap->pTransceiveInfo->sRecvData.buffer != NULL) {
        free(NdefMap->pTransceiveInfo->sRecvData.buffer);
        NdefMap->pTransceiveInfo->sRecvData.buffer = NULL;
      }
      free(NdefMap->pTransceiveInfo);
      NdefMap->pTransceiveInfo = NULL;
    }

    free(NdefMap);
    NdefMap = NULL;
  }

  if (tNciTranscvInfo.tSendData.pBuff != NULL) {
    free(tNciTranscvInfo.tSendData.pBuff);
    tNciTranscvInfo.tSendData.pBuff = NULL;
  }

  if (NdefSmtCrdFmt != NULL) {
    free(NdefSmtCrdFmt);
    NdefSmtCrdFmt = NULL;
  }
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_lock(&SharedDataMutex);
#endif
  if (NULL != NdefInfo.psUpperNdefMsg) {
    free(NdefInfo.psUpperNdefMsg);
    NdefInfo.psUpperNdefMsg = NULL;
  }
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_unlock(&SharedDataMutex);
#endif
  if (NULL != gAuthCmdBuf.pauth_cmd) {
    if (NULL != gAuthCmdBuf.pauth_cmd->buffer) {
      free(gAuthCmdBuf.pauth_cmd->buffer);
      gAuthCmdBuf.pauth_cmd->buffer = NULL;
    }
    free(gAuthCmdBuf.pauth_cmd);
    gAuthCmdBuf.pauth_cmd = NULL;
  }
  status = NFCSTATUS_SUCCESS;
  return status;
}

/*******************************************************************************
**
** Function         phNxpExtns_MfcModuleInit
**
** Description      It Initializes the memroy and global variables related
**                  to Mifare module.
**
**                  Reset all the global variables and allocate memory for
*Mifare module
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully deinitialize
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS phNxpExtns_MfcModuleInit(void) {
  NFCSTATUS status = NFCSTATUS_FAILED;
  gphNxpExtns_Context.writecmdFlag = false;
  gphNxpExtns_Context.RawWriteCallBack = false;
  gphNxpExtns_Context.CallBackCtxt = NULL;
  gphNxpExtns_Context.CallBackMifare = NULL;
  gphNxpExtns_Context.ExtnsConnect = false;
  gphNxpExtns_Context.ExtnsDeactivate = false;
  gphNxpExtns_Context.ExtnsCallBack = false;

  NdefMap = (phFriNfc_NdefMap_t*)malloc(sizeof(phFriNfc_NdefMap_t));
  if (NULL == NdefMap) {
    goto clean_and_return;
  }
  memset(NdefMap, 0, sizeof(phFriNfc_NdefMap_t));

  NdefMap->psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)malloc(
      sizeof(phLibNfc_sRemoteDevInformation_t));
  if (NULL == NdefMap->psRemoteDevInfo) {
    goto clean_and_return;
  }
  memset(NdefMap->psRemoteDevInfo, 0, sizeof(phLibNfc_sRemoteDevInformation_t));

  NdefMap->SendRecvBuf = (uint8_t*)malloc((uint32_t)(MAX_BUFF_SIZE * 2));
  if (NULL == NdefMap->SendRecvBuf) {
    goto clean_and_return;
  }
  memset(NdefMap->SendRecvBuf, 0, (MAX_BUFF_SIZE * 2));

  NdefMap->SendRecvLength = (uint16_t*)malloc(sizeof(uint16_t));
  if (NULL == NdefMap->SendRecvLength) {
    goto clean_and_return;
  }
  memset(NdefMap->SendRecvLength, 0, sizeof(uint16_t));

  NdefMap->DataCount = (uint16_t*)malloc(sizeof(uint16_t));
  if (NULL == NdefMap->DataCount) {
    goto clean_and_return;
  }
  memset(NdefMap->DataCount, 0, sizeof(uint16_t));

  NdefMap->pTransceiveInfo =
      (phNfc_sTransceiveInfo_t*)malloc(sizeof(phNfc_sTransceiveInfo_t));
  if (NULL == NdefMap->pTransceiveInfo) {
    goto clean_and_return;
  }
  memset(NdefMap->pTransceiveInfo, 0, sizeof(phNfc_sTransceiveInfo_t));

  tNciTranscvInfo.tSendData.pBuff = (uint8_t*)malloc((uint32_t)MAX_BUFF_SIZE);
  if (NULL == tNciTranscvInfo.tSendData.pBuff) {
    goto clean_and_return;
  }
  memset(tNciTranscvInfo.tSendData.pBuff, 0, MAX_BUFF_SIZE);

  NdefMap->pTransceiveInfo->sSendData.buffer =
      (uint8_t*)malloc((uint32_t)MAX_BUFF_SIZE);
  if (NdefMap->pTransceiveInfo->sSendData.buffer == NULL) {
    goto clean_and_return;
  }
  memset(NdefMap->pTransceiveInfo->sSendData.buffer, 0, MAX_BUFF_SIZE);
  NdefMap->pTransceiveInfo->sSendData.length = MAX_BUFF_SIZE;

  NdefMap->pTransceiveInfo->sRecvData.buffer = (uint8_t*)malloc(
      (uint32_t)MAX_BUFF_SIZE); /* size should be same as sRecvData */
  if (NdefMap->pTransceiveInfo->sRecvData.buffer == NULL) {
    goto clean_and_return;
  }
  memset(NdefMap->pTransceiveInfo->sRecvData.buffer, 0, MAX_BUFF_SIZE);
  NdefMap->pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;

  NdefSmtCrdFmt =
      (phFriNfc_sNdefSmtCrdFmt_t*)malloc(sizeof(phFriNfc_sNdefSmtCrdFmt_t));
  if (NdefSmtCrdFmt == NULL) {
    goto clean_and_return;
  }
  memset(NdefSmtCrdFmt, 0, sizeof(phFriNfc_sNdefSmtCrdFmt_t));
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_lock(&SharedDataMutex);
#endif
  NdefInfo.psUpperNdefMsg = (phNfc_sData_t*)malloc(sizeof(phNfc_sData_t));
  if (NULL == NdefInfo.psUpperNdefMsg) {
    goto clean_and_return;
  }
  memset(NdefInfo.psUpperNdefMsg, 0, sizeof(phNfc_sData_t));
  memset(&gAuthCmdBuf, 0, sizeof(phNci_mfc_auth_cmd_t));
  gAuthCmdBuf.pauth_cmd = (phNfc_sData_t*)malloc(sizeof(phNfc_sData_t));
  if (NULL == gAuthCmdBuf.pauth_cmd) {
    goto clean_and_return;
  }
  gAuthCmdBuf.pauth_cmd->buffer = (uint8_t*)malloc((uint32_t)NCI_MAX_DATA_LEN);
  if (NULL == gAuthCmdBuf.pauth_cmd->buffer) {
    goto clean_and_return;
  }
  status = NFCSTATUS_SUCCESS;

clean_and_return:
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_unlock(&SharedDataMutex);
#endif
  if (status != NFCSTATUS_SUCCESS) {
    LOG(ERROR) << StringPrintf("CRIT: Memory Allocation failed for MFC!");
    phNxpExtns_MfcModuleDeInit();
  }
  return status;
}

/*******************************************************************************
**
** Function         Mfc_CheckNdef
**
** Description      It triggers NDEF detection for Mifare Classic Tag.
**
**
** Returns          NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_CheckNdef(void) {
  NFCSTATUS status = NFCSTATUS_FAILED;

  EXTNS_SetCallBackFlag(false);
  /* Set Completion Routine for CheckNdef */
  NdefMap->CompletionRoutine[0].CompletionRoutine =
      Mfc_CheckNdef_Completion_Routine;

  gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
  gphNxpExtns_Context.CallBackCtxt = NdefMap;
  status = phFriNfc_MifareStdMap_H_Reset(NdefMap);
  if (NFCSTATUS_SUCCESS == status) {
    status = phFriNfc_MifareStdMap_ChkNdef(NdefMap);
    if (status == NFCSTATUS_PENDING) {
      status = NFCSTATUS_SUCCESS;
    }
  }
  if (status != NFCSTATUS_SUCCESS) {
    status = NFCSTATUS_FAILED;
  }

  return status;
}

/*******************************************************************************
**
** Function         Mfc_CheckNdef_Completion_Routine
**
** Description      Notify NDEF detection for Mifare Classic Tag to JNI
**
**                  Upon completion of NDEF detection, a
**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
**                  of the NDEF attributes (NDEF total memory size, current
**                  size, etc.).
**
** Returns:         void
**
*******************************************************************************/
static void Mfc_CheckNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status) {
  (void)NdefCtxt;
  tNFA_CONN_EVT_DATA conn_evt_data;

  conn_evt_data.ndef_detect.status = status;
  if (NFCSTATUS_SUCCESS == status) {
    /* NDef Tag Detected */
    conn_evt_data.ndef_detect.protocol = NFC_PROTOCOL_MIFARE;
    phFrinfc_MifareClassic_GetContainerSize(
        NdefMap, (uint32_t*)&(conn_evt_data.ndef_detect.max_size),
        (uint32_t*)&(conn_evt_data.ndef_detect.cur_size));
    NdefInfo.NdefLength = conn_evt_data.ndef_detect.max_size;
    /* update local flags */
    NdefInfo.is_ndef = 1;
    NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size;
    if (PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState) {
      DLOG_IF(INFO, nfc_debug_enabled)
          << StringPrintf("Mfc_CheckNdef_Completion_Routine : READ_ONLY_CARD");
      conn_evt_data.ndef_detect.flags = RW_NDEF_FL_READ_ONLY;
    } else {
      conn_evt_data.ndef_detect.flags =
          RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
    }
  } else {
    /* NDEF Detection failed for other reasons */
    conn_evt_data.ndef_detect.cur_size = 0;
    conn_evt_data.ndef_detect.max_size = 0;
    conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;

    /* update local flags */
    NdefInfo.is_ndef = 0;
    NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size;
  }
  (*gphNxpExtns_Context.p_conn_cback)(NFA_NDEF_DETECT_EVT, &conn_evt_data);

  return;
}
/*******************************************************************************
**
** Function         Mfc_ReadNdef_Completion_Routine
**
** Description      Notify NDEF read completion for Mifare Classic Tag to JNI
**
**                  Upon completion of NDEF read, a
**                  NFA_READ_CPLT_EVT will be sent, to notify the application
**                  with the NDEF data and status
**
** Returns:         void
**
*******************************************************************************/
static void Mfc_ReadNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status) {
  (void)NdefCtxt;
  tNFA_CONN_EVT_DATA conn_evt_data;
  tNFA_NDEF_EVT_DATA p_data;

  conn_evt_data.status = status;
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_lock(&SharedDataMutex);
#endif
  if (NFCSTATUS_SUCCESS == status) {
    p_data.ndef_data.len = NdefInfo.psUpperNdefMsg->length;
    p_data.ndef_data.p_data = NdefInfo.psUpperNdefMsg->buffer;
    (*gphNxpExtns_Context.p_ndef_cback)(NFA_NDEF_DATA_EVT, &p_data);
  } else {
  }

  (*gphNxpExtns_Context.p_conn_cback)(NFA_READ_CPLT_EVT, &conn_evt_data);

  if (NdefInfo.psUpperNdefMsg->buffer != NULL) {
    free(NdefInfo.psUpperNdefMsg->buffer);
    NdefInfo.psUpperNdefMsg->buffer = NULL;
  }
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_unlock(&SharedDataMutex);
#endif
  return;
}

/*******************************************************************************
**
** Function         Mfc_WriteNdef_Completion_Routine
**
** Description      Notify NDEF write completion for Mifare Classic Tag to JNI
**
**                  Upon completion of NDEF write, a
**                  NFA_WRITE_CPLT_EVT will be sent along with status
**
** Returns:         void
**
*******************************************************************************/
static void Mfc_WriteNdef_Completion_Routine(void* NdefCtxt, NFCSTATUS status) {
  (void)NdefCtxt;
  tNFA_CONN_EVT_DATA conn_evt_data;

  conn_evt_data.status = status;
  (*gphNxpExtns_Context.p_conn_cback)(NFA_WRITE_CPLT_EVT, &conn_evt_data);

  return;
}

/*******************************************************************************
**
** Function         Mfc_FormatNdef_Completion_Routine
**
** Description      Notify NDEF format completion for Mifare Classic Tag to JNI
**
**                  Upon completion of NDEF format, a
**                  NFA_FORMAT_CPLT_EVT will be sent along with status
**
** Returns:         void
**
*******************************************************************************/
static void Mfc_FormatNdef_Completion_Routine(void* NdefCtxt,
                                              NFCSTATUS status) {
  (void)NdefCtxt;
  tNFA_CONN_EVT_DATA conn_evt_data;

  conn_evt_data.status = status;
  (*gphNxpExtns_Context.p_conn_cback)(NFA_FORMAT_CPLT_EVT, &conn_evt_data);

  return;
}

/*******************************************************************************
**
** Function          phFriNfc_ValidateParams
**
** Description      This function is a common function which validates NdefRd
**                  and NdefWr parameters.
**
** Returns          NFCSTATUS_SUCCESS  - All the params are valid
**                  NFCSTATUS_FAILED   - otherwise
**
*******************************************************************************/
static NFCSTATUS phFriNfc_ValidateParams(uint8_t* PacketData,
                                         uint32_t* PacketDataLength,
                                         uint8_t Offset,
                                         phFriNfc_NdefMap_t* pNdefMap,
                                         uint8_t bNdefReq) {
  if ((pNdefMap == NULL) || (PacketData == NULL) ||
      (PacketDataLength == NULL)) {
    return NFCSTATUS_FAILED;
  }

  if (pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) {
    return NFCSTATUS_FAILED;
  }

  if (bNdefReq == PH_FRINFC_NDEF_READ_REQ) {
    if ((Offset != PH_FRINFC_NDEFMAP_SEEK_CUR) &&
        (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN)) {
      return NFCSTATUS_FAILED;
    }
    if (pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED) {
      pNdefMap->NumOfBytesRead = PacketDataLength;
      *pNdefMap->NumOfBytesRead = 0;
      return NFCSTATUS_EOF_NDEF_CONTAINER_REACHED;
    }
    if ((pNdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) &&
        (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN)) {
      return NFCSTATUS_FAILED; /* return INVALID_DEVICE_REQUEST */
    }
    if (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) {
      pNdefMap->ApduBuffIndex = 0;
      *pNdefMap->DataCount = 0;
    } else if ((pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
               (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_CUR)) {
    } else {
      return NFCSTATUS_FAILED;
    }
  } else if (bNdefReq == PH_FRINFC_NDEF_WRITE_REQ) {
    if (pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) {
      pNdefMap->WrNdefPacketLength = PacketDataLength;
      *pNdefMap->WrNdefPacketLength = 0x00;
      return NFCSTATUS_NOT_ALLOWED;
    }
  }

  return NFCSTATUS_SUCCESS;
}

/*******************************************************************************
**
** Function         Mfc_SetRdOnly_Completion_Routine
**
** Description      Notify NDEF read only completion for Mifare Classic Tag to
*JNI
**
**                  Upon completion of NDEF format, a
**                  NFA_SET_TAG_RO_EVT will be sent along with status
**
** Returns:         void
**
*******************************************************************************/
static void Mfc_SetRdOnly_Completion_Routine(void* NdefCtxt, NFCSTATUS status) {
  (void)NdefCtxt;
  tNFA_CONN_EVT_DATA conn_evt_data;
  LOG(ERROR) << StringPrintf("%s status = 0x%x", __func__, status);
  conn_evt_data.status = status;
  (*gphNxpExtns_Context.p_conn_cback)(NFA_SET_TAG_RO_EVT, &conn_evt_data);

  return;
}

/*******************************************************************************
**
** Function        Mfc_SetReadOnly
**
**
** Description:    It triggers ConvertToReadOnly  for Mifare Classic Tag.
**
** Returns:
**                  NFCSTATUS_SUCCESS if successfully initiated
**                  NFCSTATUS_FAILED otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_SetReadOnly(uint8_t* secrtkey, uint8_t len) {
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s Entering ", __func__);
  NFCSTATUS status = NFCSTATUS_FAILED;
  uint8_t mif_secrete_key[6] = {0};
  uint8_t id = 0;
  EXTNS_SetCallBackFlag(false);
  memcpy(mif_secrete_key, secrtkey, len);
  gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
  gphNxpExtns_Context.CallBackCtxt = NdefMap;
  for (id = 0; id < len; id++) {
    DLOG_IF(INFO, nfc_debug_enabled)
        << StringPrintf("secrtkey[%d] = 0x%x", id, secrtkey[id]);
    DLOG_IF(INFO, nfc_debug_enabled)
        << StringPrintf("mif_secrete_key[%d] = 0x%x", id, mif_secrete_key[id]);
  }
  /* Set Completion Routine for ReadNdef */
  NdefMap->CompletionRoutine[0].CompletionRoutine =
      Mfc_SetRdOnly_Completion_Routine;
  if (NdefInfo.is_ndef == 0) {
    status = NFCSTATUS_NON_NDEF_COMPLIANT;
    goto Mfc_SetRdOnly;
  } else if ((NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0)) {
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
    pthread_mutex_lock(&SharedDataMutex);
#endif
    NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
    pthread_mutex_unlock(&SharedDataMutex);
#endif
    status = NFCSTATUS_SUCCESS;
    goto Mfc_SetRdOnly;
  } else {
    status = phFriNfc_MifareStdMap_ConvertToReadOnly(NdefMap, mif_secrete_key);
  }
  if (NFCSTATUS_PENDING == status) {
    status = NFCSTATUS_SUCCESS;
  }

Mfc_SetRdOnly:
  return status;
}

/*******************************************************************************
**
** Function         Mfc_ReadNdef
**
** Description      It triggers receiving of the NDEF message from Mifare
*Classic Tag.
**
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_ReadNdef(void) {
  NFCSTATUS status = NFCSTATUS_FAILED;
  uint8_t* PacketData = NULL;
  uint32_t* PacketDataLength = NULL;
  phLibNfc_Ndef_EOffset_t Offset;

  EXTNS_SetCallBackFlag(false);

  Offset = phLibNfc_Ndef_EBegin;

  gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
  gphNxpExtns_Context.CallBackCtxt = NdefMap;
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_lock(&SharedDataMutex);
#endif
  if (NdefInfo.is_ndef == 0) {
    status = NFCSTATUS_NON_NDEF_COMPLIANT;
    goto Mfc_RdNdefEnd;
  } else if ((NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0)) {
    NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;
    status = NFCSTATUS_SUCCESS;
    goto Mfc_RdNdefEnd;
  } else {
    NdefInfo.psUpperNdefMsg->buffer = (uint8_t*)malloc(NdefInfo.NdefActualSize);
    if (NULL == NdefInfo.psUpperNdefMsg->buffer) {
      goto Mfc_RdNdefEnd;
    }
    NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;

    /* Set Completion Routine for ReadNdef */
    NdefMap->CompletionRoutine[1].CompletionRoutine =
        Mfc_ReadNdef_Completion_Routine;
    NdefInfo.NdefContinueRead = (uint8_t)((phLibNfc_Ndef_EBegin == Offset)
                                              ? PH_FRINFC_NDEFMAP_SEEK_BEGIN
                                              : PH_FRINFC_NDEFMAP_SEEK_CUR);
  }

  PacketData = NdefInfo.psUpperNdefMsg->buffer;
  PacketDataLength = (uint32_t*)&(NdefInfo.psUpperNdefMsg->length);
  NdefMap->bCurrReadMode = Offset;
  status = phFriNfc_ValidateParams(PacketData, PacketDataLength, Offset,
                                   NdefMap, PH_FRINFC_NDEF_READ_REQ);
  if (status != NFCSTATUS_SUCCESS) {
    goto Mfc_RdNdefEnd;
  }

  status = phFriNfc_MifareStdMap_RdNdef(NdefMap, PacketData, PacketDataLength,
                                        Offset);

  if (NFCSTATUS_INSUFFICIENT_STORAGE == status) {
    NdefInfo.psUpperNdefMsg->length = 0x00;
    status = NFCSTATUS_SUCCESS;
  }

  if (NFCSTATUS_PENDING == status) {
    status = NFCSTATUS_SUCCESS;
  }

Mfc_RdNdefEnd:
  if (status != NFCSTATUS_SUCCESS) {
    if (NULL != NdefInfo.psUpperNdefMsg->buffer) {
      free(NdefInfo.psUpperNdefMsg->buffer);
      NdefInfo.psUpperNdefMsg->buffer = NULL;
    }
    status = NFCSTATUS_FAILED;
  }
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_unlock(&SharedDataMutex);
#endif
  return status;
}
/*******************************************************************************
**
** Function         Mfc_PresenceCheck
**
** Description      It triggers receiving of the NDEF message from Mifare
*Classic Tag.
**
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_PresenceCheck(void) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;

  if (gAuthCmdBuf.auth_status == true) {
    EXTNS_SetCallBackFlag(false);
    status = nativeNfcExtns_doTransceive(gAuthCmdBuf.pauth_cmd->buffer,
                                         gAuthCmdBuf.pauth_cmd->length);
    if (status != NFCSTATUS_PENDING) {
      gAuthCmdBuf.auth_sent = false;
      status = NFCSTATUS_FAILED;
    } else {
      gAuthCmdBuf.auth_sent = true;
      status = NFCSTATUS_SUCCESS;
    }
  } else {
    status = NFCSTATUS_NOT_ALLOWED;
  }
  DLOG_IF(INFO, nfc_debug_enabled)
      << StringPrintf("%s status = 0x%x", __func__, status);
  return status;
}
/*******************************************************************************
**
** Function         Mfc_WriteNdef
**
** Description      It triggers the NDEF data write to Mifare Classic Tag.
**
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_WriteNdef(uint8_t* p_data, uint32_t len) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  uint8_t* PacketData = NULL;
  uint32_t* PacketDataLength = NULL;

  if (p_data == NULL || len == 0) {
    LOG(ERROR) << StringPrintf("MFC Error: Invalid Parameters to Ndef Write");
    status = NFCSTATUS_FAILED;
    goto Mfc_WrNdefEnd;
  }

  EXTNS_SetCallBackFlag(false);
  gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
  gphNxpExtns_Context.CallBackCtxt = NdefMap;
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_lock(&SharedDataMutex);
#endif
  if (NdefInfo.is_ndef == PH_LIBNFC_INTERNAL_CHK_NDEF_NOT_DONE) {
    status = NFCSTATUS_REJECTED;
    goto Mfc_WrNdefEnd;
  } else if (NdefInfo.is_ndef == 0) {
    status = NFCSTATUS_NON_NDEF_COMPLIANT;
    goto Mfc_WrNdefEnd;
  } else if (len > NdefInfo.NdefLength) {
    status = NFCSTATUS_NOT_ENOUGH_MEMORY;
    goto Mfc_WrNdefEnd;
  } else {
    NdefInfo.psUpperNdefMsg->buffer = p_data;
    NdefInfo.psUpperNdefMsg->length = len;

    NdefInfo.AppWrLength = len;
    NdefMap->CompletionRoutine[2].CompletionRoutine =
        Mfc_WriteNdef_Completion_Routine;
    if (0 == len) {
      /* TODO: Erase the Tag */
    } else {
      NdefMap->ApduBuffIndex = 0x00;
      *NdefMap->DataCount = 0x00;
      PacketData = NdefInfo.psUpperNdefMsg->buffer;
      PacketDataLength = &(NdefInfo.dwWrLength);
      NdefMap->WrNdefPacketLength = PacketDataLength;
      NdefInfo.dwWrLength = len;

      status = phFriNfc_ValidateParams(PacketData, PacketDataLength, 0, NdefMap,
                                       PH_FRINFC_NDEF_WRITE_REQ);
      if (status != NFCSTATUS_SUCCESS) {
        goto Mfc_WrNdefEnd;
      }

      status = phFriNfc_MifareStdMap_WrNdef(
          NdefMap, PacketData, PacketDataLength, PH_FRINFC_NDEFMAP_SEEK_BEGIN);

      if (status == NFCSTATUS_PENDING) {
        status = NFCSTATUS_SUCCESS;
      }
    }
  }

Mfc_WrNdefEnd:
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
  pthread_mutex_unlock(&SharedDataMutex);
#endif
  if (status != NFCSTATUS_SUCCESS) {
    status = NFCSTATUS_FAILED;
  }
  return status;
}
/*******************************************************************************
**
** Function          phFriNfc_NdefSmtCrd_Reset__
**
** Description      This function Resets the component instance to the initial
**                  state and initializes the internal variables.
**
** Returns          NFCSTATUS_SUCCESS
**
*******************************************************************************/
static NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(
    phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt, uint8_t* SendRecvBuffer,
    uint16_t* SendRecvBuffLen) {
  //    NFCSTATUS status = NFCSTATUS_FAILED;                      /*commented to
  //    eliminate unused variable warning*/
  uint8_t index;

  /* Initialize the state to Init */
  NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;

  for (index = 0; index < PH_FRINFC_SMTCRDFMT_CR; index++) {
    /* Initialize the NdefMap Completion Routine to Null */
    NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL;
    /* Initialize the NdefMap Completion Routine context to Null  */
    NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL;
  }

  /* Trx Buffer registered */
  NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer;

  /* Trx Buffer Size */
  NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen;

  /* Register Transfer Buffer Length */
  NdefSmtCrdFmt->SendLength = 0;

  /* Initialize the Format status flag*/
  NdefSmtCrdFmt->FmtProcStatus = 0;

  /* Reset the Card Type */
  NdefSmtCrdFmt->CardType = 0;

  /* Reset MapCompletion Info*/
  NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL;
  NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL;

  phFriNfc_MfStd_Reset(NdefSmtCrdFmt);

  return NFCSTATUS_SUCCESS;
}

/*******************************************************************************
**
** Function         Mfc_FormatNdef
**
** Description      It triggers the NDEF format of Mifare Classic Tag.
**
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_FormatNdef(uint8_t* secretkey, uint8_t len) {
  NFCSTATUS status = NFCSTATUS_FAILED;
  uint8_t mif_std_key[6] = {0};
  //    static uint8_t   Index;
  //    /*commented to eliminate unused variable warning*/
  uint8_t sak = 0;

  EXTNS_SetCallBackFlag(false);

  memcpy(mif_std_key, secretkey, len);
  memcpy(current_key, secretkey, len);

  if (NULL == NdefSmtCrdFmt || NULL == NdefMap ||
      NULL == NdefMap->SendRecvBuf) {
    goto Mfc_FormatEnd;
  }
  NdefSmtCrdFmt->pTransceiveInfo = NdefMap->pTransceiveInfo;

  gphNxpExtns_Context.CallBackMifare = phFriNfc_MfStd_Process;
  gphNxpExtns_Context.CallBackCtxt = NdefSmtCrdFmt;

  NdefInfo.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
  phFriNfc_NdefSmtCrd_Reset__(NdefSmtCrdFmt, NdefMap->SendRecvBuf,
                              &(NdefInfo.NdefSendRecvLen));

  /* Register Callbacks */
  NdefSmtCrdFmt->CompletionRoutine[0].CompletionRoutine =
      Mfc_FormatNdef_Completion_Routine;
  NdefSmtCrdFmt->CompletionRoutine[1].CompletionRoutine =
      Mfc_FormatNdef_Completion_Routine;
  NdefSmtCrdFmt->psRemoteDevInfo = NdefMap->psRemoteDevInfo;
  sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;

  if ((0x08 == (sak & 0x18)) || (0x18 == (sak & 0x18)) || (0x01 == sak)) {
    NdefSmtCrdFmt->CardType = (uint8_t)(
        ((sak & 0x18) == 0x08)
            ? PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD
            : (((sak & 0x19) == 0x19) ? PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD
                                      : PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD));
    status = phFriNfc_MfStd_Format(NdefSmtCrdFmt, mif_std_key);
  }

  if (NFCSTATUS_PENDING == status) {
    status = NFCSTATUS_SUCCESS;
  }

Mfc_FormatEnd:
  if (status != NFCSTATUS_SUCCESS) {
    status = NFCSTATUS_FAILED;
  }

  return status;
}

/*******************************************************************************
**
** Function         phNxNciExtns_MifareStd_Reconnect
**
** Description      This function sends the deactivate command to NFCC for
*Mifare
**
**
** Returns:
**                  NFCSTATUS_PENDING - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS phNxNciExtns_MifareStd_Reconnect(void) {
  tNFA_STATUS status;

  EXTNS_SetDeactivateFlag(true);
  if (NFA_STATUS_OK !=
      (status = NFA_Deactivate(true))) /* deactivate to sleep state */
  {
    LOG(ERROR) << StringPrintf("%s: deactivate failed, status = %d", __func__,
                               status);
    return NFCSTATUS_FAILED;
  }

  return NFCSTATUS_PENDING;
}

/*******************************************************************************
**
** Function         Mfc_DeactivateCbackSelect
**
** Description      This function select the Mifare tag
**
**
** Returns:         void
**
*******************************************************************************/
void Mfc_DeactivateCbackSelect(void) {
  tNFA_STATUS status;

  EXTNS_SetConnectFlag(true);
  if (NFA_STATUS_OK !=
      (status = NFA_Select(0x01, phNciNfc_e_RfProtocolsMifCProtocol,
                           phNciNfc_e_RfInterfacesTagCmd_RF))) {
    LOG(ERROR) << StringPrintf("%s: NFA_Select failed, status = %d", __func__,
                               status);
  }

  return;
}

/*******************************************************************************
**
** Function         Mfc_ActivateCback
**
** Description      This function invoke the callback when receive the response
**
**
** Returns:         void
**
**
*******************************************************************************/
void Mfc_ActivateCback(void) {
  gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt,
                                     NFCSTATUS_SUCCESS);
  return;
}

/*******************************************************************************
**
** Function         Mfc_Transceive
**
** Description      Sends raw frame to Mifare Classic Tag.
**
** Returns          NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_Transceive(uint8_t* p_data, uint32_t len) {
  NFCSTATUS status = NFCSTATUS_FAILED;
  uint8_t i = 0x00;

  if (len == 0) {
    android_errorWriteLog(0x534e4554, "132082342");
    return status;
  }

  gphNxpExtns_Context.RawWriteCallBack = false;
  gphNxpExtns_Context.CallBackMifare = NULL;
  gphNxpExtns_Context.CallBackCtxt = NdefMap;

  EXTNS_SetCallBackFlag(true);
  if (p_data[0] == 0x60 || p_data[0] == 0x61) {
    if (len < 12) {
      android_errorWriteLog(0x534e4554, "125900276");
      return status;
    }
    NdefMap->Cmd.MfCmd = (phNfc_eMifareCmdList_t)p_data[0];

    NdefMap->SendRecvBuf[i++] = p_data[1];

    NdefMap->SendRecvBuf[i++] = p_data[6]; /* TODO, handle 7 byte UID */
    NdefMap->SendRecvBuf[i++] = p_data[7];
    NdefMap->SendRecvBuf[i++] = p_data[8];
    NdefMap->SendRecvBuf[i++] = p_data[9];
    NdefMap->SendRecvBuf[i++] = p_data[10];
    NdefMap->SendRecvBuf[i++] = p_data[11];

    status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
                                      NdefMap->SendRecvBuf, NdefMap->SendLength,
                                      NdefMap->SendRecvLength);
  } else if (p_data[0] == 0xA0) {
    EXTNS_SetCallBackFlag(false);
    NdefMap->Cmd.MfCmd = phNfc_eMifareWrite16;
    gphNxpExtns_Context.RawWriteCallBack = true;

    memcpy(NdefMap->SendRecvBuf, &p_data[1], len - 1);
    NdefMap->SendLength = len - 1;
    status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
                                      NdefMap->SendRecvBuf, NdefMap->SendLength,
                                      NdefMap->SendRecvLength);
  } else if ((p_data[0] == phNfc_eMifareInc) ||
             (p_data[0] == phNfc_eMifareDec)) {
    EXTNS_SetCallBackFlag(false);
    NdefMap->Cmd.MfCmd = (phNfc_eMifareCmdList_t)p_data[0];
    gphNxpExtns_Context.RawWriteCallBack = true;

    memcpy(NdefMap->SendRecvBuf, &p_data[1], len - 1);
    NdefMap->SendLength = len - 1;
    status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
                                      NdefMap->SendRecvBuf, NdefMap->SendLength,
                                      NdefMap->SendRecvLength);
  } else if (((p_data[0] == phNfc_eMifareTransfer) ||
              (p_data[0] == phNfc_eMifareRestore)) &&
             (len == 2)) {
    NdefMap->Cmd.MfCmd = (phNfc_eMifareCmdList_t)p_data[0];
    if (p_data[0] == phNfc_eMifareRestore) {
      EXTNS_SetCallBackFlag(false);
      gphNxpExtns_Context.RawWriteCallBack = true;
      memcpy(NdefMap->SendRecvBuf, &p_data[1], len - 1);
      NdefMap->SendLength = len - 1;
    } else {
      memcpy(NdefMap->SendRecvBuf, p_data, len);
      NdefMap->SendLength = len;
    }
    status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
                                      NdefMap->SendRecvBuf, NdefMap->SendLength,
                                      NdefMap->SendRecvLength);

  } else {
    NdefMap->Cmd.MfCmd = (phNfc_eMifareCmdList_t)phNfc_eMifareRaw;

    memcpy(NdefMap->SendRecvBuf, p_data, len);
    NdefMap->SendLength = len;
    status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
                                      NdefMap->SendRecvBuf, NdefMap->SendLength,
                                      NdefMap->SendRecvLength);
  }
  if (NFCSTATUS_PENDING == status) {
    status = NFCSTATUS_SUCCESS;
  } else {
    LOG(ERROR) << StringPrintf("ERROR: Mfc_Transceive = 0x%x", status);
  }

  return status;
}

/*******************************************************************************
**
** Function         nativeNfcExtns_doTransceive
**
** Description      Sends raw frame to BCM stack.
**
** Returns          NFCSTATUS_PENDING - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
static NFCSTATUS nativeNfcExtns_doTransceive(uint8_t* buff, uint16_t buffSz) {
  NFCSTATUS wStatus = NFCSTATUS_PENDING;
  tNFA_STATUS status =
      NFA_SendRawFrame(buff, buffSz, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);

  if (status != NFA_STATUS_OK) {
    LOG(ERROR) << StringPrintf("%s: fail send; error=%d", __func__, status);
    wStatus = NFCSTATUS_FAILED;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function          phNciNfc_RecvMfResp
**
** Description      This function shall be invoked as part of ReaderMgmt data
**                  exchange sequence handler on receiving response/data from
*NFCC
**
** Returns          NFCSTATUS_SUCCESS - Data Reception is successful
**                  NFCSTATUS_FAILED  - Data Reception failed
**
*******************************************************************************/
static NFCSTATUS phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo,
                                     NFCSTATUS wStatus) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  uint16_t wPldDataSize = 0;
  phNciNfc_ExtnRespId_t RecvdExtnRspId = phNciNfc_e_InvalidRsp;
  if (NULL == RspBuffInfo) {
    status = NFCSTATUS_FAILED;
  } else {
    if (((PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE) >
         RspBuffInfo->wLen) ||
        (PH_NCINFC_STATUS_OK != wStatus) || (NULL == (RspBuffInfo->pBuff))) {
      status = NFCSTATUS_FAILED;
    } else {
      RecvdExtnRspId = (phNciNfc_ExtnRespId_t)RspBuffInfo->pBuff[0];

      switch (RecvdExtnRspId) {
        case phNciNfc_e_MfXchgDataRsp: {
          NFCSTATUS writeResponse = NFCSTATUS_SUCCESS;
          /* check the status byte */
          if (NFC_GetNCIVersion() == NCI_VERSION_2_0 &&
              (NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WR_TLV ||
               NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WRITE ||
               NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN ||
               NdefMap->State == PH_FRINFC_NDEFMAP_STATE_INIT)) {
            uint8_t rspAck = RspBuffInfo->pBuff[RspBuffInfo->wLen - 2];
            uint8_t rspAckMask = ((RspBuffInfo->pBuff[RspBuffInfo->wLen - 1]) &
                                  MAX_NUM_VALID_BITS_FOR_ACK);
            NCI_CALCULATE_ACK(rspAck, rspAckMask);
            writeResponse =
                (rspAck == T2T_RSP_ACK) ? NFCSTATUS_SUCCESS : NFC_STATUS_FAILED;
          } else {
            writeResponse = RspBuffInfo->pBuff[RspBuffInfo->wLen - 1];
          }
          if (PH_NCINFC_STATUS_OK == writeResponse) {
            status = NFCSTATUS_SUCCESS;
            uint16_t wRecvDataSz = 0;

            /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
            wPldDataSize = ((RspBuffInfo->wLen) -
                            (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE));
            wRecvDataSz = NCI_MAX_DATA_LEN;

            /* wPldDataSize = wPldDataSize-1; ==> ignoring the last status byte
             * appended with data */
            if ((wPldDataSize) <= wRecvDataSz) {
              /* Extract the data part from pBuff[2] & fill it to be sent to
               * upper layer */
              memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[1]),
                     (wPldDataSize));
              /* update the number of bytes received from lower layer,excluding
               * the status byte */
              *(NdefMap->SendRecvLength) = wPldDataSize;
            } else {
              // TODO:- Map some status for remaining extra data received to be
              // sent back to caller??
              status = NFCSTATUS_FAILED;
            }
          } else {
            status = NFCSTATUS_FAILED;
          }
        } break;

        case phNciNfc_e_MfcAuthRsp: {
          /* check the status byte */
          if (PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[1]) {
            if (gAuthCmdBuf.auth_sent == true) {
              MfcPresenceCheckResult(NFCSTATUS_SUCCESS);
              return NFCSTATUS_SUCCESS;
            }
            gAuthCmdBuf.auth_status = true;
            status = NFCSTATUS_SUCCESS;

            /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
            wPldDataSize = ((RspBuffInfo->wLen) -
                            (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE));

            /* Extract the data part from pBuff[2] & fill it to be sent to upper
             * layer */
            memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[2]),
                   wPldDataSize);
            /* update the number of bytes received from lower layer,excluding
             * the status byte */
            *(NdefMap->SendRecvLength) = wPldDataSize;
          } else {
            if (gAuthCmdBuf.auth_sent == true) {
              gAuthCmdBuf.auth_status = false;
              MfcPresenceCheckResult(NFCSTATUS_FAILED);
              return NFCSTATUS_SUCCESS;
            } else {
              /* Reset the stored auth command buffer */
              memset(gAuthCmdBuf.pauth_cmd->buffer, 0, NCI_MAX_DATA_LEN);
              gAuthCmdBuf.pauth_cmd->length = 0;
              gAuthCmdBuf.auth_status = false;
            }
            status = NFCSTATUS_FAILED;
          }
        } break;

        default: { status = NFCSTATUS_FAILED; } break;
      }
    }
  }

  return status;
}

/*******************************************************************************
**
** Function         phLibNfc_SendWrt16CmdPayload
**
** Description      This function map the raw write cmd
**
** Returns          NFCSTATUS_SUCCESS            - Command framing done
**                  NFCSTATUS_INVALID_PARAMETER  - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendWrt16CmdPayload(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;

  if ((NULL != pTransceiveInfo->sSendData.buffer) &&
      (0 != (pTransceiveInfo->sSendData.length))) {
    memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
           (pTransceiveInfo->sSendData.length));
    pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length;
    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
  } else {
    wStatus = NFCSTATUS_INVALID_PARAMETER;
  }

  if (gphNxpExtns_Context.RawWriteCallBack == true) {
    EXTNS_SetCallBackFlag(true);
    gphNxpExtns_Context.RawWriteCallBack = false;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_SendIncDecCmdPayload
**
** Description      This function prepares the Increment/Decrement Value to be
**                  sent. This is called after sending the Increment/Decrement
**                  command is already sent and successfull
**
** Returns          NFCSTATUS_SUCCESS            - Payload framing done
**                  NFCSTATUS_INVALID_PARAMETER  - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendIncDecCmdPayload(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;

  if ((NULL != pTransceiveInfo->sSendData.buffer) &&
      (0 != (pTransceiveInfo->sSendData.length))) {
    memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
           (pTransceiveInfo->sSendData.length));
    pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length;
    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
  } else {
    wStatus = NFCSTATUS_INVALID_PARAMETER;
  }

  if (gphNxpExtns_Context.RawWriteCallBack == true) {
    EXTNS_SetCallBackFlag(true);
    gphNxpExtns_Context.RawWriteCallBack = false;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         Mfc_RecvPacket
**
** Description      Decodes Mifare Classic Tag Response
**                  This is called from NFA_SendRaw Callback
**
** Returns:
**                  NFCSTATUS_SUCCESS - if successfully initiated
**                  NFCSTATUS_FAILED  - otherwise
**
*******************************************************************************/
NFCSTATUS Mfc_RecvPacket(uint8_t* buff, uint8_t buffSz) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  phNciNfc_Buff_t RspBuff;
  uint8_t* pcmd_buff;
  uint16_t buffSize;

  RspBuff.pBuff = buff;
  RspBuff.wLen = buffSz;
  status = phNciNfc_RecvMfResp(&RspBuff, status);
  if (true == gAuthCmdBuf.auth_sent) {
    DLOG_IF(INFO, nfc_debug_enabled)
        << StringPrintf("%s Mfc Check Presence in progress", __func__);
    gAuthCmdBuf.auth_sent = false;
    return status;
  }
  if (true == gphNxpExtns_Context.writecmdFlag &&
      (NFCSTATUS_SUCCESS == status)) {
    pcmd_buff = (uint8_t*)malloc((uint32_t)MAX_BUFF_SIZE);
    if (NULL == pcmd_buff) {
      return NFCSTATUS_FAILED;
    }
    buffSize = MAX_BUFF_SIZE;
    gphNxpExtns_Context.writecmdFlag = false;
    phLibNfc_SendWrt16CmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo);
    status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize);
    if (NFCSTATUS_PENDING != status) {
      LOG(ERROR) << StringPrintf("ERROR : Mfc_RecvPacket: 0x%x", status);
    } else {
      status = NFCSTATUS_SUCCESS;
    }
    if (pcmd_buff != NULL) {
      free(pcmd_buff);
      pcmd_buff = NULL;
    }
  } else if (true == gphNxpExtns_Context.incrdecflag &&
             (NFCSTATUS_SUCCESS == status)) {
    pcmd_buff = (uint8_t*)malloc((uint32_t)MAX_BUFF_SIZE);
    if (NULL == pcmd_buff) {
      return NFCSTATUS_FAILED;
    }
    buffSize = MAX_BUFF_SIZE;
    gphNxpExtns_Context.incrdecflag = false;
    phLibNfc_SendIncDecCmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo);
    status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize);
    if (NFCSTATUS_PENDING != status) {
      LOG(ERROR) << StringPrintf("ERROR : Mfc_RecvPacket: 0x%x", status);
    } else {
      status = NFCSTATUS_SUCCESS;
    }
    gphNxpExtns_Context.incrdecstatusflag = true;
    if (pcmd_buff != NULL) {
      free(pcmd_buff);
      pcmd_buff = NULL;
    }

  } else {
    if (gphNxpExtns_Context.CallBackMifare != NULL) {
      if ((gphNxpExtns_Context.incrdecstatusflag == true) && status == 0xB2) {
        gphNxpExtns_Context.incrdecstatusflag = false;
        status = NFCSTATUS_SUCCESS;
      }
      gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt,
                                         status);
    }
  }

  return status;
}

/*******************************************************************************
**
** Function         phNciNfc_MfCreateXchgDataHdr
**
** Description      This function builds the payload header for mifare XchgData
**                  request to be sent to NFCC.
**
** Returns          NFCSTATUS_PENDING            - Command framing done
**                  NFCSTATUS_FAILED             - Otherwise
**
*******************************************************************************/
static NFCSTATUS phNciNfc_MfCreateXchgDataHdr(
    phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t* buff, uint16_t* buffSz)

{
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  uint8_t i = 0;

  buff[i++] = phNciNfc_e_MfRawDataXchgHdr;
  memcpy(&buff[i], tTranscvInfo.tSendData.pBuff, tTranscvInfo.tSendData.wLen);
  *buffSz = i + tTranscvInfo.tSendData.wLen;

  status = nativeNfcExtns_doTransceive(buff, (uint16_t)*buffSz);

  return status;
}

/*******************************************************************************
**
** Function         phNciNfc_MfCreateAuthCmdHdr
**
** Description      This function builds the payload header for mifare
**                  classic Authenticate command to be sent to NFCC.
**
** Returns          NFCSTATUS_PENDING            - Command framing done
**                  NFCSTATUS_FAILED             - Otherwise
**
*******************************************************************************/
static NFCSTATUS phNciNfc_MfCreateAuthCmdHdr(
    phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t bBlockAddr, uint8_t* buff,
    uint16_t* buffSz) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  //    pphNciNfc_RemoteDevInformation_t  pActivDev = NULL;
  //    /*commented to eliminate unused variable warning*/
  uint8_t bKey = 0x00;

  /*No need to check range of block address*/
  /*To check for Authenticate A or Authenticate B type command*/
  if (PHNCINFC_AUTHENTICATION_KEYB == tTranscvInfo.tSendData.pBuff[0]) {
    bKey = bKey | PHNCINFC_ENABLE_KEY_B;
  }

  /*TO Do last 4 bits of Key to be set based of firmware implementation*/
  /*this value is hardcoded but based on firmware implementation change this
   * value*/
  bKey = (bKey | PHNCINFC_AUTHENTICATION_KEY);

  bKey |= tTranscvInfo.tSendData.pBuff[2];

  /*For authentication extension no need to copy tSendData buffer of
   * tTranscvInfo */
  tTranscvInfo.tSendData.wLen = 0x00;

  buff[0] = phNciNfc_e_MfcAuthReq;
  buff[1] = bBlockAddr;
  buff[2] = bKey;

  *buffSz = 0x03;
  if (bKey & PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY) {
    memcpy(&buff[3], &tTranscvInfo.tSendData.pBuff[3], PHLIBNFC_MFC_AUTHKEYLEN);
    *buffSz += PHLIBNFC_MFC_AUTHKEYLEN;
  }
  /* Store the auth command buffer to use further for presence check */
  if (gAuthCmdBuf.pauth_cmd != NULL) {
    memset(gAuthCmdBuf.pauth_cmd->buffer, 0, NCI_MAX_DATA_LEN);
    gAuthCmdBuf.pauth_cmd->length = *buffSz;
    memcpy(gAuthCmdBuf.pauth_cmd->buffer, buff, *buffSz);
  }
  status = nativeNfcExtns_doTransceive(buff, (uint16_t)*buffSz);

  return status;
}

/*******************************************************************************
**
** Function         phNciNfc_SendMfReq
**
** Description      This function shall be invoked as part of ReaderMgmt data
**                  exchange sequence handler.
**                  It shall send the request packet to NFCC.
**
** Returns          NFCSTATUS_PENDING  - Send request is Pending
**                  NFCSTATUS_FAILED   - otherwise
**
*******************************************************************************/
static NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo,
                                    uint8_t* buff, uint16_t* buffSz) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;

  switch (tTranscvInfo.uCmd.T2TCmd) {
    case phNciNfc_eT2TRaw: {
      status = phNciNfc_MfCreateXchgDataHdr(tTranscvInfo, buff, buffSz);
    } break;
    case phNciNfc_eT2TAuth: {
      status = phNciNfc_MfCreateAuthCmdHdr(tTranscvInfo, (tTranscvInfo.bAddr),
                                           buff, buffSz);
    } break;
    default: {
      status = NFCSTATUS_FAILED;
      break;
    }
  }

  return status;
}

/*******************************************************************************
**
** Function         phLibNfc_CalSectorAddress
**
** Description      This function update the sector address for Mifare classic
**
** Returns          none
**
*******************************************************************************/
static void phLibNfc_CalSectorAddress(uint8_t* Sector_Address) {
  uint8_t BlockNumber = 0x00;

  if (NULL != Sector_Address) {
    BlockNumber = *Sector_Address;
    if (BlockNumber >= PHLIBNFC_MIFARESTD4K_BLK128) {
      *Sector_Address = (uint8_t)(PHLIBNFC_MIFARESTD_SECTOR_NO32 +
                                  ((BlockNumber - PHLIBNFC_MIFARESTD4K_BLK128) /
                                   PHLIBNFC_MIFARESTD_BLOCK_BYTES));
    } else {
      *Sector_Address = BlockNumber / PHLIBNFC_NO_OF_BLKPERSECTOR;
    }
  } else {
  }

  return;
}

/*******************************************************************************
**
** Function         phLibNfc_GetKeyNumberMFC
**
** Description      This function find key number based on authentication
*command
**
** Returns          NFCSTATUS_SUCCESS  - If found the key number
**                  NFCSTATUS_FAILED   - otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t* buffer, uint8_t* bKey) {
  int32_t sdwStat = 0X00;
  NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;

  /*Key Configuration
    uint8_t NdefKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7};
    uint8_t RawKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF};
    uint8_t MadKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5};
    uint8_t Key[PHLIBNFC_MFC_AUTHKEYLEN] = {0x00,0x00,0x00,0x00,0x00,0x00}; */ /*Key used during ndef format*/

  uint8_t bIndex = 0x00;
  uint8_t bNoOfKeys = 0x00;

#if PHLIBNFC_NXPETENSION_CONFIGURE_MFKEYS
  uint8_t aMfc_keys[NXP_NUMBER_OF_MFC_KEYS][NXP_MFC_KEY_SIZE] = NXP_MFC_KEYS;
#else
  uint8_t aMfc_keys[1][1] = {{0x00}};
#endif

  if (NULL != bKey && NULL != buffer) {
    bNoOfKeys = sizeof(aMfc_keys) / NXP_MFC_KEY_SIZE;
    /* Traverse through the keys stored to determine whether keys is preloaded
     * key */
    for (bIndex = 0; bIndex < bNoOfKeys; bIndex++) {
      /* Check passed key is NDEF key */
      sdwStat = memcmp(&buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], aMfc_keys[bIndex],
                       PHLIBNFC_MFC_AUTHKEYLEN);
      if (!sdwStat) {
        LOG(ERROR) << StringPrintf(
            "Mifare : phLibNfc_GetKeyNumberMFC Key found");
        *bKey = bIndex;
        wStatus = NFCSTATUS_SUCCESS;
        break;
      }
    }
    LOG(ERROR) << StringPrintf(
        "Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x Key = 0x%x",
        wStatus, *bKey);
  } else {
    wStatus = NFCSTATUS_FAILED;
    LOG(ERROR) << StringPrintf(
        "Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x", wStatus);
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_ChkAuthCmdMFC
**
** Description      This function Check Authentication command send is proper or
*not
**
** Returns          NFCSTATUS_SUCCESS  - Authenticate command is proper
**                  NFCSTATUS_FAILED   - otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_ChkAuthCmdMFC(
    phNfc_sTransceiveInfo_t* pTransceiveInfo, uint8_t* bKey) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;

  if (NULL != pTransceiveInfo && NULL != pTransceiveInfo->sSendData.buffer &&
      0 != pTransceiveInfo->sSendData.length && NULL != bKey) {
    if ((pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentA ||
         pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentB)) {
      wStatus =
          phLibNfc_GetKeyNumberMFC(pTransceiveInfo->sSendData.buffer, bKey);
    } else {
      wStatus = NFCSTATUS_FAILED;
    }
  } else {
    wStatus = NFCSTATUS_FAILED;
  }
  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_MifareMap
**
** Description      Mifare Mapping Utility function
**
** Returns          NFCSTATUS_SUCCESS             - Mapping is proper
**                  NFCSTATUS_INVALID_PARAMETER   - otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_MifareMap(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;
  uint8_t bBuffIdx = 0;
  uint8_t bSectorNumber;
  uint8_t bKey = 0;

  switch (pTransceiveInfo->cmd.MfCmd) {
    case phNfc_eMifareRead16: {
      if ((NULL != pTransceiveInfo->sRecvData.buffer) &&
          (0 != (pTransceiveInfo->sRecvData.length))) {
        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareRead16;
        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
        pMappedTranscvIf->tSendData.wLen = bBuffIdx;
        pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
      } else {
        status = NFCSTATUS_INVALID_PARAMETER;
      }
    } break;

    case phNfc_eMifareWrite16: {
      if ((NULL != pTransceiveInfo->sSendData.buffer) &&
          (0 != (pTransceiveInfo->sSendData.length))) {
        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16;
        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
        memcpy(&(pMappedTranscvIf->tSendData.pBuff[bBuffIdx]),
               pTransceiveInfo->sSendData.buffer,
               (pTransceiveInfo->sSendData.length));
        pMappedTranscvIf->tSendData.wLen =
            bBuffIdx + pTransceiveInfo->sSendData.length;
        pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
      } else {
        status = NFCSTATUS_INVALID_PARAMETER;
      }
    } break;

    case phNfc_eMifareAuthentA:
    case phNfc_eMifareAuthentB: {
      if ((NULL != pTransceiveInfo->sSendData.buffer) &&
          (0 != (pTransceiveInfo->sSendData.length)) &&
          (NULL != pTransceiveInfo->sRecvData.buffer) &&
          (0 != (pTransceiveInfo->sRecvData.length))) {
        status = phLibNfc_ChkAuthCmdMFC(pTransceiveInfo, &bKey);
        if (NFCSTATUS_FAILED != status) {
          bSectorNumber = pTransceiveInfo->addr;
          phLibNfc_CalSectorAddress(&bSectorNumber);
          /*For creating extension command header pTransceiveInfo's MfCmd get
           * used*/
          pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] =
              pTransceiveInfo->cmd.MfCmd;
          pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bSectorNumber;
          pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TAuth;
          pMappedTranscvIf->bAddr = bSectorNumber;
          pMappedTranscvIf->bNumBlock = pTransceiveInfo->NumBlock;
          if (NFCSTATUS_SUCCESS == status) {
            pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey;
            (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx);

          } else if (NFCSTATUS_INVALID_PARAMETER == status) {
            bKey = bKey | PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY;
            pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey;
            memcpy(&pMappedTranscvIf->tSendData.pBuff[bBuffIdx],
                   &pTransceiveInfo->sSendData
                        .buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD],
                   PHLIBNFC_MFC_AUTHKEYLEN);

            (pMappedTranscvIf->tSendData.wLen) =
                (uint16_t)(bBuffIdx + PHLIBNFC_MFC_AUTHKEYLEN);
            status = NFCSTATUS_SUCCESS;
          } else {
            /* do nothing */
          }
        }
      } else {
        status = NFCSTATUS_INVALID_PARAMETER;
      }
    } break;

    case phNfc_eMifareRaw: {
    } break;

    default: {
      status = NFCSTATUS_INVALID_PARAMETER;
      break;
    }
  }

  return status;
}

/*******************************************************************************
**
** Function         phLibNfc_MapCmds
**
** Description      This function maps the command request from libnfc level to
*nci level
**
** Returns          NFCSTATUS_SUCCESS           - Mapping of command is
*successful
**                  NFCSTATUS_INVALID_PARAMETER - One or more of the supplied
**                  parameters could not be interpreted properly
**
*******************************************************************************/
static NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType,
                                  phNfc_sTransceiveInfo_t* pTransceiveInfo,
                                  pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS status = NFCSTATUS_SUCCESS;

  if ((NULL == pTransceiveInfo) || (NULL == pMappedTranscvIf)) {
    return NFCSTATUS_FAILED;
  }
  switch (RemDevType) {
    case phNciNfc_eMifare1k_PICC:
    case phNciNfc_eMifare4k_PICC: {
      status = phLibNfc_MifareMap(pTransceiveInfo, pMappedTranscvIf);
      break;
    }
    default: { break; }
  }

  return status;
}

/*******************************************************************************
**
** Function         phLibNfc_SendAuthCmd
**
** Description      This function Send authentication command to NFCC
**
** Returns          NFCSTATUS_SUCCESS           - Parameters are proper
**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendAuthCmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    phNciNfc_TransceiveInfo_t* tNciTranscvInfo) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;

  wStatus = phLibNfc_MapCmds(phNciNfc_eMifare1k_PICC, pTransceiveInfo,
                             tNciTranscvInfo);

  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_SendWrt16Cmd
**
** Description      This function maps Mifarewirte16 commands
**
** Returns          NFCSTATUS_SUCCESS           - Parameters are mapped
**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendWrt16Cmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
  uint8_t bBuffIdx = 0x00;

  if ((NULL != pTransceiveInfo->sSendData.buffer) &&
      (0 != (pTransceiveInfo->sSendData.length))) {
    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16;
    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
    pMappedTranscvIf->tSendData.wLen = bBuffIdx;
    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
  } else {
    wStatus = NFCSTATUS_INVALID_PARAMETER;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_SendIncDecCmd
**
** Description      This function prepares the Increment/Decrement command
**                  to be sent, increment/decrement value is sent separately
**
** Returns          NFCSTATUS_SUCCESS           - Params are mapped
**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendIncDecCmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf, uint8_t IncDecCmd) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
  uint8_t bBuffIdx = 0x00;

  if ((NULL != pTransceiveInfo->sSendData.buffer) &&
      (0 != (pTransceiveInfo->sSendData.length))) {
    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = IncDecCmd;
    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
    pMappedTranscvIf->tSendData.wLen = bBuffIdx;
    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
  } else {
    wStatus = NFCSTATUS_INVALID_PARAMETER;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         phLibNfc_SendRawCmd
**
** Description      This function maps Mifare raw command
**
** Returns          NFCSTATUS_SUCCESS           - Parameters are mapped
**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
**
*******************************************************************************/
static NFCSTATUS phLibNfc_SendRawCmd(
    phNfc_sTransceiveInfo_t* pTransceiveInfo,
    pphNciNfc_TransceiveInfo_t pMappedTranscvIf) {
  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
  //    uint8_t bBuffIdx = 0x00;                                  /*commented to
  //    eliminate unused variable warning*/

  if ((NULL != pTransceiveInfo->sSendData.buffer) &&
      (0 != (pTransceiveInfo->sSendData.length))) {
    memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
           (pTransceiveInfo->sSendData.length));
    pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length;
    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw;
  } else {
    wStatus = NFCSTATUS_INVALID_PARAMETER;
  }

  return wStatus;
}

/*******************************************************************************
**
** Function         phFriNfc_ExtnsTransceive
**
** Description      This function maps Mifare raw command and send it to NFCC
**
** Returns          NFCSTATUS_PENDING           - Operation successful
**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
**
*******************************************************************************/
NFCSTATUS phFriNfc_ExtnsTransceive(phNfc_sTransceiveInfo_t* pTransceiveInfo,
                                   phNfc_uCmdList_t Cmd, uint8_t* SendRecvBuf,
                                   uint16_t SendLength,
                                   uint16_t* SendRecvLength) {
  (void)SendRecvLength;
  NFCSTATUS status = NFCSTATUS_FAILED;
  uint8_t* buff = NULL;
  uint16_t buffSz = 0;
  uint8_t i = 0;
  uint32_t length = SendLength;
  uint8_t restore_payload[] = {
      0x00, 0x00, 0x00, 0x00,
  };

  if (SendLength == 0) {
    android_errorWriteLog(0x534e4554, "132083376");
    return status;
  }

  buff = (uint8_t*)malloc((uint32_t)MAX_BUFF_SIZE);
  if (NULL == buff) {
    return status;
  }

  pTransceiveInfo->cmd = Cmd;

  if ((Cmd.MfCmd == phNfc_eMifareAuthentA) ||
      (Cmd.MfCmd == phNfc_eMifareAuthentB)) {
    pTransceiveInfo->addr = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[4] = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[5] = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[6] = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[7] = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[8] = SendRecvBuf[i++];
    pTransceiveInfo->sSendData.buffer[9] = SendRecvBuf[i++];

    pTransceiveInfo->cmd.MfCmd = Cmd.MfCmd;

    pTransceiveInfo->sSendData.length = length;
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
    status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo);
  } else if (Cmd.MfCmd == phNfc_eMifareWrite16) {
    pTransceiveInfo->addr = SendRecvBuf[i++];
    length = SendLength - i;
    memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
    pTransceiveInfo->sSendData.length = length;
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;

    gphNxpExtns_Context.writecmdFlag = true;

    status = phLibNfc_SendWrt16Cmd(pTransceiveInfo, &tNciTranscvInfo);
  } else if ((Cmd.MfCmd == phNfc_eMifareInc) ||
             (Cmd.MfCmd == phNfc_eMifareDec)) {
    pTransceiveInfo->addr = SendRecvBuf[i++];
    length = SendLength - i;
    memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
    pTransceiveInfo->sSendData.length = length;
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;

    gphNxpExtns_Context.incrdecflag = true;

    status =
        phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd);

  } else if (Cmd.MfCmd == phNfc_eMifareRestore) {
    pTransceiveInfo->addr = SendRecvBuf[i++];
    length = SendLength - i;
    memcpy(pTransceiveInfo->sSendData.buffer, &restore_payload[0],
           sizeof(restore_payload));
    pTransceiveInfo->sSendData.length = length + sizeof(restore_payload);
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;

    gphNxpExtns_Context.incrdecflag = true;

    status =
        phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd);

  } else if ((Cmd.MfCmd == phNfc_eMifareRaw) ||
             (Cmd.MfCmd == phNfc_eMifareTransfer)) {
    pTransceiveInfo->cmd.MfCmd = (phNfc_eMifareCmdList_t)phNciNfc_eT2TRaw;
    memcpy(pTransceiveInfo->sSendData.buffer, SendRecvBuf, length);
    pTransceiveInfo->sSendData.length = length;
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
    status = phLibNfc_SendRawCmd(pTransceiveInfo, &tNciTranscvInfo);
  } else {
    pTransceiveInfo->addr = SendRecvBuf[i++];
    length = SendLength - i;
    memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
    pTransceiveInfo->sSendData.length = length;
    pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
    status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo);
  }

  if (NFCSTATUS_SUCCESS == status) {
    status = phNciNfc_SendMfReq(tNciTranscvInfo, buff, &buffSz);
    if (NFCSTATUS_PENDING != status) {
      LOG(ERROR) << StringPrintf("ERROR : phNciNfc_SendMfReq()");
    }
  } else {
    LOG(ERROR) << StringPrintf(" ERROR : Sending phNciNfc_SendMfReq");
  }
  if (buff != NULL) {
    free(buff);
    buff = NULL;
  }

  return status;
}
